POI-Excel导出:发现xxx.xlsx中的部分内容有问题

问题场景

新项目上需要用到页面上Excel导出下载,于是把老项目中用了很久的一个Excel工具类拿了过来,因为老项目导出的是 xls文件,新项目需要导出 xlsx,就对着改了下,改完之后导出文件,发现会弹出提示

在这里插入图片描述

点击是之后,文件能正常查看,文件内容也没问题。

问题原因

开始以为是新旧Excel类型的样式不兼容,最后检查发现是导出的文件流处理有问题。

工具类中处理文件用的是字节流写入,其实不该这么做,特别是导出文件多半是有中文的情况,但是在xls文件中并没有产生问题

    public static void ioWriteForSheets(HttpServletRequest request, XSSFWorkbook workbook, HttpServletResponse response, String excelName) {
        try {
            String agent = request.getHeader("USER-AGENT");
            boolean isIe = null != agent && agent.contains("MSIE") || null != agent
                    && agent.contains("Trident") || null != agent && agent.contains("Edge");
            if (isIe) {
                // ie
                String fileName = java.net.URLEncoder.encode(excelName, "UTF8");
                response.addHeader("Content-Disposition", "attachment;filename="
                        + fileName + ".xlsx");
            } else if (null != agent && agent.contains("Mozilla")) {
                // 火狐,chrome等
                String fileName = new String(excelName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
                response.addHeader("Content-Disposition", "attachment;filename="
                        + fileName + ".xlsx");
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            workbook.write(baos);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

            OutputStream os = response.getOutputStream();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
            byte[] b = new byte[1024];
            while ((inputStream.read(b)) > 0) {
                os.write(b);
            }
            inputStream.close();
            os.flush();
            os.close();

        } catch (IOException e) {
            exceptionHandle(e);
        }
    }

其实不该这么绕,可以直接将workbook 的流写入response中,并且解决了问题 修改之后的代码:

    public static void ioWriteForSheets(HttpServletRequest request, XSSFWorkbook workbook, HttpServletResponse response, String excelName) {
        try {
            String agent = request.getHeader("USER-AGENT");
            boolean isIe = null != agent && agent.contains("MSIE") || null != agent
                    && agent.contains("Trident") || null != agent && agent.contains("Edge");
            if (isIe) {
                // ie
                String fileName = java.net.URLEncoder.encode(excelName, "UTF8");
                response.addHeader("Content-Disposition", "attachment;filename="
                        + fileName + ".xlsx");
            } else if (null != agent && agent.contains("Mozilla")) {
                // 火狐,chrome等
                String fileName = new String(excelName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
                response.addHeader("Content-Disposition", "attachment;filename="
                        + fileName + ".xlsx");
            }
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

            // 直接写入response的输出流
            workbook.write(response.getOutputStream());

        } catch (IOException e) {
            exceptionHandle(e);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章