excel文件是本来存在的,放在resources/static目录下,提供接口给前端下载。下载的文件用office打开时,一直提示如下:
虽然最终能打开,但是.................
这种情况在本机eclipse中测试的时候都没有问题,只有打成jar包后才出现。度娘查到各种各样的说法,比如修改response请求回应头,比如使用ByteArrayHttpMessageConverter,比如修改文件读取方式,没点屁用!!
0.原来下载用的方法:文件输出流方式下载(下载的文件打开提示错误的)
package com.test.demo.service.impl;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import com.test.demo.service.DownLoadService;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.URLUtil;
@Service
public class DownLoadServiceImpl implements DownLoadService {
@Override
public void excelTemplateDownLoad(HttpServletRequest req, HttpServletResponse res) throws Exception {
String path = "static/excel/test.xls";
String fileName = path.substring(path.lastIndexOf("/") + 1);
String userAgent = req.getHeader("User-Agent");
// 针对IE或者以IE为内核的浏览器:
if(userAgent.contains("MSIE")||userAgent.contains("Trident")) {
fileName = URLUtil.encode(fileName,"UTF-8");
}else {
// 非IE浏览器的处理:
fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
}
res.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
res.setContentType("application/vnd.ms-excel; charset=utf-8");
res.setCharacterEncoding("UTF-8");
// 读取服务器端模板文件
InputStream inputStream = FileUtil.getInputStream(path);
// 将流中内容写出去
OutputStream outputStream = res.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
inputStream.close();
outputStream.close();
}
}
解决办法1:使用spring boot 静态资源下载的方式;这种方式下不需定义接口,权限等问题不可控(未测试,这个方法是借鉴网上的,顺便记录下来)
将资源文件放到resource/static目录下,启动服务,使用 IP:端口/文件路径 下载即可;这种方案下,需要将pom文件下的resource.filtering要设置为false,打成jar之后,也是正常可用的;
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/webapp</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</build>
解决办法2:使用文件输出流的方式下载,接口实现过程,使用POI的Workbook输出流(我用的这个办法,现在下载下来的excel不提示错误了)
和原来的方法差不多,只是文件用POI的XSSFWorkbook(HSSFWorkbook)处理了一下,流中写出的是HSSFWorkbook对象
public void downDeviceManagementTemplate(HttpServletRequest req, HttpServletResponse res) throws IOException {
String path = "static/excel/test.xls";
String fileName = path.substring(path.lastIndexOf("/") + 1);
// 读取服务器端模板文件
InputStream inputStream = FileUtil.getInputStream(path);
// 转为POI的Workbook输出流,这样下载后 打开不报错,直接输出 流 的话,打开excel可能提示错误
@SuppressWarnings("resource")
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
String userAgent = req.getHeader("User-Agent");
// 针对IE或者以IE为内核的浏览器:
if(userAgent.contains("MSIE")||userAgent.contains("Trident")) {
fileName = URLUtil.encode(fileName,"UTF-8");
} else {
// 非IE浏览器的处理:
fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
}
res.setHeader("Content-disposition", "attachment; filename=" + fileName);
res.setContentType("application/vnd.ms-excel; charset=utf-8");
res.setCharacterEncoding("UTF-8");
// 将流中内容写出去
OutputStream outputStream = res.getOutputStream();
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
}
PS:代码中用到的FileUtil工具类用的是 hutool
工具包中的
网友评论