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⽂件望知情⼤佬指证。