2023年11月25日发(作者:)
java通过poi⽣成excel并下载出现⽂件打不开、⽂件格式和⽂件扩展名⽆效问题
的分析与解决
需求描述:
需要完成这样⼀个功能:后台通过poi⽣成excle,前台点击按钮可直接下载。
代码逻辑(核⼼部分):
第⼀种:
public String generatePlanExcel(@RequestParam(value = "planId") int planId, HttpServletRequest request, HttpServletResponse response) throws Excepti
on{
// 1.Excel(workbook)
创建新的⼯作簿
// 1.1 07ExcelXSSFWorkbook
版本的需要对象
Workbook workbook = new XSSFWorkbook();
// 2.workbooksheet
使⽤创建
// 2.1Excel(sheet) Sheet0
在⼯作簿中建⼀⼯作表,其名为缺省值
//Sheet sheet = Sheet();
// 2.2""
如要新建⼀名为预案详细信息的⼯作表,其语句为:
Sheet sheet = workbook.createSheet("预案详细信息");
...
String fileName = planRecordAndResources.getName() + ".xlsx";
ByteArrayOutputStream os = new ByteArrayOutputStream();
workbook.write(os);
byte[] content = os.toByteArray();
InputStream is = new ByteArrayInputStream(content);
// response
设置参数,可以打开下载页⾯
response.reset();
response.setContentType("application/");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"utf-8"));
response.setHeader("Content-Length", String.valueOf(is.available()));
response.setCharacterEncoding("UTF-8");
ServletOutputStream sout = response.getOutputStream();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(sout);
byte[] buff = new byte[2048];
int bytesRead;
// Simple read/write loop.
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
} catch (Exception e) {
logger.error("导出excel出现异常:", e);
} finally {
if (bis != null){
bis.close();
}
if (bos != null){
bos.close();
}
}
...
}
第⼆种:
public String generatePlanExcel(@RequestParam(value = "planId") int planId, HttpServletRequest request, HttpServletResponse response) throws Excepti
on{
// 1.Excel(workbook)
创建新的⼯作簿
// 1.1 07ExcelXSSFWorkbook
版本的需要对象
Workbook workbook = new XSSFWorkbook();
// 2.workbooksheet
使⽤创建
// 2.1Excel(sheet) Sheet0
在⼯作簿中建⼀⼯作表,其名为缺省值
//Sheet sheet = Sheet();
// 2.2""
如要新建⼀名为预案详细信息的⼯作表,其语句为:
Sheet sheet = workbook.createSheet("预案详细信息");
//
临时⽂件
File tempFile = null;
try {
//
要保存的⽂件名
String filename = planRecordAndResources.getName() + ".xlsx";
//
要保存的根⽬录
String rootDir = request.getSession().getServletContext().getRealPath("/");
//
要保存的⽬录路径
String path = rootDir + File.separator + "tempfile";
File saveDir = new File(path);
if (!saveDir.exists()) {
saveDir.mkdirs();//
如果⽂件不存在则创建⽂件夹
}
//
⽂件路径
path = path + File.separator + filename;
//
初始化临时⽂件
tempFile = new File(path);
//
输出流
OutputStream out = new FileOutputStream(tempFile);
try {
//
保存⽂件
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}
out.close();
//
以流的形式下载⽂件。
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// response
清空
response.reset();
// responseHeader
设置的
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"utf-8"));
response.setHeader("Content-Length", "" + tempFile.length());
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setContentType("application/-excel;charset=UTF-8");
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (tempFile != null && tempFile.exists()) {
tempFile.delete();//
删除临时⽂件
}
}
问题描述:
response.setHeader("Content-Length", fis.available()+"");
2.说创建xls与xlsx⼯作薄的不同
导出xlsx格式,创建⼯作薄的时候⽤:
Workbook workbook = new XSSFWorkbook();
导出xls格式,创建⼯作薄的时候⽤:
Workbook workbook = new HSSFWorkbook();
3.说tentType设置的不同
导出xlsx格式设置ContentType需要:
response.setContentType("application/");
导出xls格式设置ContentType需要:
response.setContentType("application/-excel");
在⽹上找到的所有的解决⽅法都尝试仍然⽆效之后,找到了这篇博客
发现,如果单纯没有和前台对接的前提下,使⽤swagger或者postman进⾏接⼝测试,⽆论怎么修改response的header都没有办法下载
出正常的excel⽂件,但是通过在浏览器中直接输⼊url的⽅式,就得到了正常的可打开且格式正确的excel。
⾄于为何通过swagger和postman⽆法下载处正常的可打开的excel⽂件望知情⼤佬指证。
发布评论