easyexcel基于模板的数据导出及自定义表头

需求背景:需要将数据导出成excel格式,但是表头信息不确定和表头格式复杂,基于代码也可以实现,但是代码实现复杂,且后续需要改动时成本较大,所以选择依赖模板的形式进行数据导出,将提前准备好的模板放置在指定路径下,数据导出的时候依赖指定模板即可

依赖包导入:此处使用的版本是2.2.3,相关版本可以根据具体的项目要求进行依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.3</version>
</dependency>

具体实现:模板中需要设置一些数据导出的时候需要替换的文字

(1)依赖模板单sheet数据导出

代码实现:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;


/**
       * @author:xhwang
       * @date:2022年12月9日
       * @description:依赖模板数据导出,单个sheet页面
       * @version:1.0
       * @param:sheetName:每个sheet页面名称   data:每个sheet页面填充的数据  templatePath:模板路径  filePath:生成文件路径 map:替换模板中的正则表达式  fileName:文件名称
       */
      public static void export(List<List<Object>> data,String templatePath,String filePath,Map<String, Object> map,String fileName){
             ExcelWriter excelWriter = null;
            try{
                excelWriter = EasyExcel.write(filePath).withTemplate(templatePath).registerWriteHandler(new ColumnStyle()).build();
    //map中存储需要替换模板中item的数据,例如表格表头需要显示2013级,那么map中需要传入的数据为("item",2013)
                WriteSheet writeSheet = EasyExcel.writerSheet(0,map.get("item") != null ? map.get("item").toString(): fileName).build();
                excelWriter.write(data, writeSheet);
                excelWriter.fill(map, writeSheet);
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                excelWriter.finish();
            }
      }

(2)依赖多模板的多sheet页面数据导出,具体的需求为,导出的数据中有50家单位的数据,需要将每家单位的数据导出为一个sheet页,其中一家单位的表头和其余49家单位的表头不一样,所以我们的模板需要设置两个sheet,两个sheet的表头不一样,第一家使用模板的第一个sheet,其余49家使用第二个sheet,所以在数据导出的时候就需要对模板中第二个sheet进行拷贝

模板中第一个sheet如下:

第二个sheet如下:

代码实现:

 /**
       * @author:xhwang
       * @date:2022年12月9日
       * @description: 利用模板导入多个Sheet,需要克隆模板Sheet,此处为特殊需求,模板中有两个sheet,导出的excel有很多sheet,导出的excel第一个sheet用模板里面第一个sheet,其余的sheet用模板里面第二个sheet
       * @version:1.0
       * @param:sheetName:每个sheet页面名称   data:每个sheet页面填充的数据  templatePath:模板路径  filePath:生成文件路径
       */
      public static void exportMoreSheet(List<String> sheetName,List<List<List<Object>>> data,String templatePath,String filePath){
          FileInputStream fileInputStream= null;ExcelWriter excelWriter = null;ByteArrayOutputStream bos = new ByteArrayOutputStream();
             try {
                    fileInputStream = new FileInputStream(templatePath); 
                    XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
                    for (int i = 0; i <  sheetName.size(); i++) {
                        if(i<=1){
                            workbook.setSheetName(i,  sheetName.get(i));
                        }else{
                            workbook.cloneSheet(1, sheetName.get(i));//导出的文件自第二个sheet页开始使用模板中的第二个sheet,需要按照数据对模板中的第二个sheet进行制定长度的克隆
                        }
                    }
                    //写到流里
                    workbook.write(bos);
                    byte[] bArray = bos.toByteArray();
                    InputStream is = new ByteArrayInputStream(bArray);
                    //输出文件路径
                    excelWriter = EasyExcel.write(filePath).withTemplate(is).build();
                    Map<String,Object> map = new HashMap<String, Object>();
                    for (int i = 0; i <  sheetName.size(); i++) {
                        WriteSheet writeSheet = EasyExcel.writerSheet(i,sheetName.get(i)).registerWriteHandler(new MoreSheetStyle()).build();
                        excelWriter.write(data.get(i), writeSheet);
                        map.put("item", sheetName.get(i));
                        excelWriter.fill(map, writeSheet);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally{
                    try {
                        fileInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                     excelWriter.finish();
                }
            
        }

代码中涉及到的CloumnStyle.java和MoreSheetStyle.java两个类都是对导出数据样式的一些自定义细微调整,可以根据自己的实际需要进行设置

import java.util.List;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;


@SuppressWarnings("rawtypes")
public class ColumnStyle implements CellWriteHandler  {
    
    
    
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
    }
 
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
    }

    
   
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
            List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
         Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
         CellStyle cellStyle = workbook.createCellStyle();
         Font font = workbook.createFont();
     
             cellStyle.setBorderBottom(BorderStyle.THIN);
             cellStyle.setBorderLeft(BorderStyle.THIN);
             cellStyle.setBorderRight(BorderStyle.THIN);
             cellStyle.setBorderTop(BorderStyle.THIN);
             cell.setCellStyle(cellStyle);
             font.setFontHeightInPoints((short) 16);
             font.setFontName("宋体");
             font.setBold(true);
             cellStyle.setFont(font);
             cellStyle.setAlignment(HorizontalAlignment.CENTER);
             cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        

    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
            CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    }
    

}

easyexcel做的比较灵活,可以根据自己实际要进行数据导出

官网地址:https://easyexcel.opensource.alibaba.com/docs/current/

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值