【RuoYi-Vue-Plus】问题笔记 04 - EasyExcel 导出 Excel 问题合集

前言

导出需求在后台管理中十分常见,在框架中也有集成相关的框架组件,在默认的生成方法中也有导出方法,但是最近遇到比较复杂的导出需求,也踩了一些坑,所以在此记录一下。

常用的导出都是像框架中的导出方法是传入表头以及数据集合全部写出到空白 Excel 表中,无论是使用 Apache POI 还是 EasyExcel 都不难实现,也有很多现有的方法,但是如果是对模板填充就没有这么简单。

参考目录

EasyExcel 使用参考

问题解决参考

需求说明

  1. 首先是查询到需要导出的数据,这一步主要是 SQL + 业务代码。
  2. 根据自定义模板 key 将数据填充到 Excel 模板的指定单元格中,这一步比较复杂的点在于模板的 key 和第 1 步的数据需要对应准确。
  3. 将 Excel 表导出。

前面两步都算顺利,看着 Demo 能顺利导出,但是问题出现在第三步。

问题一:Excel 导出本地

问题说明

找了很多例子,导出的实现都是直接导出到本地,但是我想达到的需求是:Excel 不要直接导出到本地,需要返回二进制流到前端,让前端进行下载。

官方 Demo 写法:导出到资源文件夹下
在这里插入图片描述
狮子大佬的写法:导出到系统桌面或者自定义路径下
在这里插入图片描述

和前端小姐姐沟通过,她无法获取到导出路径,所以一开始这里卡了挺久。

问题解决方案

这里和同事小哥讨论了之后,他提供了一种“曲线救国”的思路,目前也是采用这种方式实现上面的需求。

实现方式:

  1. 将单个或多个 Excel 文件导出到本地,以 UUID 命名一个文件夹,将文件夹路径返回给前端。
  2. 前端拿到文件夹路径后,请求下载文件接口:后端将文件夹压缩为压缩包,然后读取压缩包二进制流输出到前端,同时删除本地文件夹以及压缩包

压缩方法:

// 生成zip文件
ZipUtil.zip(url);

获取 byte[] 并写出到前端:

byte[] bytes = FileUtil.readBytes(path + ".zip");
// 写出到前端(可以参考框架方法 ExcelUtil#exportExcel)
response.reset();
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
// fileName 可以自定义
FileUtils.setAttachmentResponseHeader(response, "fileName.zip");
OutputStream stream = new BufferedOutputStream(response.getOutputStream());
stream.write(bytes);
stream.flush();
stream.close();

删除文件夹:

FileUtil.del(url);

问题二:模板文件读取报错

问题说明

Excel 模板不要写死在绝对路径,放在资源文件夹下,但是读取的时候报错了。

模板文件存放位置:
在这里插入图片描述
这个问题看起来好像不难,但是也卡了挺久,找了好多方法,换了几种写法都不大好使,报错的内容也不一样……

举几个栗子:

报错一:
Create workbook failure
报错二:
Failed to execute ‘createObjectURL’ on ‘URL’: Overload resolution failed.
报错三:
Invalid header signature; read 0xE011BDBFEFBDBFEF, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
报错四:
Unexpected record signature: 0X9

报错当时没有截图,就只是复制了一些控制台的打印直接去搜索,所以只记得大概这几种。

最开始的写法(参考官方 Demo 写法):

// 获取资源文件夹路径
this.getClass().getResource("/").getPath();

问题解决方案

一开始以为是 getResource() 方法有问题,搜了一波之后还是没有解决问题,后面换成了 Hutool 的写法:

InputStream stream = new ClassPathResource("/excel/Template.xls").getStream();

// 模板文件传入 InputStream,原本是传入文件路径
EasyExcel.write(fileName).withTemplate(stream).sheet().doFill(map);

报错变了,然后再去搜索就是需要配置 maven 对资源文件不进行压缩:

<plugins>
	<plugin>
	    <groupId>org.apache.maven.plugins</groupId>
	    <artifactId>maven-resources-plugin</artifactId>
	    <version>3.1.0</version>
	    <configuration>
	        <!--配置不需要压缩的文件-->
	        <nonFilteredFileExtensions>
	            <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
	            <nonFilteredFileExtension>xls</nonFilteredFileExtension>
	        </nonFilteredFileExtensions>
	    </configuration>
	</plugin>
