使用Apache POI写入Excel时抛出IllegalArgumentException问题
Apache POI写入Excel时出现IllegalArgumentException的解决方法
问题场景
尝试用Apache POI写入新Excel文件,代码如下:
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; class Scratch { public static void main(String[] args) throws IOException { XSSFWorkbook excelWB = null; try { String fileName = "C:\\Users\\frank\\Desktop\\Output\\test.xlsx"; System.out.println("fileName: " + fileName); excelWB = new XSSFWorkbook(); XSSFSheet sheet = excelWB.createSheet("PartList"); XSSFRow headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("Type"); XSSFRow dataRow = sheet.createRow(1); dataRow.createCell(0).setCellValue("0th column"); dataRow.createCell(1).setCellValue("1st column"); FileOutputStream fileOut = new FileOutputStream(fileName); excelWB.write(fileOut); fileOut.close(); } catch (Exception e) { e.printStackTrace(); } finally { //assert excelWB != null; excelWB.close(); } } }
执行时抛出IllegalArgumentException,报错信息如下:
14:24:12.172 [main] WARN org.apache.poi.util.XMLHelper - SAX Feature unsupported [log suppressed for 5 minutes] http://javax.xml.XMLConstants/property/accessExternalStylesheet java.lang.IllegalArgumentException: Not supported: http://javax.xml.XMLConstants/property/accessExternalStylesheet at org.apache.xalan.processor.TransformerFactoryImpl.setAttribute(TransformerFactoryImpl.java:571) at org.apache.poi.util.XMLHelper.trySet(XMLHelper.java:283) at org.apache.poi.util.XMLHelper.getTransformerFactory(XMLHelper.java:224) at org.apache.poi.util.XMLHelper.newTransformer(XMLHelper.java:230) at org.apache.poi.openxml4j.opc.StreamHelper.saveXmlInStream(StreamHelper.java:56) at org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager.saveImpl(ZipContentTypeManager.java:68) at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.save(ContentTypeManager.java:450) at org.apache.poi.openxml4j.opc.ZipPackage.saveImpl(ZipPackage.java:563) at org.apache.poi.openxml4j.opc.OPCPackage.save(OPCPackage.java:1490) at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:227) at Scratch.main(20240726.excel.hata.java:27)
问题原因
该错误是由于Apache POI尝试设置http://javax.xml.XMLConstants/property/accessExternalStylesheet这个XML安全属性,但当前使用的TransformerFactory实现(如旧版Xalan)不支持该属性导致的。
解决方法
方法1:升级Apache POI版本
将Apache POI升级到5.2.5及以上的稳定版本,新版本已修复该兼容性问题,会自动跳过不支持的属性设置,无需修改代码。
方法2:指定兼容的TransformerFactory实现
在代码开头添加系统属性设置,指定支持该属性的TransformerFactory:
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
或者在JVM启动时添加参数:
-Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
方法3:优化代码资源管理(可选)
建议使用try-with-resources语法自动关闭流,避免资源泄漏,修正后的完整代码如下:
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; class Scratch { public static void main(String[] args) throws IOException { // 指定兼容的TransformerFactory System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); XSSFWorkbook excelWB = null; try { String fileName = "C:\\Users\\frank\\Desktop\\Output\\test.xlsx"; System.out.println("fileName: " + fileName); excelWB = new XSSFWorkbook(); XSSFSheet sheet = excelWB.createSheet("PartList"); XSSFRow headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("Type"); XSSFRow dataRow = sheet.createRow(1); dataRow.createCell(0).setCellValue("0th column"); dataRow.createCell(1).setCellValue("1st column"); // 使用try-with-resources自动关闭流 try (FileOutputStream fileOut = new FileOutputStream(fileName)) { excelWB.write(fileOut); } } catch (Exception e) { e.printStackTrace(); } finally { if (excelWB != null) { excelWB.close(); } } } }
内容的提问来源于stack exchange,提问作者Lyrk
相关产品推荐
相关产品推荐

