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


    背景介绍

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

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

    代码实战

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

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

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

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

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

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

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

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

    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 44)
    @HeadFontStyle(fontHeightInPoints = 10)
    @ContentFontStyle(fontHeightInPoints = 10)
    public class SaleTransferSummaryRateExportVo {
    
     @ExcelProperty("老师昵称")
        private String teacherName;
    
        @ExcelProperty("大区")
        private String regionName;
    
        @ExcelProperty("小组")
        private String groupName;
    
        @ExcelProperty("创建时间")
        @DateTimeFormat("yyyy-MM-dd")
        private Date createTime;
    
    }
    

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

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

    遇到的坑

    1. 版本问题

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

    
     <dependency>
        <groupId>org.apache.poigroupId>
        <artifactId>poi-ooxmlartifactId>
        <version>3.17version>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>easyexcelartifactId>
        <version>3.1.2version>
    dependency>
    

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

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

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


    __EOF__

  • 本文作者: 女友在高考
  • 本文链接: https://www.cnblogs.com/javammc/p/16857425.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    【Android 四大组件之Content Provider】一文吃透 BroadcastReceiver 广播接收器
    大一新生常踩的5大坑,轻则损失钱财,重则影响毕业
    剑指offer 24. 合并两个排序的链表
    Qt 围炉札记
    前端基础入门之JS对象 原型 prototype
    【编程题】【Scratch二级】2022.09 绘制图形
    java构建树
    WPF中DataGrid控件绑定数据源
    被PMP考试“折磨”出来的考试心得,值得你一览
    OPCHDA接口
  • 原文地址:https://www.cnblogs.com/javammc/p/16857425.html