记录一次开发下载excel模板记录
项目场景:
需求是下载excel导入模板
问题描述:
代码中模板位置:
代码是这样的:
//获取模板文件输入流
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(IntegralConstants.INTEGRAL_BATCH_ISSUE_TEMPLATE_PATH);
//下载文件
public static void download(HttpServletResponse response, InputStream inputStream, String filename) {
OutputStream outputStream = null;
try {
setHeader(response, filename);
outputStream = response.getOutputStream();
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
outputStream.write(buffer);
} catch (Exception e) {
log.error("download.error:{}", Throwables.getStackTraceAsString(e));
} finally {
try {
inputStream.close();
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (Exception ex) {
log.error("download.close.error:{}", Throwables.getStackTraceAsString(ex));
}
}
}
private static void setHeader(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
response.reset();
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.setCharacterEncoding("utf-8");
}
结果是本地下载文件格式错误,我找到target中的excel模板文件,发现打开也是文件损坏,这应该是文件打包时的问题,因为打为jar包时对resources资源文件进行了转码压缩。
于是在pom文件中添加了mavn插件,打包时跳过对xls和xlsx文件的转码压缩。
<!--编译跳过ecxel-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
这时候本地下载成功,但是部署到服务器,依旧下载的文件是损坏文件。
原因分析:
本地调试的时候读取的是正确完整的byte[]数据,可能开发环境上读取的不全或没有读取数据,查看了下源码:
解决方案:
于是尝试读取一部分就写一部分,写完为止,修改如下
public static void download(HttpServletResponse response, InputStream inputStream, String filename) {
OutputStream outputStream = null;
try {
setHeader(response, filename);
outputStream = response.getOutputStream();
byte[] b = new byte[1024];
int len;
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
//byte[] buffer = new byte[inputStream.available()];
//inputStream.read(buffer);
//outputStream.write(buffer);
} catch (Exception e) {
log.error("download.error:{}", Throwables.getStackTraceAsString(e));
} finally {
try {
inputStream.close();
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (Exception ex) {
log.error("download.close.error:{}", Throwables.getStackTraceAsString(ex));
}
}
}
再次部署,本地和开发环境下载的模板都完好;