使用SXSSFWorkbook导出Excel图片空白,HSSFWorkbook正常的解决咨询
SXSSFWorkbook导出图片为空的解决方法
你的测试用例如下:
@Test public void testXSSF() throws IOException { String[] imgs = { "D:/EvaluationProject/uploadPath/upload/2023/07/24/f5214a64-72a7-41e6-a4e9-a64c992feaad.jpg", "D:/EvaluationProject/uploadPath/upload/2023/07/24/7fbc9564-2f2d-4dcd-959c-efc2d86191b5.jpg", "D:/EvaluationProject/uploadPath/upload/2023/07/24/405ad233-0a4a-4f13-b0e9-4a96f6fe530f.jpg", "D:/EvaluationProject/uploadPath/upload/2023/07/24/37b01589-dd2b-4703-9edb-064734efb3bd.jpg" }; SXSSFWorkbook workBook = new SXSSFWorkbook(); SXSSFSheet sheet = workBook.createSheet(); sheet.setColumnWidth(0, 4800 * imgs.length); BufferedImage bufferedImage = null; Drawing patriarch = sheet.createDrawingPatriarch(); try { SXSSFRow imgRow = sheet.createRow(0); imgRow.setHeight((short) 1000); int mar = 10 + 10 + (imgs.length - 1) * 10; int ave = (1023 - mar) / imgs.length; for (int i = 0; i < imgs.length; i++) { File file = new File(imgs[i]); bufferedImage = ImageIO.read(file); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); XSSFClientAnchor anchor = new XSSFClientAnchor(10 * (i + 1) + ave * i, 10, (10 + ave) * (i + 1), 245, (short) 1, 1, (short) 1, 1); patriarch.createPicture(anchor, workBook.addPicture(byteArrayOutputStream.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG)); } FileOutputStream outputStream = new FileOutputStream("D://" + new Date().getTime() + ".xls"); workBook.write(outputStream); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } }
切换为SXSSFWorkbook后图片为空的核心问题及解决方法:
- 锚点类不兼容:SXSSF需使用对应的
SXSSFClientAnchor,不能混用XSSF的锚点类,两者底层实现逻辑不匹配。 - 文件格式错误:SXSSFWorkbook对应OOXML格式的Excel文件(后缀应为
.xlsx),保存为.xls会导致内容解析异常。 - 绘图对象类型匹配:明确将绘图对象转为
SXSSFDrawing,确保与SXSSF体系的API兼容。
修改后的可运行代码:
@Test public void testSXSSF() throws IOException { String[] imgs = { "D:/EvaluationProject/uploadPath/upload/2023/07/24/f5214a64-72a7-41e6-a4e9-a64c992feaad.jpg", "D:/EvaluationProject/uploadPath/upload/2023/07/24/7fbc9564-2f2d-4dcd-959c-efc2d86191b5.jpg", "D:/EvaluationProject/uploadPath/upload/2023/07/24/405ad233-0a4a-4f13-b0e9-4a96f6fe530f.jpg", "D:/EvaluationProject/uploadPath/upload/2023/07/24/37b01589-dd2b-4703-9edb-064734efb3bd.jpg" }; // 指定内存保留行数,优化大文件内存占用 SXSSFWorkbook workBook = new SXSSFWorkbook(100); SXSSFSheet sheet = workBook.createSheet(); sheet.setColumnWidth(0, 4800 * imgs.length); BufferedImage bufferedImage = null; SXSSFDrawing patriarch = (SXSSFDrawing) sheet.createDrawingPatriarch(); try { SXSSFRow imgRow = sheet.createRow(0); imgRow.setHeight((short) 1000); int mar = 10 + 10 + (imgs.length - 1) * 10; int ave = (1023 - mar) / imgs.length; for (int i = 0; i < imgs.length; i++) { File file = new File(imgs[i]); bufferedImage = ImageIO.read(file); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); // 使用SXSSF专属锚点类 SXSSFClientAnchor anchor = new SXSSFClientAnchor(10 * (i + 1) + ave * i, 10, (10 + ave) * (i + 1), 245, (short) 0, 0, (short) 0, 0); patriarch.createPicture(anchor, workBook.addPicture(byteArrayOutputStream.toByteArray(), SXSSFWorkbook.PICTURE_TYPE_JPEG)); } // 保存为正确的.xlsx格式 FileOutputStream outputStream = new FileOutputStream("D://" + new Date().getTime() + ".xlsx"); workBook.write(outputStream); outputStream.close(); // 清理SXSSF生成的临时文件 workBook.dispose(); } catch (Exception e) { e.printStackTrace(); } }
额外优化提示:
- SXSSFWorkbook构造器传入的数字代表内存中保留的行数,超过该数量的行会被写入临时文件,可根据数据量调整避免内存溢出。
- 调用
dispose()方法可以及时清理SXSSF生成的临时文件,避免磁盘空间浪费。
内容的提问来源于stack exchange,提问作者yi deng
相关产品推荐
相关产品推荐

