POI跨行导出excell表格实现

POI跨行导出excell表格实现

需求:需要导出父子级关系的元素,父级需要跨行显示,子级需要单独显示。

由于数据库中的数据存的是子级存父级的ID形式,所以需要将数据包装,自己将装在父级下的list中,本案例将会包装成五级子级形式。

第一步:首先写sql ,sql中要计算出父级需要跨的行数。(思路:首先自身内连接,计算出每一级需要跨的行数,在与主表相连将跨行数关联上去)


    <select id="findList" resultType="OcScope">
        SELECT
            a.* ,b.label as typeName,c.scope_name as parentName,
            case when a.level =1  then ‘评估维度‘
             when a.level =2  then ‘评估类别‘
              when a.level =3  then ‘评估项目‘
               when a.level =4  then ‘评估内容‘
                when a.level =5  then ‘问题‘
            else ‘未知类别‘ end as levelName
        FROM oc_scope a  left join oc_dict b on a.type=b.value and b.type="evaluation_dimension"
          left join oc_scope c on a.parent_id=c.id
        WHERE a.status = #{DEL_FLAG_NORMAL}
        <if test="scopeName != null and scopeName != ‘‘">
            AND a.scope_name LIKE
                    <if test="dbName == ‘oracle‘">‘%‘||#{scopeName}||‘%‘</if>
                    <if test="dbName == ‘mssql‘">‘%‘+#{scopeName}+‘%‘</if>
                    <if test="dbName == ‘mysql‘">CONCAT(‘%‘, #{scopeName}, ‘%‘)</if>
        </if>
        <if test="type != null and type != ‘‘">
            AND a.type = #{type}
        </if>
        <if test="level != null and level != ‘‘">
            AND a.level = #{level}
        </if>
        <if test="remark != null and remark != ‘‘">
            AND a.remark = #{remark}
        </if>
        <if test="parentId != null and parentId != ‘‘">
            AND a.parent_id = #{parentId}
        </if>

        <if test="scopeName != null and scopeName != ‘‘">
            AND a.scope_name LIKE CONCAT(CONCAT(‘%‘,#{scopeName},‘%‘))
        </if>
            ORDER BY a.type,a.level, a.sort
    </select>

        

第二步:编写实体类(OcScope):

private String type;
private String level;
private OcScope parent;
private String parentId;
private String parentName;
private String grandFatherName;
private String module;
private String typeName;
private String scopeName;
private String p1ScopeName;
private String p2ScopeName;
private String p3ScopeName;
private String p4ScopeName;
private Integer count1;
private Integer count2;
private Integer count3;
private Integer count4;
private String activityCatalogue;
private String sow;
private String activityCataloguePosition;
private String sowPosition;
private String remark;
private String sort;
private Double weights;
private Double p1Weights;
private Double p2Weights;
private Double p3Weights;
private Double p4Weights;
private Double remainWeights;
private String levelName;
private String showStatus;
         .......

第三步:编写mapper层:

    public List<OcScope> findCountList(OcScope ocScope);

第四步:编写server层:

一.需要先包装数据,将子级包装到list中

1.写一个实体类(ExcelDataBo)包装数据:

    public class ExcelDataBo  {
   private String id;
   private String name;
   private String pid;
   private Double  weights;
   private Integer count;
   private String level;
   private List<ExcelDataBo> subList;
          ...........
    }
    

2.包装数据

public List<ExcelDataBo> getExcelDataList() {
        List<ExcelDataBo> boList = Lists.newArrayList();
    //从数据库中查询出level=1的数据
        OcScope ocScope = new OcScope();
        ocScope.setLevel("1");
        List<OcScope> list1 = dao.findList(ocScope);
    //从数据库中查询出level=2的数据
        ocScope.setLevel("2");
        List<OcScope> list2 = dao.findList(ocScope);
    //从数据库中查询出level=3的数据
        ocScope.setLevel("3");
        List<OcScope> list3 = dao.findList(ocScope);
    //从数据库中查询出level=4的数据
        ocScope.setLevel("4");
        List<OcScope> list4 = dao.findList(ocScope);
    //从数据库中查询出level=5的数据
        ocScope.setLevel("5");
        List<OcScope> list5 = dao.findList(ocScope);

        int count1=0,count2=0,count3=0,count4=0;
        for (OcScope oc : list1) { // level 1
            if (oc.getLevel().equals("1")) {
                ExcelDataBo bo = new ExcelDataBo();
                bo.setId(oc.getId());
                bo.setPid(oc.getParentId());
                bo.setName(oc.getScopeName());
                bo.setWeights(oc.getWeights());
                count1=0;  //首先赋值为0,count1:用于记录该项需要跨的行数

                List<ExcelDataBo> boList2 = Lists.newArrayList();
                for (OcScope oc2 : list2) { // level 2
                    if (oc2.getParentId().equals(bo.getId())) {
                        ExcelDataBo bo2 = new ExcelDataBo();
                        bo2.setId(oc2.getId());
                        bo2.setPid(oc2.getParentId());
                        bo2.setName(oc2.getScopeName());
                        bo2.setWeights(oc2.getWeights());
                        count2=0;  //首先赋值为0,count2:用于记录该项需要跨的行数
                        List<ExcelDataBo> boList3 = Lists.newArrayList();
                        for (OcScope oc3 : list3) { // level 3
                            if (oc3.getParentId().equals(bo2.getId())) {
                                ExcelDataBo bo3 = new ExcelDataBo();
                                bo3.setId(oc3.getId());
                                bo3.setPid(oc3.getParentId());
                                bo3.setName(oc3.getScopeName());
                                bo3.setWeights(oc3.getWeights());
                                count3=0;  //首先赋值为0,count3:用于记录该项需要跨的行数
                                List<ExcelDataBo> boList4 = Lists.newArrayList();
                                for (OcScope oc4 : list4) { // level 4
                                    if (oc4.getParentId().equals(bo3.getId())) {
                                        ExcelDataBo bo4 = new ExcelDataBo();
                                        bo4.setId(oc4.getId());
                                        bo4.setPid(oc4.getParentId());
                                        bo4.setName(oc4.getScopeName());
                                        bo4.setWeights(oc4.getWeights());
                                        count4=0; //首先赋值为0,count4:用于记录该项需要跨的行数
                                        List<ExcelDataBo> boList5 = Lists.newArrayList();
                                        for (OcScope oc5 : list5) {  // level 5
                                            if (oc5.getParentId().equals(bo4.getId())) {
                                                ExcelDataBo bo5 = new ExcelDataBo();
                                                bo5.setId(oc5.getId());
                                                bo5.setPid(oc5.getParentId());
                                                bo5.setName(oc5.getScopeName());
                                                bo5.setWeights(oc5.getWeights());
                                                  bo5.setCount(1); //直接赋值1,这是最底层数据不存跨行的问题
                                                boList5.add(bo5);
                                                count4++;
                                            }
                                        }
                                        if(count4==0)  //有可能其下没有list子级,但是本身需要跨一行
                                        count4=1;
                                        bo4.setCount(count4);
                                        bo4.setSubList(boList5);
                                        boList4.add(bo4);
                                        count3 = count3+count4;
                                    }
                                }
                                if(count3==0)//有可能其下没有list子级,但是本身需要跨一行
                                count3=1;
                                bo3.setCount(count3);
                                bo3.setSubList(boList4);
                                boList3.add(bo3);
                                count2 = count2+count3;
                            }
                        }
                        if(count2==0) //有可能其下没有list子级,但是本身需要跨一行
                        count2=1;
                        bo2.setCount(count2);
                        bo2.setSubList(boList3);
                        boList2.add(bo2);
                        count1 = count1 + count2;
                    }
                }
                if(count1==0) //有可能其下没有list子级,但是本身需要跨一行
                count1=1;
                bo.setCount(count1);
                bo.setSubList(boList2);
                boList.add(bo);
            }

        }
        return boList;
    }
 

二.将数据写在excel中去

1.编写工具类(ExcelUtils),注:该类可直接复制我的就行


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.utils.IdGen;

public class ExcelUtils {
   /**
    * 根据路径获取Workbook
    * @param filePath excel文件路径
    * @return
    * @throws Exception
    */
   public static Workbook getWorkbook(String filePath) throws Exception{
       int version = 0;
       if (filePath.endsWith(".xls")) {
           version = 2003;
       }else if (filePath.endsWith(".xlsx")) {
           version = 2007;
       }else {
           throw new Exception("Incorrect file format,Only allowed ‘.xls,.xlsx‘ extension");
       }
       Workbook workbook = null;
       switch (version) {
           case 2003:
               POIFSFileSystem fs = new POIFSFileSystem(new BufferedInputStream(new FileInputStream(filePath)));
               workbook = new HSSFWorkbook(fs);
               break;

           case 2007:
               workbook = new XSSFWorkbook(new BufferedInputStream(new FileInputStream(filePath)));
               break;
       }
       return workbook;
   }

   /**
   @SuppressWarnings("unchecked")
   public static void main(String[] args) throws Exception {
       long start = System.currentTimeMillis();
       Workbook wb = ExcelUtils.getWorkbook("D:/temp/002.xlsx");
       XSSFSheet sheet = (XSSFSheet) wb.getSheet("Security");
       int last = sheet.getLastRowNum();
       System.out.println("rownum:"+last);
       System.out.println("phy rownum:"+sheet.getPhysicalNumberOfRows());
       System.out.printf("删除共花费%s毫秒\n",System.currentTimeMillis() - start);

       System.out.println(sheet.getRow(1).getCell(0).getStringCellValue().equals("Level 4\n(Product)"));

       Field nameField = XSSFSheet.class.getDeclaredField("_rows");
       Field modifiersField = Field.class.getDeclaredField("modifiers");
       modifiersField.setAccessible(true);
       modifiersField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL);//把 final从修饰集中除掉
       nameField.setAccessible(true); //允许访问 private
       Object object = nameField.get(sheet);
       SortedMap<Integer, XSSFRow> rowMap = (SortedMap<Integer, XSSFRow>) object;
       Integer index = new Integer(4);
       int idx = rowMap.headMap(index).size();
       Field worksheetField = XSSFSheet.class.getDeclaredField("worksheet");
       worksheetField.setAccessible(true);
       nameField.setAccessible(true); //允许访问 private
       CTWorksheet worksheet = (CTWorksheet) worksheetField.get(sheet);
       worksheet.getSheetData().removeRow(idx);
       rowMap.remove(index);
       System.out.println(((SortedMap<Integer, XSSFRow>)object).keySet());

       List<XSSFRow> list = new ArrayList<XSSFRow>();
       for (int i=0;i<last;i++) {
           if (i==5) {
               continue;
           }
           list.add(sheet.getRow(i));
       }

       int sheetIndex = wb.getSheetIndex(sheet);
       String sheetname = sheet.getSheetName();
       //wb.removeSheetAt(sheetIndex);
       Sheet createSheet = wb.createSheet(sheetname+"2");
       wb.setSheetOrder(sheetname+"2", sheetIndex);

       for (int i=1;i<list.size()+1;i++) {
           Row row = sheet.getRow(i);
           XSSFRow createRow = (XSSFRow) createSheet.createRow(i);
           createRow.copyRowFrom(row, new CellCopyPolicy());
       }

       last = sheet.getLastRowNum();
       System.out.println("rownum:"+last);
       start = System.currentTimeMillis();
       wb.write(new FileOutputStream("D:/temp/007-test.xlsx"));
       System.out.printf("写共花费%s毫秒",System.currentTimeMillis() - start);
       wb.close();
   }
    * @throws Exception
   */

   public static void testZipFiles(String filePath) throws Exception{
       zipFiles("D:/temp/test/99b6d26cbea34e3890b9a16b5b2a6676","D:/temp/test/test.xlsx");
   }

   public static void main(String[] args) throws Exception {
       String unzipExcel = unzipExcel("D:/temp/test/0010.xlsx","D:/temp/test/");
       System.out.println(unzipExcel);
   }

   @SuppressWarnings("unchecked")
   public static void editXml(String filePath) throws Exception{
       long start = System.currentTimeMillis();
       SAXReader reader = new SAXReader();
       Document document = reader.read(new File(filePath));
       Element rootElement = document.getRootElement();
       Iterator<Element> elements = rootElement.element("sheetData").elementIterator("row");
       int index = 0;
       while (elements.hasNext()) {
           Element row = elements.next();
           index++;
           String rownum = index+"";
           if (index>2) {
               //获取第一列
               Element col = row.element("c");
               if (col.element("v")==null) {
                   row.getParent().remove(row);
                   index--;
                   continue;
               }

               row.addAttribute("r", rownum);

               List<Element> cols = row.elements("c");
               for (Element element : cols) {
                   String colnum = element.attributeValue("r");
                   //数字匹配
                   Matcher matcher = Pattern.compile("\\d+").matcher(colnum);
                   matcher.find();
                   String colno = matcher.group();
                   colnum = colnum.replace(colno, "");
                   element.addAttribute("r", colnum + rownum);
               }
           }
       }

       /**
       List<Element> elements = rootElement.element("sheetData").elements("row");
       for (int i = 0; i < elements.size(); i++) {
           Element row = elements.get(i);
           int index = i+1;
           String rownum = index+"";
           if (!row.attributeValue("r").equals(rownum)) {
               row.addAttribute("r", index+"");
           }
           List<Element> cols = row.elements("c");
           for (Element element : cols) {
               String colnum = element.attributeValue("r");
               //数字匹配
               Matcher matcher = Pattern.compile("\\d+").matcher(colnum);
               matcher.find();
               String colno = matcher.group();
               colnum = colnum.replace(colno, "");
               element.addAttribute("r", colnum + rownum);
           }

       }
       */
       OutputFormat outputFormat = OutputFormat.createPrettyPrint();
       outputFormat.setEncoding("UTF-8");    // 指定XML编码
       outputFormat.setNewlines(false); //设置是否换行
       outputFormat.setIndent(false); //设置是否缩进
       XMLWriter writer = new XMLWriter(new FileWriter("D:/temp/0010/xl/worksheets/test.xml"), outputFormat);
       writer.write(document);
       writer.close();
       document.clone();
       System.out.println(String.format("共耗时%s ms", System.currentTimeMillis()-start));
   }

   @SuppressWarnings("unchecked")
   public static void removeFromXml(String xmlFilePath,Map<Integer, Object> indexs) throws Exception{
       long start = System.currentTimeMillis();
       SAXReader reader = new SAXReader();
       File xmlFile = new File(xmlFilePath);
       Document document = reader.read(xmlFile);
       Element rootElement = document.getRootElement();
       Iterator<Element> elements = rootElement.element("sheetData").elementIterator("row");
       int index = 0;
       int i = 0;
       for (;elements.hasNext();i++) {
           Element row = elements.next();
           index++;
           String rownum = index+"";
           if (i>=2) {
               if (indexs.containsKey(i)) {
                   row.getParent().remove(row);
                   index--;
                   continue;
               }

               row.addAttribute("r", rownum);

               List<Element> cols = row.elements("c");
               for (Element element : cols) {
                   String colnum = element.attributeValue("r");
                   //数字匹配
                   Matcher matcher = Pattern.compile("\\d+").matcher(colnum);
                   matcher.find();
                   String colno = matcher.group();
                   colnum = colnum.replace(colno, "");
                   element.addAttribute("r", colnum + rownum);
               }
           }
       }

       OutputFormat outputFormat = OutputFormat.createPrettyPrint();
       outputFormat.setEncoding("UTF-8");    // 指定XML编码
       outputFormat.setNewlines(false); //设置是否换行
       outputFormat.setIndent(false); //设置是否缩进

       //创建临时文件
       String tempFileName = IdGen.uuid();
       File tempFile = new File(xmlFilePath.replace(xmlFile.getName(), tempFileName+".xml"));

       XMLWriter writer = new XMLWriter(new FileOutputStream(tempFile), outputFormat);
       writer.write(document);
       writer.close();
       //删除原来xml
       try {
           xmlFile.delete();
       } catch (Exception e) {
           throw new RuntimeException(e);
       }
       //重命名修改后的xml
       tempFile.renameTo(new File(xmlFilePath));
       System.out.println(String.format("共耗时%s ms", System.currentTimeMillis()-start));
   }

   /**
    * 解压excel文件到指定临时目录,并返回解压后的临时目录
    * @param excelFilePath
    * @param tempPath
    * @return
    * @throws Exception
    */
   public static String unzipExcel (String excelFilePath,String tempPath) throws Exception{
       String tempDir = tempPath;
       String dirName = IdGen.uuid();
       ZipFile zipFile = null;
       try {
           zipFile = new ZipFile(new File(excelFilePath));
           if (tempPath.endsWith("/")||tempPath.endsWith(File.separator)) {
               tempDir = tempDir + dirName + File.separator;
           }else {
               tempDir = tempDir + File.separator + dirName + File.separator;
           }
           unZipFiles(zipFile, tempDir);
       } catch (Exception e) {
           throw e;
       }finally{
           if (zipFile!=null) {
               zipFile.close();
           }
       }
       return tempDir.replaceAll("\\\\", "/");
   }

   @SuppressWarnings("rawtypes")
   private static void unZipFiles(ZipFile zipFile,String descDir)throws IOException{
       for(Enumeration entries = zipFile.entries();entries.hasMoreElements();){
           ZipEntry entry = (ZipEntry)entries.nextElement();
           String zipEntryName = entry.getName();
           InputStream in = zipFile.getInputStream(entry);
           String outPath = (descDir+zipEntryName).replaceAll("\\\\", "/");;
           //判断路径是否存在,不存在则创建文件路径
           File file = new File(outPath.substring(0, outPath.lastIndexOf(‘/‘)));
           if(!file.exists()){
               file.mkdirs();
           }
           //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
           if(new File(outPath).isDirectory()){
               continue;
           }
           //输出文件路径信息
           System.out.println(outPath);

           OutputStream out = new FileOutputStream(outPath);
           byte[] buf1 = new byte[1024];
           int len;
           while((len=in.read(buf1))>0){
               out.write(buf1,0,len);
           }
           in.close();
           out.close();
           }
       System.out.println("******************unzip scuccess********************");
   }

//  public static void unZipFiles(File zipFile,String descDir)throws IOException{
//      File pathFile = new File(descDir);
//      if(!pathFile.exists()){
//          pathFile.mkdirs();
//      }
//      unZipFiles(zipFile, descDir);
//  }

   public static void zipFiles(String inputFileName,String outPutFileName) throws IOException {
       File file = new File(inputFileName);
       if (!file.exists()){
           throw new RuntimeException(inputFileName + "not exists!");
       }
       String rootPath = inputFileName;

       if (inputFileName.endsWith("/")) {
           rootPath = inputFileName.substring(0,inputFileName.lastIndexOf("/"));
       }
       FileOutputStream fileOutputStream = null;
       CheckedOutputStream cos = null;
       ZipOutputStream out = null;
       try {
           fileOutputStream = new FileOutputStream(outPutFileName);
           cos = new CheckedOutputStream(fileOutputStream,new CRC32());
           out = new ZipOutputStream(cos);
           zipByType(file, out, "",rootPath);    

       } catch (Exception e) {
           e.printStackTrace();
           throw new RuntimeException(e);
       }finally {
           if (out!=null) {
               out.close();
           }
           if (fileOutputStream!=null) {
               fileOutputStream.close();
           }
       }
   } 

    /**
    * 判断是目录还是文件,根据类型(文件/文件夹)执行不同的压缩方法
    */
   private static void zipByType(File file, ZipOutputStream out, String basedir,String rootDir) {
       /* 判断是目录还是文件 */
       if (file.isDirectory()) {
          zipDirectory(file, out, "",rootDir);
       } else {
           zipFile(file, out, basedir,rootDir);
       }
   }    

   /**
    * 压缩一个目录
    */
   private static void zipDirectory(File dir, ZipOutputStream out, String basedir,String rootDir) {
       if (!dir.exists()){
            return;
       }
       File[] files = dir.listFiles();
       for (int i = 0; i < files.length; i++) {
           /* 递归 */
           zipByType(files[i], out, basedir + dir.getName() + "/",rootDir);
       }
   }    

   /**
    * 压缩一个文件
    */
   private static void zipFile(File file, ZipOutputStream out, String basedir, String rootDir) {
       if (!file.exists()) {
           return;
       }
       try {
           BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
           //获取文件相对于压缩文件夹根目录的子路径
           String subPath = file.getAbsolutePath();
           int index = subPath.indexOf(file.getAbsolutePath());
           if (index != -1)
           {
               subPath = subPath.substring(rootDir.length() + File.separator.length());
           }
           ZipEntry entry = new ZipEntry(subPath);
           out.putNextEntry(entry);
           int count;
           byte data[] = new byte[4096];
           while ((count = bis.read(data, 0, 4096)) != -1) {
               out.write(data, 0, count);
           }
           bis.close();
       } catch (Exception e) {
           throw new RuntimeException(e);
       }
   }

   /**
    * 删除Excel中需要保留Sheet之外的其他Sheet,返回Workbook对象
    * @param filePath Excel文件路径
    * @param sheetName 需要保留的Sheet名称
    * @return 返回只包含保留Sheet的Workbook对象
    * @throws Exception
    */
   public static Workbook getSingleSheetWorkbook(String filePath,String sheetName) throws Exception {
       Workbook workbook = getWorkbook(filePath);
       int numberOfSheets = workbook.getNumberOfSheets();
       String[] sheetNames = new String[numberOfSheets];
       for (int i = 0; i < numberOfSheets; i++) {
           sheetNames[i] = workbook.getSheetName(i);
       }
       for (String name : sheetNames) {
           if (!sheetName.equalsIgnoreCase(name)) {
               workbook.removeSheetAt(workbook.getSheetIndex(name));
           }
       }
       return workbook;
   }

   /**
    * 删除Excel中需要保留Sheet之外的其他Sheet,返回Workbook对象
    * @param workbook Workbook对象
    * @param sheets 需要保留的Sheet名称数组
    * @return 返回只包含保留Sheet的Workbook对象
    * @throws Exception
    */
   public static Workbook getSheetWorkbook(Workbook workbook,String[] sheets) throws Exception {
       int numberOfSheets = workbook.getNumberOfSheets();
       String[] sheetNames = new String[numberOfSheets];
       for (int i = 0; i < numberOfSheets; i++) {
           sheetNames[i] = workbook.getSheetName(i);
       }
       Map<String, Object> sheetMap = Maps.newHashMap();
       for (String sheet : sheets) {
           sheetMap.put(sheet.toLowerCase(), null);
       }
       for (String name : sheetNames) {
           if (!sheetMap.containsKey(name.toLowerCase())) {
               workbook.removeSheetAt(workbook.getSheetIndex(name));
           }
       }
       return workbook;
   }

   /**
    * 复制单元格样式
    * @param wb 新建单元格所在Workbook
    * @param scrCell 源单元格,需要复制的单元格
    * @param destCell 目标单元格,新建单元格
    */
   public static void copyCellStyle(Workbook wb,Cell scrCell, Cell destCell) {
       CellStyle newStyle = wb.createCellStyle();
       copyStyle(scrCell.getCellStyle(), newStyle);
       destCell.setCellStyle(newStyle);
   }  

   // 单元格样式复制函数
   private static void copyStyle(CellStyle oldStyle, CellStyle newStyle) {
         newStyle.setAlignment(oldStyle.getAlignment());
         //边框和边框颜色
         newStyle.setBorderBottom(oldStyle.getBorderBottom());
         newStyle.setBorderLeft(oldStyle.getBorderLeft());
         newStyle.setBorderRight(oldStyle.getBorderRight());
         newStyle.setBorderTop(oldStyle.getBorderTop());
         newStyle.setTopBorderColor(oldStyle.getTopBorderColor());
         newStyle.setBottomBorderColor(oldStyle.getBottomBorderColor());
         newStyle.setRightBorderColor(oldStyle.getRightBorderColor());
         newStyle.setLeftBorderColor(oldStyle.getLeftBorderColor());  

         //背景和前景
         newStyle.setFillBackgroundColor(oldStyle.getFillBackgroundColor());
         newStyle.setFillForegroundColor(oldStyle.getFillForegroundColor());  

         newStyle.setDataFormat(oldStyle.getDataFormat());
         newStyle.setFillPattern(oldStyle.getFillPattern());
//        newStyle.setFont(oldStyle.getFont(null));
         newStyle.setHidden(oldStyle.getHidden());
         newStyle.setIndention(oldStyle.getIndention());//首行缩进
         newStyle.setLocked(oldStyle.getLocked());
         newStyle.setRotation(oldStyle.getRotation());//旋转
         newStyle.setVerticalAlignment(oldStyle.getVerticalAlignment());
         newStyle.setWrapText(oldStyle.getWrapText());
   } 

   public static void copyRowStyle(Workbook wb,Row scrRow,Row destRow){
       for (int i=0;i<destRow.getLastCellNum();i++) {
           Cell cell = scrRow.getCell(i);
           if (cell!=null) {
               CellStyle newStyle = wb.createCellStyle();
               newStyle.cloneStyleFrom(scrRow.getCell(i).getCellStyle());
               destRow.getCell(i).setCellStyle(newStyle);
           }
       }
   }

   /**
    * 判断指定的单元格是否是合并单元格,如果是则返回合并单元格index,不是则返回-1
    * @param sheet
    * @param row 行下标
    * @param column 列下标
    * @return
    */
   public static int isMergedRegion(Sheet sheet,int row ,int column) {
       int sheetMergeCount = sheet.getNumMergedRegions();
       for (int i = 0; i < sheetMergeCount; i++) {
           CellRangeAddress range = sheet.getMergedRegion(i);
           int firstColumn = range.getFirstColumn();
           int lastColumn = range.getLastColumn();
           int firstRow = range.getFirstRow();
           int lastRow = range.getLastRow();
           if(row >= firstRow && row <= lastRow){
               if(column >= firstColumn && column <= lastColumn){
                   return i;
               }
           }
       }
       return -1;
   }

   /**
   * 获取合并单元格的值
   * @param sheet
   * @param row
   * @param column
   * @return
   */
   public static String getMergedRegionValue(Sheet sheet ,int row , int column){
       int sheetMergeCount = sheet.getNumMergedRegions();    

       for(int i = 0 ; i < sheetMergeCount ; i++){
           CellRangeAddress ca = sheet.getMergedRegion(i);
           int firstColumn = ca.getFirstColumn();
           int lastColumn = ca.getLastColumn();
           int firstRow = ca.getFirstRow();
           int lastRow = ca.getLastRow();
           if(row >= firstRow && row <= lastRow){
               if(column >= firstColumn && column <= lastColumn){
                   Row fRow = sheet.getRow(firstRow);
                   Cell fCell = fRow.getCell(firstColumn);
                   return getCellValue(fCell) ;
               }
           }
       }    

       return null ;
   }  

   /**
    * 获取单元格的值
    * @param cell
    * @return
    */
   public static String getCellValue(Cell cell) {
       if (cell == null)
           return "";
       if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
           return cell.getStringCellValue();
       } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
           return String.valueOf(cell.getBooleanCellValue());
       } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
           return cell.getCellFormula();
       } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
           return String.valueOf(cell.getNumericCellValue());
       }
       return "";
   }

   /**
    * 合并单元格
    * @param sheet
    * @param firstRow 开始行
    * @param lastRow 结束行
    * @param firstCol 开始列
    * @param lastCol 结束列
    */
   public static void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
       sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
   }   

}

