我正在开发一个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字符的安全可靠方法是什么?
答案 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();
}
conversionTable
是HashMap
对象,其中包含替换代码为十六进制值。