请看看NameObject的例子,并试试看。您会看到iText会自动转义名称中的特殊字符。
iText的遵循ISO-32000-1规范,统计(7.3.5,名称对象):
与PDF 1.2的名称对象开始时的原子符号唯一地 通过任何字符的序列所定义(8位值),除了空 (字符代码0)。唯一定义意味着由相同字符序列组成的任何两个名称对象 表示相同的对象。原子是指名称没有内部结构;虽然它是由一系列字符定义的 ,但这些字符不是 所考虑的名称的元素。
不是名称的一部分,但表示接下来是在PDF文件中表示名称字符 序列,并应 遵循这些规则的前缀:
一)数字符号(23H)( #)的名称应使用其 2位十六进制代码(23)编写,前面加上数字符号。 b)作为常规字符的名称中的任何字符(除 NUMBER SIGN以外)应写为自身或使用其2位 十六进制代码,前面带有数字符号。
c)任何非常规字符的字符都应该使用其2位十六进制代码写入 ,前面加上NUMBER SIGN。
注1:PDF文件 中没有唯一的名称编码,因为常规字符可能以两种方式编码。
用作名称的一部分空白应当始终使用 2位十六进制表示法被编码和没有空白可 固相线和所述编码的名称之间介入。
是范围感叹号(21H) (!),以波浪号(把7Eh)(〜)之外的普通字符应该使用十六进制 符号来书写。
令牌SOLIDUS(斜线后跟无正则字符) 引入由空字符 字符定义的唯一有效名称。
注2表4中显示的示例和包含#的示例在PDF 1.0或1.1中无效 字面名称。
我不复制/粘贴表4,但我没有看到任何使用由两个字节组成的字符的示例。你可以分享一个PDF文件,其中包含一个双字节字符的行为符合你的意愿的名字吗? PDF规范明确指出,名称上下文中的字符是8位值。你似乎是在谈论16位值...
附加说明:在当前实现的iText的,我们只看8位:
c = (char)(chars[k] & 0xff);
我们故意扔掉所有的更高当超过8位的字符被传递时,这些位将被传送。
其实,我想我已经回答了你的问题。起初,我以为你是要求添加这个字符:http://www.fileformat.info/info/unicode/char/c3a4/index.htm
事实证明,你只需要"\u00e4"
(ä)。我制作了一个小代码示例,演示如何将自定义条目添加到包含此字符的DID中:ChangeInfoDictionary。
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
Map<String, String> info = reader.getInfo();
info.put("Special Character: \u00e4", "\u00e4");
stamper.setMoreInfo(info);
stamper.close();
reader.close();
}
当然,当你打开一个PDF浏览器的PDF,你不一定看到“特殊字符:a”作为核心价值,但这是PDF阅读器中的一个问题。当您打开一个文本编辑器的PDF,你清楚地看到:
/Special#20Character:#20#e4(ä)
这意味着,iText的是否正确转义特殊字符。
但是,正如您在评论中指出的那样,字符不会显示在Adobe Reader中。根据我使用Acrobat创建的PDF,我发现了一个变通方法,通过使用下面的代码:
StringBuffer buf = new StringBuffer();
buf.append((char) 0xc3);
buf.append((char) 0xa4);
info.put(buf.toString(), "\u00e4");
现在的字符显示正确。换句话说:这是一个编码的问题......
我已经更新了我的答案。在额外的片段中,您会找到解决方法。 –