2.将数据写到excel中去

//注入地址,防止硬编码问题
@Value("${excel.temp.dir}")
    private String tempDir;

@SuppressWarnings("unchecked")
    public void exportEvaluationTemplate(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Workbook workbook = null;
        File destFile = null;
        try {
            //保证模板文件放在项目中,或者自己的c/d盘中,(本例是放在项目中的) 获取最新Excel模板
             String classpath = exportEvaluationTemplate.class.getClassLoader().getResource("").getPath(); //获取当类的位置
               String templatePath = classpath + "/templates/"; //类所在的文件夹中新建一个templates包用来存储文件的包

         //      templatePath:文件的地址
            File srcFile = new File(templatePath+"Evaluation_Template.xlsx"); //拿到文件
            String tempName = "Evaluation_Template_" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
            destFile = new File(tempDir + "/" + tempName);
            FileUtils.copyFile(srcFile, destFile);
            workbook = ExcelUtils.getWorkbook(destFile.getPath());
            Sheet sheet = workbook.getSheetAt(0);
            // 得到需要写入的数据
            List<ExcelDataBo> rowList = getExcelDataList();
            // 统计信息从第2行,第一列开始写
            int rowIndex = 1; // 行
            int cellIndex = 0;  //列
            for (ExcelDataBo bo : rowList) {
                String cellName = bo.getName();
                Double cellWeights = bo.getWeights();
                int rowMgrCnt = bo.getCount(); // 合并行数
                cellIndex = 0;
                //将数据写入表格
                sheet.getRow(rowIndex).getCell(cellIndex).setCellValue(cellName);
                //合并所需要的行或者列
                if(rowMgrCnt > 1)  //如果rowMgrCnt<1,就没有必要合并单元格了
                ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, cellIndex, cellIndex);
                cellIndex++;
                sheet.getRow(rowIndex).getCell(cellIndex).setCellValue(cellWeights);
                if(rowMgrCnt > 1)
                ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, cellIndex, cellIndex);
                    List<ExcelDataBo> boList2 = bo.getSubList();
                    if(boList2!=null && boList2.size()>0 ){
                    for (ExcelDataBo bo2 : boList2) {
                        rowMgrCnt = bo2.getCount(); // 合并行

                        int c1=cellIndex;
                        c1++;
                        sheet.getRow(rowIndex).getCell(c1).setCellValue(bo2.getName());
                        if(rowMgrCnt > 1)
                        ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c1, c1);
                        c1++;
//                      sheet.getRow(rowIndex).getCell(c1).setCellValue(bo2.getWeights());
                        if(bo2.getWeights()!=null && !bo2.getWeights().equals("") )
                        {
                            sheet.getRow(rowIndex).getCell(c1).setCellValue(bo2.getWeights());
                        }else{
                            sheet.getRow(rowIndex).getCell(c1).setCellValue(0);
                        }
                        if(rowMgrCnt > 1)
                        ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c1, c1);
                            List<ExcelDataBo> boList3 = bo2.getSubList();
                            if(boList3!=null && boList3.size()>0 ){
                            for (ExcelDataBo bo3 : boList3) {
                                rowMgrCnt = bo3.getCount(); // 合并行
                                int c2=c1;
                                c2++;
                                sheet.getRow(rowIndex).getCell(c2).setCellValue(bo3.getName());
                                if(rowMgrCnt > 1)
                                ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c2, c2);
                                c2++;
                                if(bo3.getWeights()!=null && !bo3.getWeights().equals("") )
                                {
                                    sheet.getRow(rowIndex).getCell(c2).setCellValue(bo3.getWeights());
                                }else{
                                    sheet.getRow(rowIndex).getCell(c2).setCellValue(0);
                                }
                                if(rowMgrCnt > 1)
                                ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c2, c2);

                                    List<ExcelDataBo> boList4 = bo3.getSubList();
                                    if(boList4!=null && boList4.size()>0 ){
                                    for (ExcelDataBo bo4 : boList4) {
                                        rowMgrCnt = bo4.getCount(); // 合并行

                                        int c3=c2;
                                        c3++;
                                        sheet.getRow(rowIndex).getCell(c3).setCellValue(bo4.getName());
                                        if(rowMgrCnt > 1)
                                        ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c3, c3);
                                        c3++;
                                        if(bo4.getWeights()!=null && !bo4.getWeights().equals("") )
                                        {
                                            sheet.getRow(rowIndex).getCell(c3).setCellValue(bo4.getWeights());
                                        }else{
                                            sheet.getRow(rowIndex).getCell(c3).setCellValue(0);
                                        }
                                        if(rowMgrCnt > 1)
                                        ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c3, c3);

                                        List<ExcelDataBo> boList5 = bo4.getSubList();
                                        if(boList5!=null && boList5.size()>0 ){
                                            for (ExcelDataBo bo5 : boList5) {
                                                rowMgrCnt = 1; // 合并行
                                                int c4=c3;
                                                c4++;
                                                sheet.getRow(rowIndex).getCell(c4).setCellValue(bo5.getName());
                                                if(rowMgrCnt > 1)
                                                ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c4, c4);
                                                c4++;
                                                if(bo5.getWeights()!=null && !bo5.getWeights().equals("") )
                                                {
                                                    sheet.getRow(rowIndex).getCell(c4).setCellValue(bo5.getWeights());
                                                }else{
                                                    sheet.getRow(rowIndex).getCell(c4).setCellValue(0);
                                                }

                                                if(rowMgrCnt > 1)
                                                ExcelUtils.mergeRegion(sheet, rowIndex, rowIndex + rowMgrCnt - 1, c4, c4);
                                                //将行数怎家
                                                rowIndex=rowIndex+rowMgrCnt;
                                            }
                                    }else{  //进入else就是等于说是rowMgrCnt=0,输出表格需要换行开始下一行的数据输出。
                                        rowIndex = rowIndex+1;
                                    }

                                }

                            }else{
                                rowIndex = rowIndex+1;
                            }
                        }
                        }else{
                            rowIndex = rowIndex+1;
                        }
                    }

                }else{
                    rowIndex = rowIndex+rowMgrCnt;
                }

            }
            OutputStream wos = null;
            try {
                wos = new FileOutputStream(destFile);
                workbook.write(wos);
            } catch (Exception e) {
                throw e;
            } finally {
                if (wos != null) {
                    wos.close();
                }
            }
            FileUtils.downFile(destFile, request, response);
        } catch (Exception e) {
            throw e;
        } finally {
            if (workbook != null) {
                workbook.close();
            }
            if (destFile != null) {
                try {
                    destFile.delete();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

第五步:编写controller层:

    /**
     *    表单导出方法
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "export")
    public void exportEvaluationTemplate(HttpServletRequest request, HttpServletResponse response) throws Exception {

        ocScopeService.exportEvaluationTemplate(request,response);

    }

原文地址:https://www.cnblogs.com/jiajialeps/p/10311988.html

时间: 2024-11-06 14:28:29

POI跨行导出excell表格实现的相关文章

POI跨行导出excell表格实现.md

# POI跨行导出excell表格实现### 需求:需要导出父子级关系的元素,父级需要跨行显示,子级需要单独显示. ### 由于数据库中的数据存的是子级存父级的ID形式,所以需要将数据包装,自己将装在父级下的list中,本案例将会包装成五级子级形式. ### 第一步:首先写sql ,sql中要计算出父级需要跨的行数.(思路:首先自身内连接,计算出每一级需要跨的行数,在与主表相连将跨行数关联上去) ```xml <select id="findList" resultType=&q

poi导出word表格跨行

DataCommon.java package com.ksource.pwlp.model.statistic; public class DataCommon { private Long id; private String name; private String otherName; private String dataName; private String otherDataName; private int value; private float otherValue; pr

java 使用poi 结合Struts2导出execl表格

第一步写action方法: public String exportActiveExcel() { String name ="活跃度列表.xls"; try { name = java.net.URLEncoder.encode(name, "UTF-8"); fileName = new String(name.getBytes(), "iso-8859-1"); } catch (UnsupportedEncodingException e

poi导入导出excel后记

续上一篇:在springmvc项目中使用poi导入导出excel http://blog.csdn.net/kingson_wu/article/details/38942967 一. 导入时,发现了不少问题,如果是导出excel之后,在里面不删除行,只是简单的修改一些数据的话,则不会出问题,但如果是删除了一些行,或者excel表不是导出的,而是另外的excel文件,里面有很多数据ctrl+a,ctrl+v生成的,那么导入的时候就会出问题,因为里面虽然看起来的数据就那么多,但是有一些数据痕迹.很

Springboot使用POI实现导出Excel文件示例

Springboot使用POI实现导出Excel文件示例 前面讲述了使用POI导出Word文件和读取Excel文件,这两个例子都相对简单,接下来要讲述的使用POI导出Excel文件要复杂得多,内容也会比较长.创建表头信息表头信息用于自动生成表头结构及排序public class ExcelHeader implements Comparable<ExcelHeader>{/**  * excel的标题名称  */private String title;/**  * 每一个标题的顺序  */p

java代码实现导出Excel表格、工具ssm框架、maven、idea

第一步.导入依赖 <!--生成excel文件--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId&g

React+后端实现导出Excle表格的功能

最近在做一个基于React+antd前端框架的Excel导出功能,我主要在后端做了处理,这个功能完成后,便总结成一篇技术分享文章,感兴趣的小伙伴可以参考该分享来做导出excle表格功能,以下步骤同样适用于vue框架,或者JSP页面的实现. 在做这类导出文件的功能,其实,在后端进行处理,会更容易些,虽然前端也可以进行处理,但还是建议后端来做,因为很多导出工具类基本都是很好用. 根据以下步骤,可以很容易就实现导出Excel表格数据的功能. 1.导出图标 按钮代码: 1 <Button type=&quo

PHP 和 JS 导入导出csv表格(上)

CSV简介 在开发后台管理系统的时候,几乎无可避免的会遇到需要导入导出Excel表格的需求.csv也是表格的一种,其中文名为"逗号分隔符文件".在Excel中打开如下图左边所示,在记事本打开如下图右边所示: 再看包含特殊字符的表格 与xls或xlsx 表格相类似,CSV文件也是用来表示二维表格.而不同的是: 1.CSV是一种纯文本文件,任何编辑器都能打开并读取它:xls(x)是专用的二进制文件,要用表格软件才能正常打开,否则乱码: 2.CSV的体积很小,比如上面的表格内容,csv只有几

原生JavaScript 导出excel表格(兼容ie和其他主流浏览器)

因同事的需求是想前端导出excel表格,网上找了一些demo,自己修改了一下,可能以后会用到,记录下来吧,兼容ie和一些主流浏览器,ie可能会报错,原因参考 这里,edge 浏览器还没有办法导出,正在尝试... <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>table 导出excel表格</title>