В общем
Прежде всего, код, который вы используете, работает только при благоприятных обстоятельствах, то есть только для PDF-файлов, созданных особым образом. В то время как PDF-файлы в прежние годы довольно часто создавались таким образом, в настоящее время их в основном уже нет. Это привело к удалению примера PDFBox, из которого этот код был получен из базы исходного кода PDFBox 2.0.
Соответствующая запись в руководстве по миграции объясняет:
Почему был удален пример ReplaceText?
Пример ReplaceText был удален, поскольку он дал неверную иллюзию того, что текст можно легко заменить. Слова часто разделяются, как видно из этого фрагмента потока контента:
[ (Do) -29 (c) -1 (umen) 30 (tation) ] TJ
Другие проблемы появятся с подмножествами шрифтов: например, если используются только глифы для a, b и c, они будут закодированы как шестнадцатеричные 0, 1 и 2, поэтому вы не найдете «abc». Кроме того, вы не можете заменить «c» на «d», поскольку он не является частью подмножества.
У вас также могут быть проблемы с лигатурами, например, «Ff», «fl», «fi», «ffi», «ffl», которые могут быть представлены одним кодом во многих шрифтах. Чтобы понять это самостоятельно, просмотрите любой файл с помощью PDFDebugger и просмотрите запись «Содержание» на странице.
См. Также PDFBox 2.0 RC3 - Найти и заменить текст
( Миграция в PDFBox 2.0.0 )
Проблема, связанная с разделением слов для кернинга, в основном была обойдена в вашем коде путем конкатенации блоков строковых параметров для оператора TJ . Остающиеся проблемы остаются, тем не менее.
В случае ваших примеров документов
В случае вашего примера документа проблема заключается в том, что заменяющие "цифры показывают друг на друга":
==>
![screen shot with replacement](https://i.stack.imgur.com/T99wX.png)
Причина аналогична проблеме «наборов шрифтов», упомянутой в руководстве по миграции. Тем не менее, рассматриваемая программа шрифтов TTF не встроена, так что это не настоящая проблема "подмножества шрифтов" Но информация, относящаяся к шрифту, хранящаяся в PDF, является правильной только для глифов, фактически используемых в исходном PDF, то есть '@', 'e', 's' и 't', но не для глифов замены, то есть цифр «1», хотя «6».
Специфичной для глифа информацией, имеющей отношение к данному случаю, является ширина глифа: только для первоначально используемых глифов она задана правильно, для всех других глифов данная ширина равна 0
! Следствие: после рисования одного из ваших замещающих глифов позиция для рисования следующего глифа не смещается надлежащим образом, но остается той же самой (как уместно для глифов шириной 0), поэтому следующий нарисованный глиф начинается в той же позиции, эффективно рисуя все ваши заменяющие глифы друг на друга.
(Более конкретно, массив widths для этого шрифта выглядит следующим образом:
[ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 921 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 444 0 0 0 0 0 0 0 0 0 0 0 0 0 389 278]
с кодированием '@', 'e', 's' и 't' с использованием WinAnsiEncoding и шрифта, состоящего из диапазона от '@' до 't'.)
В этом особом случае вы, вероятно, сможете решить проблему, невидимо (например, белым по белому) напечатав в шаблоне Word строку со всеми символами шрифта, которые вы, возможно, захотите использовать в качестве замены для заполнителя.
В целом, однако, кодировка не должна быть чем-то вроде ASCII'а, подобной WinAnsiEncoding , но вместо этого может быть совершенно другой, вероятно, даже подстроенной по этому случаю, например. # 1 для первого глифа, используемого на странице, # 2 для второго, другого глифа на этой странице и т. Д. Таким образом, в общем, обходной путь не так легко найти.