</plugins>

配置好之后重新打包重启之后问题二也顺利解决了。

补充说明

在需求第 2 步中,模板其实有一些单元格是写了 SUM 函数的单元格,大家用过 Excel 的话都很熟悉这个函数是用来合计指定单元格的,但是用 EasyExcel 导出的时候,填充了单元格之后,导出的文件 SUM 函数并不会执行,但是如果双击填充了数据单元格的话,Excel 又会进行合计(所以我在做这块的时候真的无力吐槽……),找了一圈只能放弃 SUM。

EasyExcel Issue 截图:这里是引用

所以后面只能修改模板,把 SUM 函数的单元格也变成模板填充单元格,在程序中进行计算。

记得很久之前用过Apache POI设置单元格公式,找了一下以前的代码证明我的记忆没错乱,改天有时间的话看看能不能优化一下这里的模板。
在这里插入图片描述

### 回答1: "failed to execute 'createobjecturl' on 'url': overload resolution failed" 的意思是在执行 'createobjecturl' 函数时出现了重载解析失败的错误。这通常是由于传递给函数的参数不正确或不兼容所导致的。需要检查参数是否正确,并确保它们符合函数的要求。 ### 回答2: "failed to execute 'createobjecturl' on 'url': overload resolution failed" 是一个 JavaScript 错误。在使用 createObjectURL() 方法时,如果参数类型不正确或参数数量不符合要求,就会出现这个错误。 createObjectURL() 是一个用于创建 URL 对象的方法,它接受一个参数。这个参数可以是 Blob、File 或 MediaSource 对象,用于创建一个 URL 对象,以便在页面上播放视频或显示图片等内容。 当这个方法的参数不符合要求时,就会出现 "overload resolution failed" 的错误。这个错误表示使用的 createObjectURL() 方法的版本不支持调用当前提供的参数或参数组合。 可能出现这个错误的原因也很简单。可能错误的情况有: 1. 参数类型不正确 如果传入的参数不是 Blob、File 或 MediaSource 对象,就会导致这个方法无法执行,从而报错。因此,应该先检查传入的参数类型是否正确。 2. 参数数量不符合要求 如果传入的参数数量不符合要求,比如 createObjectURL() 方法只能接受一个参数,如果传入了两个参数,就会导致这个方法无法执行,从而报错。 综上所述,当出现 "failed to execute 'createobjecturl' on 'url': overload resolution failed" 错误的时候,应该先检查传入的参数类型是否正确,再检查传入的参数数量是否符合要求。如果这些方面都没有问题,可以考虑使用另外一个方法来达到相同的目的,比如 URL.createObjectURL() 方法。 ### 回答3: 当我们在浏览器开发过程中使用了 “createobjecturl” 方法时,有时会出现 “failed to execute 'createobjecturl' on 'url': overload resolution failed" 的错误提示。 这个错误提示实际上是因为我们使用 “createobjecturl” 方法时,传递的参数类型不匹配导致的。 在JavaScript 中,“createobjecturl” 方法主要用于创建表示指定 Blob 对象或者 File 对象的 URL。 通常情况下,我们的代码实现是如下所示: ```javascript var file = document.getElementById ('file').files [0]; var url = window.URL.createObjectURL (file); ``` 在这个代码示例中,我们尝试使用 “createobjecturl” 方法,创建一个表示指定 File 对象的 URL。 但是,由于某些原因(如浏览器版本更新、JavaScript 引擎优化等),在执行代码时,我们传递的参数类型不符合该方法的要求,导致了方法解析失败的错误。 解决这个问题的方法非常简单,我们只需要确认传递给 “createobjecturl” 方法的参数是否合适即可。 我们可以查看浏览器开发文档或者使用控制台进行调试,找到问题的根本原因。 在有些情况下,我们可以使用其他方法来代替 “createobjecturl” 方法,比如使用 FileReader 对象读取文件数据等等。 总之,只要我们认真分析错误提示信息,找到问题原因,再针对性地进行优化和调整,便能够解决这个问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MichelleChung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值