当前位置: 首页 > 知识库问答 >
问题:

Java PDFBox-使用特殊字符(变音符)读取和修改pdf

云曦之
2023-03-14

我正在尝试使用这种方法修改一个pdf(第一个代码块--使用PDFStreamParser并通过PDFOperator,然后在需要时更新COSString):

http://www.coderanch.com/t/556009/open-source/pdfbox-replace-string-double-pdf

我有一些UTF-8字符(变音符)的问题:当我打印要更新的文本时,显示“societ??ii na?ionale”(其中‘?’是像0002或0004这样的代码)。

有趣的是:

  1. 当我编写更新的pdf文件时,字符会正确显示(即使我无法检测并替换它们)
  2. 如果我尝试使用PDFTextStripper的getText(...)剥离文本,则文本被完美地提取出来。
  3. 我尝试了两个pdfbox版本:1.5.0(其行为如上所述)和1.8.1(其中最终的、编写的pdf文件不能正确显示特殊字符,并且“空”字符串出现在文档中)

我可以为用于更新pdf的类做什么(配置)(或者至少尝试...)以便正确显示所有UTF-8字符?

编辑2:

我通过PDFTextStripper中的pdfbox源代码及其超类进行了搜索,我发现了文本是如何提取的:

在processStream方法的开头,我们有

graphicsState = new PDGraphicsState(aPage.findCropBox());
final PDFont font = graphicsState.getTextState().getFont();
String c = font.encode( string, i, codeLength );

共有1个答案

聂煜
2023-03-14

不能只是替换字符串中的文本。我不是轻率地说这些。多年前我曾在Acrobat上工作,在最初版本中做过文本搜索工具,因此我对文本编码问题有相当深入的理解。主要的问题是PDF中的每一个字符串都是以某种方式编码的。这是因为PDF是在Unicode普遍可用之前制作的,并且在PostScript中有历史。PosctScript喜欢使用非常灵活的字体编码方法,并鼓励重新编码。

所以让我们退一步,了解一下全貌。

PDF中的字符串中的一个字符,如果要用文本运算符显示,默认情况下,将被编码为一系列8位字符。为了确定为每个字节绘制什么字形,将该字节推入该字体的编码向量。编码向量将字节映射到字形名称,然后在字体中查找字形名称并绘制在页面上。请注意,这个描述是半真半假的(稍后更多)。

一些应用程序试图在生成的PDF中更加节省,因此它们查看所使用的字形,并决定嵌入字体的子集。如果它们只使用大小写罗马字母和数字,它们就会重建没有这些元素的字体,并且还可以选择重新索引它们,并提供一个编码向量,以便字节0x00转到字形'a'和0x01转到字形'b',以此类推。

现在回到一半的真相。有一类字体是按字符ID(或CID)编码的,TrueType和OpenType字体就属于这一类。在本例中,您可以访问Unicode,但也有一个编码步骤,将字符串(现在为UTF16BE)映射到CID,用于从字体中获取字形。Adobe使用PostScript函数来进行映射,这并不是特别好的原因。同样,这是一个3/4的事实,因为对于较旧的中文、日文和韩文字体的管理,也有不同的编码。

因此,在您轻松地将一个字符放入PDF字体的字符串中之前,您必须问几个问题:

  1. 字体中是我的字形吗?
  2. 我的字形是否在编码中?
  3. 我的字形的编码是什么?

而其中的任何一个都可能与你所期望的不同。例如,如果您想输入“(一个指示),您必须查看字体是否有它的字形(可能没有,因为字体是一个子集)。那么字体可能有一个有趣的编码,可能不包括字形。最后,用于“”的实际字节值可能不是标准的。

所以当我看到有人试图简单地替换PDF内容中的一大块文本时,我看到的只是一个痛苦的世界。对于大多数正常的PDF,90%的时间都是这样,但是对于任何异国情调的东西--祝你好运。PDF文本呈现的怪癖已经够痛苦的了,有时我们更容易把它看成是一种只写格式

 类似资料:
  • 问题内容: 我正在为法国客户做一些工作,因此需要处理带重音符号的字符。但是我遇到了很多困难,希望解决方案很简单,并且有人可以向我指出。 字符串: 转换为: 请注意,带重音符号的字符缺失- 在 ê* 后面紧跟着 t ,在 é 后面紧跟着 m 。 * 我尝试使用StringEscapeUtils来成功转义某些字符,例如 ă 。我还构建了自己的转义功能,该功能产生相同的结果( ă 可以工作, ê 不会)

  • 问题内容: 我正在阅读文件,但我不知道如何阅读口音和特殊字符,这是我阅读的代码,我必须添加其他编纂,但我不知道该怎么做 谢谢 问题答案: 请尝试以下操作:

  • 有一个应用程序,它使用生成XML文件,它基本上从textbox中获取输入(也包括特殊字符)保存为XML,并通过从XML反编组来显示。 用户正在复制控制台输出(可能包含特殊字符),粘贴在文本框中,并将其保存到XML中。 解编组时,收到解编组异常: 解组XML时发现一个无效的XML字符。我在这个论坛上搜索了一些帮助,发现很少链接,但两个都没有解决方案或变通方法。有人能指引我吗。 我尝试过其他编码类型,

  • 关于字符集和替代字形 除键盘上可看到的字符之外,字体中还包括许多字符。根据字体的不同,这些字符可能包括连字、分数字、花饰字、装饰字、序数字、标题和文体替代字、上标和下标字符、变高数字和全高数字。字形是特殊形式的字符。例如,在某些字体中,大写字母 A 有几种形式可用,如花饰字或小型大写字母。 插入替代字形的方式有两种: 可以使用 “字形 ”面板来查看和插入任何字体中的字形。 可以使用 “OpenTy

  • 一些字符在 XML 中有特殊的含义,只能够通过其实体名称输入 字符 写法 缩写涵义 < &lt; less than > &gt; greater than & &amp; ampersand " &quot; quote ' &apos; apostrophe 空格 &nbsp; none-break space 通常需要使用实体输入的字符包括<、&、空格   XML 会将任意数量的空格解析为一

  • 问题内容: 我想在Winforms中编写一个小型应用程序,在其中我可以写一些单词,然后使用ADO.net将它们写到SQL数据库中。 当我想用一个占位符写一个字符串时遇到麻烦: 我的数据库中记录的是: 我该如何克服通过传输到我的数据库的C#更改字符串? 这是我的代码的一部分: 问题答案: 您使用参数化的sql。