Java EasyPoi之复杂多表头多sheet页excel模板导出实例
本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一 :简介
最近开发中遇到复杂多表头多sheet页多图片excel导出的问题。
本文使用操作Excel的框架是EasyPoi
EasyPoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法
官方主页: http://www.wupaas.com/easypoi.html
API文档: http://doc.wupaas.com/docs/easypoi/easypoi-1c0u6ksp2r091
二:EasyPoi 模板指令介绍
模板是处理复杂Excel的简单方法,复杂的Excel样式,可以用Excel直接编辑,完美的避开了代码编写样式的雷区,同时指令的支持,也提了模板的有效性\ 下面列举下EasyPoi支持的指令以及作用,最主要的就是各种fe的用法
- 空格分割
- 三目运算 {{test ? obj:obj2}}
- n: 表示 这个cell是数值类型 {{n:}}
- le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
- fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
- fn: 格式化数字 {{fn:(obj;###.00)}}
- fe: 遍历数据,创建row
- !fe: 遍历数据不创建row
- $fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入
-
fe: 横向遍历
- v_fe: 横向遍历值
- !if: 删除当前列 {{!if:(test)}}
- 单引号表示常量值 ‘’ 比如’1’ 那么输出的就是 1
- &NULL& 空格
- &INDEX& 表示循环中的序号,自动添加
- ]] 换行符 多行遍历导出
- sum: 统计数据
- cal: 基础的+-X% 计算
- dict: 字典
- i18n: 国际化
三:设计思路
1.根据easypoi模板指令,设计导出数据结构,并填充进入Excel模板中.
2.查询数据,对需要遍历的列表设计到的sheet页和单元格,进行预处理:
将模板表中对应单元格下移,并合并需要合并的单元格
java
//下移单元格
sheet.shiftRows(startRow, endRow, n);
java
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
3.创建模板导出参数
java
//创建模板导出参数
TemplateExportParams params = new TemplateExportParams(dealTemplatePath, true, sheetNames);
4.生成导出 workbook
java
//生成导出 workbook
Workbook workbook = templateExcelExportHelper.createExcelByTemplate(getMinioInputStream(BUCKET_NAME, dealTemplatePath), params, sheetMap);
5.处理easypoi生成的workbook
java
/**
* 设置外边框
* @param workbook 工作表
* @param i sheet下标
*/
public static void setSheetBorder(Workbook workbook, int i) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, workbook.getSheetAt(i).getLastRowNum(),0,
workbook.getSheetAt(i).getRow(0).getPhysicalNumberOfCells() -1);
RegionUtil.setBorderBottom(BorderStyle.MEDIUM,cellRangeAddress, workbook.getSheetAt(i));
RegionUtil.setBorderLeft(BorderStyle.MEDIUM,cellRangeAddress, workbook.getSheetAt(i));
RegionUtil.setBorderRight(BorderStyle.MEDIUM,cellRangeAddress, workbook.getSheetAt(i));
RegionUtil.setBorderTop(BorderStyle.MEDIUM,cellRangeAddress, workbook.getSheetAt(i));
}
6.输出文件并删除预处理产生的模板文件
```java
//输出文件流至 Servlet
setExportExcelFormat(response, workbook, exportExcelName);
//删除生成的预处理模板
deleteTemplate(dealTemplatePath);
```
java
/**
* 输出文件流
*
* @param response
* @param workbook
* @param fileName
* @throws Exception
*/
public void setExportExcelFormat(HttpServletResponse response, Workbook workbook, String fileName) throws Exception {
ServletOutputStream outStream = null;
String fileNameURL = URLEncoder.encode(fileName, "UTF-8");
response.setContentType("octets/stream");
response.setHeader("Content-disposition", "attachment;filename=" + fileNameURL + ";"
+ "filename*=utf-8''" + fileNameURL);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
try {
outStream = response.getOutputStream();
workbook.write(outStream);
} finally {
outStream.close();
}
}
四:模板示例
五:预处理模板截图
五:导出截图
踩坑记录
1.单元格样式丢失
在导出过程中发现,easypoi合并单元格纵向遍历列表导出后,出现了单元格样式丢失的问题:如下图
2.多sheet dichandle失效
多sheet页导出,没有把params中的dichandle赋值,详见: Java EasyPoi Excel模板多sheet页导出,数据字典赋值问题