excel转为流,进行下载。本地可以,服务器报:
问题一:FileNotFoundException (文件名、目录名或卷标语法不正确。)
java.io.FileNotFoundException: file:\E:\liziyi\guopei6\gp6-exam\target\gp6-exam-0.0.1-SNAPSHOT.jar!\BOOT-INF\classes!\exceltemplate\exam_record_import_template.xls (文件名、目录名或卷标语法不正确。)
源代码报上面的错,因为服务器上是要打jar包,运行的。用getResourceAsStream()查询文件地址,会报错:
public String download(String fileName, String folder, HttpServletRequest request, HttpServletResponse response) {
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
try {
String path = this.getClass().getClassLoader().getResource(folder + "/" + fileName).getPath();
InputStream inputStream = new FileInputStream(new File(path));
OutputStream os = response.getOutputStream();
byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) > 0) {
os.write(b, 0, length);
}
// 这里主要关闭。
os.close();
inputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
解决方法:
因为jar属于压缩包,所以要使用getResourceAsStream,不能使用getResource
public String download(String fileName, String folder, HttpServletRequest request, HttpServletResponse response) {
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(folder + "/" + fileName);
OutputStream os = response.getOutputStream();
byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) > 0) {
os.write(b, 0, length);
}
// 这里主要关闭。
os.close();
inputStream.close();
} catch (FileNotFoundException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
问题二:getOutputStream() has already been called for this response
翻译:已为此响应调用 getOutputStream() 或者说:response.getOutputStream() 已经用过了不能再次使用。
但是运行的时候发现是空指针导致的,和下图勾选的两个方法没关系。
那就解决this.getClass().getClassLoader().getResourceAsStream(为什么拿到的是null
问题三:this.getClass().getClassLoader().getResourceAsStream()拿到值为Null
这个首先要考虑的是为啥取文件是null。
1.方法导致错误
先是怀疑方法用错了,毕竟用流导出文件有n种方法。下面是从网上查询的定义:
1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源。
2.Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源。
其实看不懂,感觉没问题
2.位置导致错误
我本地的是Excel文件放到Exam模块,下载Excel的方法放在model模块,Lms和Order和Exam模块调用model模块,然后去exam模块拿文件进行下载。
现在是exam模块测试可以拿到文件,其他模块不可以。因为文件不存在其他模块,所以报错。
后来把excel从exam模块挪动到各个模块,这样class就是从本模块获取excel文件。果然解决了问题。如下图:
待补充:
excel,先生成,再下载
excel使用多线程和redis下载文件