Sptingboot项目
— maven打包,云效,docker,k8s
场景
— 导出excel模板
问题
1.乱码
2.下载为0KB,打开没有数据
模板内容
测试代码
测试方法
方法 | 过程 | 结果 | 问题原因 |
---|---|---|---|
将文件直接放到服务器 | 使用接口下载 | 数据正常,排除文件问题 | 排除接口问题,文件问题 |
文件放到resource目录下 | 使用接口下载 | 下载乱码 | 使用相同接口下载乱码,猜测是maven编译问题 |
文件移出到resouce目录外 | 使用接口下载 | 下载为0KB | 使用相同接口下载乱码,猜测是maven编译问题 |
代码
InputStream inputStream = null;
ServletOutputStream servletOutputStream = null;
try {
//注意修改目录
Resource resource = new DefaultResourceLoader().getResource("classpath:file/goods_import.xls");
response.setContentType("application/force-download");
response.setHeader("Content-Disposition", "attachment;fileName=" + new String("goods_import".getBytes(), StandardCharsets.ISO_8859_1)
+ ".xls");
inputStream = resource.getInputStream();
servletOutputStream = response.getOutputStream();
IOUtils.copy(inputStream, servletOutputStream);
response.flushBuffer();
} catch (Exception e) {
log.error("下载批量上传用户模板文件错误", e);
} finally {
try {
if (servletOutputStream != null) {
servletOutputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (Exception e) {
log.error("下载批量上传用户模板文件错误", e);
}
}
过程-可以跳过直接看解决办法
— 遵循网上的办法,使用字节流,设置字节大小,设置编码,都测试过一遍。
设置字节大小
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("classpath:file/goods_import.xls");
File file = new File("goods_import.xls"); // 指定下载文件的路径和名称
try (OutputStream outputStream = new FileOutputStream(file)) {
// 将inputStream中的数据写入到outputStream中,确保文件不为0KB
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace(); // 处理异常
}finally {
if (file.exists()){
file.delete();
}
}
设置字符集编码
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=\"" + "file/goods_import.xls" + "\"");
//这里设置为GBK,UTF-8都不行
response.setCharacterEncoding("GBK");
try (BufferedInputStream inputStream = new BufferedInputStream(ImportBusiness.class.getClassLoader().getResourceAsStream("file/goods_import.xls"));
OutputStream outputStream = response.getOutputStream()) {
if (inputStream == null) {
// 处理文件未找到的情况
response.sendError(HttpServletResponse.SC_NOT_FOUND, "File not found");
return;
}
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
} catch (IOException e) {
// 处理IO异常
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "IO error");
}
使用字节流输出
/**
* 模板下载
*/
public void downloadTemplate(HttpServletResponse response) {
OutputStream out = null;
InputStream in = null;
ByteArrayOutputStream bos = null;
String fileName = "good_import";
try {
// 读取模板
Resource res = new ClassPathResource("classpath:file/goods_import.xls");
XSSFWorkbook workbook = new XSSFWorkbook(res.getInputStream());
// 转换为字节流
bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] barray = bos.toByteArray();
in = new ByteArrayInputStream(barray);
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
out = response.getOutputStream();
byte[] b = new byte[1024];
int len;
while ((len = in.read(b)) > 0) {
out.write(b, 0, len);
}
out.flush();
} catch (Exception e) {
log.error("下载模板失败", e);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
log.error("关闭资源异常", e);
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
log.error("关闭资源异常", e);
}
}
if (null != bos) {
try {
bos.flush();
bos.close();
} catch (IOException e) {
log.error("关闭资源异常", e);
}
}
}
}
经测试以上方法均不行,然后考虑到jar打包会被编译,会不会是这个导致的呢。能不能忽略掉这个xls文件呢?
这里使用maven打包,使用提供的插件排除,如下
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
重新调用接口下载,文件正常