java下载xlsx文件_【小坑】java下载excel文件

本文记录了在Java中下载xlsx文件时遇到的问题,包括inputstream序列化错误、读取resources下xlsx文件的问题、zip压缩导致的异常、读取问题以及excel单元格换行的处理。解决方案包括将inputstream转换为byte[],处理资源文件的打包方式,正确读取inputstream,以及处理包含换行的单元格。最后提到了使用window.open而非ajax进行文件下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

excel文件的导入导出是很常见的功能,这次做了个下载的功能,踩了一些坑,记下来避免以后重复踩……

1、inputstream序列化问题

Could not write JSON document: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer

客户端调取服务端上传,从前台获取的file文件中拿到inputstream,做一些判断后(格式校验、大小校验等)将inputstream作为参数传给服务端报如下错误:

Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON document: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

因为输入流InputStream序列化错误。计算机传输数据实际上是二进制的传输,将inputstream转化为字节数组就可以通过网络流进行传输了,使用byte[] 来替代InputStream。

2、读取resources下的xlsx文件

将xlsx文件放项目resources目录下,通过以下代码本地调试通过:

InputStream templateStream =ClassUtils.getDefaultClassLoader().getResourceAsStream(TEMPTALTE);int len =templateStream.available();byte[] readBuf = new byte[len];

templateStream.read(readBuf,0, len);

将inputstream读入到readBuf里,再将readBuf传给服务端。本地测试通过,放到测试环境,于是开始了填坑……

3、java.util.zip.ZipException: invalid stored block lengths

是因为打为jar包时对resources资源文件进行了转码压缩,直接读取inputstream使用无法识别。将jar包解压缩,打开里面的xlsx文件,报错提示:

a37c5a207ed56d7df1f6a649f3c138b0.png  

aa1b37ffb3eb8f8c39cddfe750401b4f.png

按文中办法添加maven插件,打包时对xls和xlsx文件不进行转码压缩。

org.apache.maven.plugins

2.6

maven-resources-plugin

UTF-8

xlsx

添加排除xlsx打包压缩之后,从打完的jar包解压缩出的xlsx可以正常打开。

4、read读取的问题

a64e669e41e9fe5e372a061abdc48928.png

由提示信息得知:这个问题报的是格式或扩展名的问题。而扩展名是没有问题了,经检查发现是格式的问题,本地调试的时候读取的是正确完整的byte[]数据,测试环境读取的不全或没有读取数据。

查看inputstream的read(byte b[], int off, int len)方法

* Reads up to len bytes of data from the input stream into

* an array of bytes. An attempt is made to read as many as

* len bytes, but a smaller number may be read.

* The number of bytes actually read is returned as an integer.

修改如下:

InputStream templateStream =ClassUtils.getDefaultClassLoader().getResourceAsStream(TEMPLATE);

ByteArrayOutputStream baos= newByteArrayOutputStream();byte[] buffer = new byte[2048];int num = -1;while((num = templateStream.read(buffer)) != -1){

baos.write(buffer,0, num);

}

baos.flush();

baos.toByteArray();

baos.close();

5、excel单元格包含换行

读取excel到json,然后通过fastjson反序列化为list对象。当excel单元格包含换行符时报错:(参考:用java导入导出excel如何去掉软回车和硬回车)

Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value excel

一种方法是替换掉excel的特殊字符

for(int i=10;i<14;i++)

{

str= str.replaceAll(String.valueOf((char)i), "");

}

另一种方法是正则替换

//空格\t、回车\n、换行符\r、制表符\t

Pattern p = Pattern.compile("\\s*|\t|\r|\n");

Matcher m=p.matcher(str);

dest= m.replaceAll("");

6、ajax下载

由于ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以通过ajax去请求该接口是无法下载。查看XHR,可以看到返回的报文体。

window.open("下载文件的后端接口")

构建一个表单实现下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值