🎈 1 参考文档
【RuoYi-Vue-Plus】问题笔记 04 – EasyExcel 导出 Excel 问题合集 | pudn-Michelle_Zhong
🔍2 问题描述
2.1 需要导出的Excel文件
2.2 刚开始的解决方案
一般都是固定表头,然后填充数据,相当于一维的。因为表头是
动态
的,所以第二部分数据相当于二维的,需要将
表头
和
表格
数据分别进行填充。
EasyExcel的
填充
方式是通过
模板
进行填充导出的,那我们可以导出两次,第一次用
/resources/template
下的模板文件将Excel导出到
本地
,此时还能立马查看、验证第一次导出的结果是否正确,接着以第一次导出的Excel
文件
,作为第二次导出的模板,最后再导出需要的Excel表格文件,最后有必要的话再删除第一次导出的Excel文件。
模板:
第一次导出:
第二次导出:
2.3 简化后的代码
// 获得文件当前路径
String getFilePath = this.getClass().getResource("/").getPath();
// 获取模板文件
String screenTemplateFileName = getFilePath + "template" + File.separator + "screenTemplate.xlsx";
// 导出的临时模板文件名称
String screenTemporaryTemplateFileName = getFilePath + "template" + File.separator + "screenTemporaryTemplate.xlsx";
// 这里使用try-with-resource
try (
OutputStream screenOut = new FileOutputStream(screenTemporaryTemplateFileName);
BufferedOutputStream screenBos = new BufferedOutputStream(screenOut);
OutputStream finalScreenOut = httpServletResponse.getOutputStream();
BufferedOutputStream finalScreenBos = new BufferedOutputStream(finalScreenOut);
) {
// --------------------------------基本配置--------------------------------
......
// ---------------------模拟获取第一部分的表格数据、表头参数---------------------
......
// --------------------------------第一次导出--------------------------------
ExcelWriter screenTemplateExcelWriter = EasyExcel
.write(screenBos) // 导出临时文件
.withTemplate(screenTemplateFileName) // 使用的模板
.build();
screenTemplateExcelWriter.finish();
// ----------------------------模拟获取第二部分数据----------------------------
......
// --------------------------------第二次导出--------------------------------
ExcelWriter screenScoreExcelWriter = EasyExcel
.write(finalScreenBos) // 导出最终文件
.withTemplate(screenTemporaryTemplateFileName) // 以第一次导出的文件,作为第二次导出的模板
.build();
screenScoreExcelWriter.finish();
} catch (IOException e) {
throw new RuntimeException(e);
}
2.4 本地运行测试导出结果
可以看到临时文件正常导出,最终下载的文件也正常导出。
2.5 在Linux上运行测试导出结果
-
打开Excel导出文件报错:Excel 无法打开文件“exportFile.xlsx”,因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配。
-
查看日志。
java.io.FileNotFoundException: file:/home/hyc/java/demo-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/template/screenTemporaryTemplate.xlsx (没有那个文件或目录) at java.io.FileOutputStream.open0(Native Method) ~[na:1.8.0_345] at java.io.FileOutputStream.open(FileOutputStream.java:270) ~[na:1.8.0_345] at java.io.FileOutputStream.<init>(FileOutputStream.java:213) ~[na:1.8.0_345] at java.io.FileOutputStream.<init>(FileOutputStream.java:101) ~[na:1.8.0_345] ......
💡 3 原因分析
在Windows环境下中运行没问题,而在Linux环境下就不行。
把代码打成jar包之后,放在Linux环境上运行,在Linux中无法直接访问未经解压的文件,所以无法通过路径去读取文件的。
🚀4 解决方案
最简单的解决方案:让第一次直接导出Excel流,而不导出Excel文件,就不需要去
resources
下获取临时模板文件。
EasyExcel也支持读取模板文件的时候使用流:
public ExcelWriterBuilder withTemplate(InputStream templateInputStream) {
this.writeWorkbook.setTemplateInputStream(templateInputStream);
return this;
}
完整解决方案参考另一篇博客:
基于EasyExcel模板填充方式进行二次导出(动态表头、合并单元格问题处理)
。