如何打开XLSX文件以避免CharConversionException异常?
问题分析与解决
错误原因
这个CharConversionException是因为你的XLSX文件中包含了超过4字节的Unicode字符(比如部分罕见emoji、生僻表意文字或特殊符号),而Apache POI底层依赖的XMLBeans库中的Piccolo XML解析器不支持解析这类字符,导致加载SharedStringsTable(XLSX存储重复文本的核心结构)时失败。
解决方案
1. 升级Apache POI版本(推荐)
从POI 4.1.0版本开始,官方已替换老旧的Piccolo解析器,改用更兼容的Woodstox解析器,彻底解决了4字节字符的解析问题。
确保项目依赖的POI及POI-OOXML版本≥4.1.0,比如Maven依赖:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency>
2. 强制使用SAX解析器(不升级版本的临时方案)
如果暂时无法升级POI,可通过设置系统属性让XMLBeans使用SAX解析器替代Piccolo,在加载XLSX文件前添加以下代码:
System.setProperty("org.apache.xmlbeans.impl.piccolo.xml.XmlParserFactory", "org.apache.xmlbeans.impl.piccolo.xml.JAXPParserFactory");
3. 预处理文件移除非法字符
若文件可控(自行生成或可预处理),可扫描并移除超过4字节的Unicode字符:
- 生成文件场景:写入Excel时过滤掉
Character.isBmpCodePoint(c)返回false的字符; - 用户上传文件场景:先解压XLSX(本质是ZIP包),找到
xl/sharedStrings.xml文件,替换其中的4字节字符后重新打包。
4. 优化JavaFX加载逻辑避免冻结
错误导致应用冻结是因为文件加载在UI线程执行,建议将Excel加载操作放到后台线程(比如JavaFX的Task),避免阻塞UI:
Task<XSSFSheet> loadExcelTask = new Task<>() { @Override protected XSSFSheet call() throws Exception { try (FileInputStream fis = new FileInputStream(f)) { XSSFWorkbook workbook = new XSSFWorkbook(fis); return workbook.getSheetAt(0); } } }; loadExcelTask.setOnSucceeded(e -> { XSSFSheet sheet = loadExcelTask.getValue(); // 处理列数、单元格数据,更新UI int columnCount = sheet.getRow(0).getLastCellNum(); // ...后续业务逻辑 }); loadExcelTask.setOnFailed(e -> { Throwable exception = loadExcelTask.getException(); // 处理加载失败,比如弹出错误提示 exception.printStackTrace(); }); new Thread(loadExcelTask).start();
内容的提问来源于stack exchange,提问作者NebuCodeNezzar
相关产品推荐
相关产品推荐

