java通过poi生成excel并下载出现文件打不开、文件格式和文件扩展名无效问题的分析与解决

您所在的位置:网站首页 excel无法打开xlsx文件是什么原因 java通过poi生成excel并下载出现文件打不开、文件格式和文件扩展名无效问题的分析与解决

java通过poi生成excel并下载出现文件打不开、文件格式和文件扩展名无效问题的分析与解决

2023-07-26 06:28| 来源: 网络整理| 查看: 265

需求描述: 需要完成这样一个功能:后台通过poi生成excle,前台点击按钮可直接下载。 代码逻辑(核心部分):

第一种:

public String generatePlanExcel(@RequestParam(value = "planId") int planId, HttpServletRequest request, HttpServletResponse response) throws Exception{ // 1.创建新的Excel工作簿(workbook) // 1.1 07版本的Excel需要XSSFWorkbook对象 Workbook workbook = new XSSFWorkbook(); // 2.使用workbook创建sheet // 2.1在Excel工作簿中建一工作表(sheet),其名为缺省值 Sheet0 //Sheet sheet = workbook.createSheet(); // 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/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 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 Exception{ // 1.创建新的Excel工作簿(workbook) // 1.1 07版本的Excel需要XSSFWorkbook对象 Workbook workbook = new XSSFWorkbook(); // 2.使用workbook创建sheet // 2.1在Excel工作簿中建一工作表(sheet),其名为缺省值 Sheet0 //Sheet sheet = workbook.createSheet(); // 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(); // 设置response的Header 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/vnd.ms-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();// 删除临时文件 } }

问题描述: 接口写完之后,通过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");

在网上找到的所有的解决方法都尝试仍然无效之后,找到了这篇博客 使用httpServletResponse和POI写入excle时标题和内容乱码的问题解决 发现,如果单纯没有和前台对接的前提下,使用swagger或者postman进行接口测试,无论怎么修改response的header都没有办法下载出正常的excel文件,但是通过在浏览器中直接输入url的方式,就得到了正常的可打开且格式正确的excel。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 至于为何通过swagger和postman无法下载处正常的可打开的excel文件望知情大佬指证。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3