【发布时间】:2021-03-31 13:53:43
【问题描述】:
更新:2021-01-15 - 添加赏金
我正在尝试更改编校注释以更改在您应用编校时刻录到 PDF 中的基础文本。在 Acrobat 中,您可以设置“编校代码”的集合,这些代码可用于确定您将某些内容标记为已编校的原因。我的目标是用系统定义的值覆盖用户选择的内容。代码将在应用编辑之前运行。
在我的尝试中,我发现将光标悬停在编辑框上时 Acrobat 产品中可用的“预览”是 Acrobat 独有的,大多数其他查看器不会显示预览。似乎预览与应用的实际编辑分开维护。我不需要更改预览中显示的文本,只需更改应用密文后显示的内容即可。
我已经增加了 150 声望的赏金,因为我认为我自己无法找到解决方案。我最初的问题指定了 iText7,因为这是在我自己的尝试中让我最接近的库。虽然我更喜欢使用 iText7,但我也会考虑使用我可以合理访问的其他库的解决方案(如果需要,我确实有少量预算可以用来购买另一个库)。
我保留了我最初的问题以及我个人在下面尝试过的后续问题。感谢您提供的任何帮助。
如果您需要一个样本进行测试,this DropBox 文件夹中有一个名为 01 - Original.pdf 的文件,您可以将其用作源文档。期望的结果是能够更改在将“原始覆盖文本”应用编辑时显示的文本到任何其他值,例如“新文本”。
原问题:
我正在尝试使用 iText7 更改 PDF 中每个编校注释中包含的文本。 PdfRedactAnnotation 对象有一个名为 SetOverlayText() 的方法,看起来它应该做我想做的事。所以,我写了一个方法,打开一个PDF,循环浏览页面,然后循环浏览每一页上的注释,并检查一个注释是否是PdfRedactAnnotation。如果是,它会调用SetOverlayText()。
在调试和查看注解属性时,我可以看到OverlayText 确实发生了变化。但是,当我打开文件并通过将光标悬停在编辑标记上来检查覆盖文本时,原始覆盖文本仍然存在。
此外,如果我应用了编辑,原始的覆盖文本就会被烧入页面。
但是,当我右键单击注释时(在应用编辑之前),覆盖文本会立即更新为新文本:
此时,当我应用修订时,将新文本刻录到 PDF 中。
有什么方法可以让我以编程方式触发密文注释更新,而无需打开并右键单击每个注释?我在下面包含了我的代码。感谢您提供任何建议。
PdfDocument pdfDoc = new PdfDocument(new PdfReader(@"C:\temp\Test - Original.pdf"), new PdfWriter(@"C:\temp\Test - Output.pdf"));
Document doc = new Document(pdfDoc);
int pageCount = pdfDoc.GetNumberOfPages();
for (int i = 1; i <= pageCount; i++)
{
var annotations = pdfDoc.GetPage(i).GetAnnotations();
foreach(var annotation in annotations)
{
if (annotation is PdfRedactAnnotation)
{
PdfRedactAnnotation redact = (PdfRedactAnnotation)annotation;
redact.SetOverlayText(new PdfString("New Text"));
}
}
}
doc.Close();
更新:截至 2021 年 1 月 7 日的调查结果
正如@mkl 的回答所指出的,PDF 编校注释规范阐明了底层编校注释 DOM 条目。 OverlayText 只是其中的一部分。如果您使用 OverlayText,则必须定义一个 DA 元素(DA 是一个为 OverlayText 提供格式信息的字符串)。最后,如果定义了 RO,它将取代几乎所有其他独立的显示条目。
我的测试文档是使用 Acrobat DC Pro 制作的,通过在 Acrobat 中手动添加编辑。这样做会产生一个带有所有上述条目的编辑注释。我的测试文档的副本可以在this DropBox 文件夹中找到。
(旁注:在我最初的问题中,我提到将鼠标悬停在编校的红色矩形上以预览应用编校的外观......在多个浏览器和其他 PDF 查看器(如 Foxit Reader)中进行测试后,看起来只有 Acrobat 产品才支持通过将鼠标悬停在红色轮廓上来“预览”编辑内容的功能。所有其他测试的查看器将仅显示红色边框,当您将鼠标悬停时不会发生任何事情将光标悬停在上面。上面显示的黑色矩形只有在应用了编辑后才能在其他程序中查看。
其他测试表明,悬停预览与编辑详细信息本身是分开维护的,Acrobat 会尝试使悬停详细信息与基础注释保持同步。测试时最好忽略悬停预览,并在应用编辑后参考结果。)
@mkl 建议删除 RO 条目以尝试让 OverlayText 优先是一个好主意,但不幸的是它没有奏效。与我的原始结果没有显着差异。
在 iText7 的 PdfRedactAnnotation 中一探究竟,我发现以下方法都会导致对 Redact 对象的 RO 条目的引用:
PdfRedactAnnotation redact = (PdfRedactAnnotation)annotation;
redact.GetRolloverAppearanceObject();
redact.GetRedactionRolloverAppearance();
redact.GetPdfObject().Get(PdfName.RO);
redact.GetAppearanceDictionary().Get(PdfName.R);
(我通过检查相等比较器确认它们实际上是完全相同的引用。作为引用类型,当使用== 进行测试时,它们都返回true。
在进一步的测试中,我得出的结论是 RO 属性必须在内部存储相同的 OverlayText 的副本。如果您有两个具有不同原始值的密文,您可以将 RO 元素从一个密文“复制”到另一个:
PdfObject ro = firstRedact.GetPdfObject().Get(PdfName.RO);
secondRedact.GetPdfObject().Put(PdfName.RO, ro);
如果您这样做并应用密文,第一个密文中的“覆盖文本”将替换第二个密文中的“覆盖文本”。其他 RO 元素值也会被复制(例如 BBox,它定义了黑色矩形的尺寸)……但至少可以调整这些元素。
问题仍然存在,RO 的 iText7 PdfObject 有 7 个子元素,它们或其后代元素似乎都没有暴露我要更改的文本。
我的最后一个测试是我是否可以将 RO 元素从一个 PDF 复制到另一个(以便我可以使用第二个源 PDF 并带有已配置所需 RO“覆盖文本”的注释),但它看起来像间接对象不'不喜欢被 .Put() 放入其他文档中。
所以现在,我只能尝试找到一种方法来访问/更改存储在 RO 中的文本,或者从另一个文档中克隆预配置的 RO。
【问题讨论】: