从docx中提取符号字符

时间:2014-02-10 19:41:34

标签: java utf-8 openxml symbols docx

我正在开发一个JAVA程序,它处理docx文件的XML内容并将其转换为特定格式。它工作得很好,但如果Word文件包含符号字符,我会遇到问题,例如希腊字母。在这种情况下,我只看到小方块。

我查看了源代码并看到如下内容:

<w:r w:rsidRPr="008E65F6"><w:rPr><w:rFonts w:ascii="Symbol" w:hAnsi="Symbol"/></w:rPr><w:t>ďˇ</w:t></w:r>

或者如果我将编码设置为UTF-8:

<w:r w:rsidRPr="008E65F6"><w:rPr><w:rFonts w:ascii="Symbol" w:hAnsi="Symbol"/></w:rPr><w:t></w:t></w:r>

当我查看为Hexa时,似乎希腊字符编码为EF 81 A1表示alpha,EF 81 A2表示beta,依此类推。

我还尝试了val.getBytes(Charset.forName("utf8")),其中val是<w:t>标记的值。结果是例如[-17, -127, -95]。负值对我来说非常令人惊讶。

所以我的问题是,将这些符号转换为常规UTF-8字符的安全可靠方法是什么?

1 个答案:

答案 0 :(得分:2)

与此同时,我找到了解决方案,因此我将其添加为答案供将来参考。

我使用字形查看器软件检查了Symbol字体,我意识到它使用Unicode的专用区域作为其字符。 Times New Roman等其他字体存储正常Unicode范围内的相关字符(例如希腊字母)。

因此,解决方案是使用标准Unicode字形映射Symbol字形。我已经手工创建了一个转换表,用于希腊字母(大写/小写),符号字体中可用的标点,数字和数学符号。注意,甚至variuos范围内的字符的顺序也彼此不同,例如,希腊字母表在符号和Unicode中的顺序不同。所以我必须逐个检查字符代码。

当我有转换表时,我将其存储在txt文件中。当我的应用程序在Word文件中找到使用符号字体(示例中为<w:rFonts>标记)格式化的段(运行)时,它会调用转换方法。在此方法中,我将txt文件解析为HashMap,并将符号从Symbol代码逐个更改为Unicode:

public String convert(String symbolString)  {
    StringBuilder sb = new StringBuilder();

    for(int k=0; k<symbolString.length(); k++){
        int origCode = Character.codePointAt(symbolString, k);
        Integer replaceCode = conversionTable.get(origCode);
        if(replaceCode != null) {
            sb.append(Character.toChars(replaceCode));
        } else {
            sb.append("?");
        }
    }

    return sb.toString();
}

conversionTableHashMap对象,其中包含替换代码为十六进制值。