java - 使用 Apache POI 写入 Unicode Plane 1 字符

标签 java excel character-encoding apache-poi

我正在尝试将 Unicode 字符写入 Excel 文件。我在 Unicode 平面 0 上成功完成了此操作,但在 Unicode 平面 1 上失败了。

我使用 POI 3.16 并使用这段简单的代码进行测试:

    public void createFile() throws IOException {
        SXSSFWorkbook workbook = new SXSSFWorkbook(1);
        SXSSFSheet sheet = workbook.createSheet("data");

        Row row = sheet.createRow(0);
        Cell cell = row.createCell(0);
        String value = "💩💩💩ᚬᚬᚬ";
        cell.setCellValue(value);

        try (FileOutputStream fop = new FileOutputStream("C:\\Users\\Emilien\\PROJECTS_FILES\\BUGS\\SLIMS_14124\\test.xlsx")) {
            workbook.write(fop);
        } finally {
            workbook.dispose();
        }
    }

在 Excel 2016 中,单元格包含“??????ᚬᚬᚬ”,而不是显示“💩💩💩ᚬᚬᚬ”。 在这里查找有关角色的 URL 在这里💩 .

我解压了excel文件并调查了sheetdata的内容,单元格对应的XML内容是:

<row r="1">
   <c r="A1" t="inlineStr"><is><t>??????&#5804;&#5804;&#5804;</t></is></c> 
</row>

我们可以看到,平面 0 字符已转换为 HTML Unicode 字符,而平面 1 字符已丢失。

如果我改变“??????”通过 XML 文件中的“💩💩💩”,然后再次将文件压缩到新的 xlsx 文件中,字符将按需要渲染(也就是说,该单元格实际上包含 💩💩💩ᚬᚬᚬ)。

Java 字符串似乎没有以 UTF-8 的形式写入 XML,而是经过 POI 处理(最终得到 HTML 字符)。有谁之前经历过这个吗 ?是否可以将 SMP 字符写入 Excel 文件?

这可能是一个错误吗?我的意思是,XML 文件在其 header 中声明了 UTF-8 编码,但似乎并不遵循它。我错过了什么吗?

<?xml version="1.0" encoding="UTF-8"?>

最佳答案

解决方案有所不同,具体取决于 apache poi 的流部分 SXSSFapache poi< 的默认 XSSF 部分使用

There was a problem with xmlbeans-2.6.0.jar 3.17 版本之前的 apache poi 用于访问 XML。该库已将字符的高代理范围 (\uD800-\uDBFF) 和低代理范围 (\uDC00-\uDFFF) 排除为“坏字符”。这就是为什么所有需要这些代理范围的 Unicode 都无法正确处理的原因。这是从 0x10000 向上的 Unicode 范围。请参阅Supplementary Characters as Surrogates .

然后,在 apache poi 版本 3.17 中,这个问题在其流 SXSSF 部分中得到了解决,因此 SXSSF也使用 xmlbeans-2.6.0.jar 工作。因此,流式 SXSSF 部分的解决方案只需更新到 apache poi 版本 3.17

但是 SXSSF 默认情况下会创建内联字符串,并且其工作方式与 XSSF 部分不同。这就是为什么当需要 0xFFFF 以上的 Unicode 并使用 xmlbeans-2.6.0.jar 时,XSSF 会进一步创建错误的 XML。为了在 XSSF 中解决这个问题,需要更新版本的 XMLBeans。有 xmlbeans-2.6.2.jar 和现在 xmlbeans-3.0.0.jar 可用。两者都通过 apache poiXSSF 部分解决问题。

关于java - 使用 Apache POI 写入 Unicode Plane 1 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51838159/

相关文章:

python - 有没有办法改变 Python 的 open() 默认文本编码?

匈牙利语字符的 MySQL 错误 ORDER BY

java - 查找字符串中的子序列

java - 为什么 gluProject 不使用 LWJGL 给出正确的屏幕空间坐标

java - 如何在 Hibernate 中内连接两个独立实体

java - 创建一个只有可见边框的框架来选择屏幕区域

excel - 需要 Excel 公式返回 "Yes"/"No"而不是 bool 值

java - 方法调用后将任务计时器重置为 0

excel - VBA - 在条形图中写入值

excel - Excel VBA中的多列自动筛选