我用EasyExcel优化了公司的导出(附踩坑记录)

x33g5p2x  于9个月前 转载在 其他  
字(4.4k)|赞(0)|评价(0)|浏览(1483)

背景介绍

最近要改一个导出的功能,在原有的基础上,在导出一份明细数据,要求导出内容加在原有 excel 的第二个 sheet 上。考虑到数据量还比较大,干脆引入阿里的 EasyExcel 来做。

下面我先上最终代码,再来说说我遇到的坑有哪些

代码实战

  1. public String doHandle() {
  2. try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  3. com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(outputStream).build()) {
  4. List<SaleTransferSummaryRateExportVo> exportVos = queryAction.querySummaryExport();
  5. List<SaleTransferClassRateExportVo> exportRateVos = queryAction.queryClassRate();
  6. WriteSheet writeSheet = EasyExcel.writerSheet(0, "统计").head(SaleTransferSummaryRateExportVo.class).build();
  7. excelWriter.write(exportVos, writeSheet);
  8. WriteSheet rateWriteSheet = EasyExcel.writerSheet(1, "明细").head(SaleTransferClassRateExportVo.class).build();
  9. excelWriter.write(exportRateVos, rateWriteSheet);
  10. excelWriter.close();
  11. // 数据落地到OSS
  12. String resultPath = ossClient.uploadFile(outputStream.toByteArray(), ContentMediaEnum.XLSX.getName(), FileExtEnum.XLSX.getName());
  13. return resultPath;
  14. } catch (Exception e) {
  15. return "";
  16. }
  17. }

我们项目是将文件传到 oss,然后去 oss 进行下载。也可以直接写入到文件或 response

  1. public void doHandle() {
  2. File file=new File("");
  3. try(
  4. com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(file).build()) {
  5. List<SaleTransferSummaryRateExportVo> exportVos = queryAction.querySummaryExport();
  6. List<SaleTransferClassRateExportVo> exportRateVos = queryAction.queryClassRate();
  7. WriteSheet writeSheet = EasyExcel.writerSheet(0, "统计").head(SaleTransferSummaryRateExportVo.class).build();
  8. excelWriter.write(exportVos, writeSheet);
  9. WriteSheet rateWriteSheet = EasyExcel.writerSheet(1, "明细").head(SaleTransferClassRateExportVo.class).build();
  10. excelWriter.write(exportRateVos, rateWriteSheet);
  11. } catch (Exception e) {
  12. log.error("导出异常",e);
  13. }
  14. }

只需要修改 write 的参数即可。

主要的代码就完成了,那么数据的属性和 excel 列名称怎么对应上的呢?

在数据的实体类上加上@ExcelProperty 注解就行了。它就能自动创建列头,并将数据对应写入。

  • @ColumnWidth 列宽度
  • @ExcelIgnore 代表不用导出的属性
  • DateTimeFormat 日期格式化
  1. public class SaleTransferSummaryRateExportVo {
  2. @ExcelProperty("老师昵称")
  3. @ColumnWidth(10)
  4. private String teacherName;
  5. @ExcelProperty("大区")
  6. private String regionName;
  7. @ExcelProperty("小组")
  8. private String groupName;
  9. @ExcelProperty("创建时间")
  10. @DateTimeFormat("yyyy-MM-dd")
  11. private Date createTime;
  12. }

写完之后觉得表格有点丑,于是又调了下样式。也是几个注解搞定

  1. @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 44)
  2. @HeadFontStyle(fontHeightInPoints = 10)
  3. @ContentFontStyle(fontHeightInPoints = 10)
  4. public class SaleTransferSummaryRateExportVo {
  5. @ExcelProperty("老师昵称")
  6. private String teacherName;
  7. @ExcelProperty("大区")
  8. private String regionName;
  9. @ExcelProperty("小组")
  10. private String groupName;
  11. @ExcelProperty("创建时间")
  12. @DateTimeFormat("yyyy-MM-dd")
  13. private Date createTime;
  14. }

fillForegroundColor 的值就代表颜色,具体什么值代表什么颜色,可以参考 IndexedColors 枚举类。

就这样就完成了。导出效果图如下:

遇到的坑

  1. 版本问题

我最开始用的版本是这样的,因为项目里之前就引入了 poi

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi-ooxml</artifactId>
  4. <version>3.17</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.alibaba</groupId>
  8. <artifactId>easyexcel</artifactId>
  9. <version>3.1.2</version>
  10. </dependency>

版本不对的时候写入直接报错。
异常信息如下:

  1. Exception in thread "main" com.alibaba.excel.exception.ExcelGenerateException: java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Cell.setCellValue(Ljava/time/LocalDateTime;)V
  2. at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:65)
  3. at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:70)
  4. at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:47)
  5. at cn.jojo.sales.app.task.ExportSalesTransferSummaryTask.main(ExportSalesTransferSummaryTask.java:90)
  6. Caused by: java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Cell.setCellValue(Ljava/time/LocalDateTime;)V
  7. at com.alibaba.excel.write.executor.AbstractExcelWriteExecutor.converterAndSet(AbstractExcelWriteExecutor.java:95)
  8. at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addJavaObjectToExcel(ExcelWriteAddExecutor.java:174)
  9. at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addOneRowOfDataToExcel(ExcelWriteAddExecutor.java:82)
  10. at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.add(ExcelWriteAddExecutor.java:58)
  11. at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:59)
  12. ... 3 more
  1. excelWriter 要关闭
  1. excelWriter.close();

我之前因为 excelWriter 的定义是是写在 try 里的,所以没有 close,但是我的用法又是将 excelWriter 写入到字节流,然后字节流传到 oss,而且这个步骤也是在 try 里面。就导致了我一直写入不成功,后来才发现,浪费了一点时间。

书山有路勤为径,学海无涯苦作舟

相关文章