Java EasyPoi之复杂多表头多sheet页excel模板导出实例

语言: CN / TW / HK

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一 :简介

最近开发中遇到复杂多表头多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(); } }

四:模板示例

image.png

image.png

image.png

五:预处理模板截图

image.png

image.png

五:导出截图

image.png

image.png

image.png

踩坑记录

1.单元格样式丢失

在导出过程中发现,easypoi合并单元格纵向遍历列表导出后,出现了单元格样式丢失的问题:如下图

2.多sheet dichandle失效

多sheet页导出,没有把params中的dichandle赋值,详见: Java EasyPoi Excel模板多sheet页导出,数据字典赋值问题