Обновление: 15.01.2021 - добавлена награда
Я пытаюсь изменить аннотацию редактирования, чтобы изменить базовый текст, который записывается в PDF-файл, когда вы применяете исправления. В Acrobat вы можете настроить набор кодов редактирования, которые можно использовать для определения того, почему вы помечаете что-то как отредактированное. Моя цель - перезаписать то, что было выбрано пользователем, с системным значением. Код будет запущен до того, как будут применены исправления.
В своих попытках я обнаружил, что предварительный просмотр, доступный в продуктах Acrobat при наведении курсора на поле редактирования, является уникальным для Acrobat, и большинство других средств просмотра не будут отображать предварительный просмотр. Также кажется, что предварительный просмотр поддерживается отдельно от применяемого фактического редактирования. Мне не нужно изменять текст, отображаемый в предварительном просмотре, только то, что отображается после применения исправлений.
Я добавил награду в размере 150 репутации, так как не думаю, что смогу найти решение самостоятельно. В моем исходном вопросе был указан iText7, так как это была библиотека, которая ближе всего ко мне в моих собственных попытках. Хотя я бы предпочел использовать iText7, я также рассмотрю решения с использованием других библиотек, к которым у меня есть разумный доступ (у меня есть небольшой бюджет, который я мог бы использовать для покупки другой библиотеки, если мне нужно).
Я сохранил свой первоначальный вопрос и последующие, которые я лично пробовал, ниже. Я ценю любую предложенную помощь.
Если вам нужен образец для тестирования, в этой папке DropBox есть файл с именем 01 - Original.pdf
, который можно использовать в качестве исходного документа. Желаемый результат - иметь возможность изменять текст, который появляется при применении исправлений из исходного оверлейного текста к любому другому значению, например новому тексту.
Исходный вопрос:
Я пытаюсь изменить текст, содержащийся в каждой аннотации редактирования в PDF-файле, используя iText7
. У объекта PdfRedactAnnotation
есть метод SetOverlayText()
, который, похоже, должен делать то, что я хочу. Итак, я написал метод, который открывает PDF-файл, просматривает страницы, затем просматривает аннотации на каждой странице и проверяет, является ли аннотация PdfRedactAnnotation
. Если это так, он вызывает SetOverlayText()
.
При отладке и просмотре свойств аннотации я вижу, что OverlayText
определенно изменился. Однако когда я открываю файл и проверяю наложенный текст, наведя курсор мыши на отметку редактирования, исходный текст наложения все еще присутствует.
Кроме того, если я применю исправления, исходный текст наложения будет записан на странице.
Однако, когда я щелкаю аннотацию правой кнопкой мыши (перед применением исправлений), текст наложения немедленно обновляется до нового текста:
На этом этапе, когда я применяю исправления, в PDF-файл записывается новый текст.
Есть ли способ, которым я могу запустить обновление аннотации Redaction программно, без необходимости открывать и щелкать правой кнопкой мыши каждое из них? Я включил свой код ниже. Спасибо за любой совет, который может дать кто-нибудь.
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();
Обновление: данные по состоянию на 07.01.2021
Как указывает ответ @mkl, спецификация PDF Redact Annotation Specification разъясняет основные записи DOM аннотации редактирования. OverlayText - это лишь часть уравнения. Если вы используете OverlayText, тогда должен быть определен элемент DA (DA - это строка, которая предоставляет информацию о форматировании для OverlayText). Наконец, если задан RO, он заменяет почти все другие независимые записи отображения.
Мой тестовый документ был создан с использованием Acrobat DC Pro путем ручного редактирования в Acrobat. В результате появится аннотация Redact со всеми указанными выше записями. Копии моих тестовых документов можно найти в этой папке DropBox.
(Боковое примечание: в моем исходном вопросе я упоминаю наведение курсора на красный прямоугольник редактирования, чтобы предварительно просмотреть, как будет выглядеть примененное редактирование ... После тестирования в нескольких браузерах и других средствах просмотра PDF, таких как Foxit Reader, это выглядит как функция предварительного просмотра того, как будет выглядеть редакция при наведении указателя мыши на красный контур, поддерживается только в продуктах Acrobat. Все другие протестированные средства просмотра будут отображать только красную рамку, при наведении курсора на нее ничего не происходит. . Черные прямоугольники, показанные выше, можно просмотреть в других программах только после внесения исправлений.
Дополнительное тестирование показало, что предварительный просмотр при наведении курсора поддерживается отдельно от самих деталей редактирования, при этом Acrobat пытается синхронизировать детали при наведении курсора с основной аннотацией. Лучше игнорировать предварительный просмотр при наведении курсора при тестировании и обращаться к результатам после внесения исправлений.)
Рекомендация @mkl удалить запись RO, чтобы попытаться позволить OverlayText иметь приоритет, была хорошей идеей, но, к сожалению, не сработала. Никаких заметных отличий от моих первоначальных результатов не было.
Покопавшись в PdfRedactAnnotation iText7, я обнаружил, что все следующие методы приводят к ссылке на запись RO объекта Redact:
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, который определяет размеры черного прямоугольника) ... но, по крайней мере, эти элементы можно настраивать.
Проблема остается в том, что у iText7 PdfObject RO есть 7 субэлементов, и ни один из них или их дочерние элементы, похоже, не раскрывают текст, который я пытаюсь изменить.
Мой последний тест заключался в том, могу ли я скопировать элементы RO из одного PDF-файла в другой (чтобы я мог использовать второй исходный PDF-файл с аннотацией с уже настроенным желаемым наложенным текстом RO), но похоже, что косвенным объектам не нравится быть. Поместите () в другие документы.
Итак, теперь мне остается попытаться либо найти способ получить доступ / изменить текст, хранящийся в RO, либо клонировать предварительно сконфигурированный RO из другого документа.