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 07版本的Excel需要XSSFWorkbook对象
Workbook workbook =new XSSFWorkbook();
// 2.使⽤workbook创建sheet
// 2.1在Excel⼯作簿中建⼀⼯作表(sheet),其名为缺省值 Sheet0
//Sheet sheet = ateSheet();
// 2.2如要新建⼀名为"预案详细信息"的⼯作表,其语句为:
Sheet sheet = ateSheet("预案详细信息");
...
String fileName = Name()+".xlsx";
ByteArrayOutputStream os =new ByteArrayOutputStream();
workbook.write(os);
byte[] content = os.toByteArray();
InputStream is =new ByteArrayInputStream(content);
// 设置response参数,可以打开下载页⾯
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition","attachment;filename="+ de(fileName,"utf-8"));
response.setHeader("Content-Length", String.valueOf(is.available()));
response.setCharacterEncoding("UTF-8");
ServletOutputStream sout = OutputStream();
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 = ad(buff,0, buff.length))){
bos.write(buff,0, bytesRead);
}
}catch(Exception e){
<("导出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 07版本的Excel需要XSSFWorkbook对象
Workbook workbook =new XSSFWorkbook();
// 2.使⽤workbook创建sheet
// 2.1在Excel⼯作簿中建⼀⼯作表(sheet),其名为缺省值 Sheet0
//Sheet sheet = ateSheet();
// 2.2如要新建⼀名为"预案详细信息"的⼯作表,其语句为:
Sheet sheet = ateSheet("预案详细信息");
//临时⽂件
File tempFile = null;
try{
//要保存的⽂件名
String filename = Name()+".xlsx";
/
/要保存的根⽬录
String rootDir = Session().getServletContext().getRealPath("/");
//要保存的⽬录路径
String path = rootDir + File.separator +"tempfile";
File saveDir =new File(path);
if(!ists()){
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();
// 以流的形式下载⽂件。
getsavefilename
BufferedInputStream fis =new BufferedInputStream(new FileInputStream(path));
byte[] buffer =new byte[fis.available()];
fis.close();
// 清空response
// 设置response的Header
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition","attachment;filename="+ de(fileName,"utf-8")); response.setHeader("Content-Length",""+ tempFile.length());
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
OutputStream toClient =new OutputStream());
toClient.write(buffer);
toClient.flush();
toClient.close();
}catch(Exception e){
e.printStackTrace();
}finally{
if(tempFile != null && ists()){
tempFile.delete();// 删除临时⽂件
}
}
问题描述:
接⼝写完之后,通过swagger和postman进⾏测试发现⽂件⽆法正常打开。
下载的⽂件是这样的:
⽤WPS打开该⽂件是这样的:
⽤office Excel打开该⽂件是这样的:
刚开始感觉是⾃⾝代码出现了问题,但是通过第⼆种先⽣成临时⽂件的⽅式实现excel下载,我在本地打开临时⽣成的excel⽂件是没有问题的,通过流的⽅式转换和下载之后就仍然出现上⾯的问题。于是乎感觉可能是response设置的问题,便开始了长达2⼩时的百度求知。
查到的解决⽅式很多都是重复的,⼤致上可以分为:
1.说response中必须有这⾏设置
response.setHeader("Content-Length", fis.available()+"");
2.说创建xls与xlsx⼯作薄的不同
导出xlsx格式,创建⼯作薄的时候⽤:
Workbook workbook =new XSSFWorkbook();
导出xls格式,创建⼯作薄的时候⽤:
Workbook workbook =new HSSFWorkbook();
3.说response.setContentType设置的不同
导出xlsx格式设置ContentType需要:
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
导出xls格式设置ContentType需要:
response.setContentType("application/vnd.ms-excel");
在⽹上到的所有的解决⽅法都尝试仍然⽆效之后,到了这篇博客
发现,如果单纯没有和前台对接的前提下,使⽤swagger或者postman进⾏接⼝测试,⽆论怎么修改response的header都没有办法下载出正常的excel⽂件,但是通过在浏览器中直接输⼊url的⽅式,就得到了正常的可打开且格式正确的excel。
⾄于为何通过swagger和postman⽆法下载处正常的可打开的excel⽂件望知情⼤佬指证。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论