2016-08-30 2 views
2

В рамках нашего процесса автоматической сборки мы хотели бы исправить номер сборки в серии PDF-файлов (наши справочники). Чистый способ заключается в автоматизации некоторых макросов в LibreOffice для обновления поля и вывода PDF снова.Как исправить документ PDF

Однако я хотел бы знать, существует ли более прямое (но, возможно, грязное) решение, состоящее в запуске некоторого бинарного поиска и замены замещающего в файле PDF. Однако содержимое не отображается в открытом тексте в PDF. Есть ли трюк, который поможет?

+0

Как номер сборки должен быть извлекаемый? Должен ли он быть видимым в обычном средстве просмотра PDF? Или он должен содержаться в скрытом месте? – mkl

+0

Он должен быть видимым в тексте, например, в нижнем колонтитуле или приложении –

+0

В этом случае, скорее всего, ответ Бруно показывает, как будет выглядеть быстрое и грязное решение. – mkl

ответ

2

Число не доступно в ясном тексте, потому что оно является частью сжатого потока контента.

Возьмите «Привет, мир!». пример. Поток контента, который представляет, что может текст выглядит следующим образом:

2 0 obj 
<</Length 65/Filter/FlateDecode>>stream 
xœ+är 
á26S°00SIá2PÐ5´ 1ôÝBÒ¸4<RsròÂó‹rR5C²€[email protected]*\C¸¹ Çq° 
endstream 
endobj 

При распаковке бинарной части, вы найдете это:

q 
BT 
36 806 Td 
0 -18 Td 
/F1 12 Tf 
(Hello World!) Tj 
0 0 Td 
ET 
Q 

Однако следующий синтаксис также будет правильным:

BT 
/F1 12 Tf 
88.66 806 Td 
(ld!) Tj 
-22 0 Td 
(Wor) Tj 
-15.33 0 Td 
(llo) Tj 
-15.33 0 Td 
(He) Tj 
ET 

Этот синтаксис гораздо труднее читать, но если вы выполните всю математику и переработаете различные фрагменты текста на основе изменений в текстовой матрице, вы обнаружите, что вывод идентичен выходу синтаксиса, который у нас был раньше.

Если ваши PDF-файлы создаются прямолинейным способом, что означает, что строки могут быть легко распознаны в распакованном синтаксисе, вы можете получить поток контента на странице, распаковать его, изменить, сжать и поместить это снова в PDF.

Это также предполагает, что строка, которую вы ищете, присутствует в потоке содержимого страницы, а не во внешнем потоке содержимого; то есть: в Форма XObject.

Если все эти предположения будут выполнены, вы могли бы использовать IText так:

PdfReader reader = new PdfReader(src); 
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
int total = reader.getNumberOfPages() + 1; 
for (int i = 1; i < total; i++) { 
    byte[] content = reader.getPageContent(i); 
    byte[] alteredBytes = doSomethingWith(content); 
    reader.setPageContent(i, alteredBytes); 
} 
stamper.close(); 
reader.close(); 

Вы должны реализовать метод doSomethingWith() так, что он выполняет бинарный поиск & заменить вам нужно.

Важно: вы просили быстро & грязно, и это очень быстрый & грязный путь. Если я увижу, что один из моих сотрудников отправил этот код, я бы уволил его или ее на месте, если он или она не могут дать мне достойные аргументы в пользу использования этого кода. Этот код не удастся для многих PDF-файлов, но это может быть именно то, что вам нужно в вашем конкретном прецеденте.

Вы также можете прочитать: iText or iTextSharp rudimentary text edit

+0

Спасибо за такой исчерпывающий ответ. Очень проницательный! Мы сейчас сдадимся и отправимся в чистое решение (автоматизировать libreoffice) позже. –