2013-08-16 3 views
0

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

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

Я понял, что при создании HTML я мог бы просто поставить токен вместо текущей даты и времени (например, '__CURRENT_DATE_TIME__') и что я мог бы выполнять текстовый поиск и заменять в кэшированном PDF-файле. К сожалению, PDF, похоже, использует кодировку, которая делает это немного сложнее. Вот пример закодированного текста:

\x947+\xbf\xad|H\xf9c\xe5\xcf\x95\xa7\x941\xd5\x1d\xaa\x07US\xaa\xb7\xd4\t\xea\nu\xbbz\xad\xfa&\xf5w\xd5\x87\xd5\xbfS\xc74\xb9\xe8Om\xc8}\xfe\xbc4w\x07\xb9T\xe1\xe5\xf6\x90\x187\x85r\xff\x90\x1b\xe3\xff\x8d\xfb:y\xe2\xbcL\xb8\x1b9\xe8\x85\x8d\xdc\x14\xff\x0c\xf7\xcd\xab\xf6\xf0o\xf0\xdf\xe3\xae\x05P4\xb3\xe9E\x98\xc5^\x82\x1f\xc0K\xca_+\x92\x95o\xc1\x8b\\:\xbc\x87\xf9\xf0\xeb\xbc\x9f\xfb!w/g%\x15\xfcB\xc5\r\x8a\x970\xebL \x9f\x0fq\'85\xb7\x0f1\xfe\x84\xd6\xd8\x08\x17\x934\xf8\x8bb\x1d\xbc\x8f\xfa?\xa2\xdc\x8d:]\xcc\x1d\'Op/p\x17\xa1\'\x1f\x83\x87\xb9\xc3p/\xec\x85\x00\xa9D\xeez\xe1I\xf8\x18\xbeF\x0e\xf1"9\x88~\xb7\x03\x8e\xc2\xbbp\xf2\x1c\xb7\n\xef\xd9F\xae^e\xe5\xb6\xaaj\xd0B\x87\xc8\xaa\xd8\x8b\\~\xecO\x18\xf5\xbf\'7\xc0\xeb\xfc\xc7\xe8\xfb\xeb\xc8\n\xe2\x85G\xe1M\xb4\xfao\x88\x8f\xd8\x153\n\x1b\xbc\x8c\x99/\x0b\xeeG\xaf\xfd#Lb\x0c\xfe\\\x91\x8d\x11\xf4\x11\x1c\xe2}\xb0^q\x12m\xee=\xfb\xb3\x99f\xe5\x18\x7f\x1d9\xc35\xa09SY\xe6^I\xb31\xe6\xe0{0W\xd1<\x9a\x08\xfb\xd0\x130\x8b\xb0\x88\xfe\x13\xfc\x828Q\x8b\xbfV\xbd\x06\xf7\xc1\xed\xf04\x9f\x0c9\xfc#\xdcN.\xc6\xffT!\xc2\xbf\xc0I~9\xeez5\xe6\xa7\x0c\xe2CJC0\x80r\x88\xb1?\xcc<\x8c\x14.\x87*\xa8"\x9b\xc8zh\xc6\x99\xa5\x90\x15\x1bB\xce\x1f\xc5\\$\xc56\xc4\xeeUv*=\xf0K\xb2\x9c$\xc3\xb3\x98\xbd\xac\xa8\xc5\xbb\x94\xda\x99\xd3\x88y\x00\xe3\xf0uXJn\x86\xc9\x99^\x98\xc6s\xc5JrH)z\xd3i\xe5V\xe5\x1e\xe5\xe3\xca\x03\xca\x1f*\x7f\xa1Z\x00W`\xd4\xde\x8fV|\x03>\xc4SC$=\xa8\x8bw\xe0o\xe8\xeb\x8d\x18=\x85\x18?\r\xc8\xc5R<\xc3\x06\xb9N\xfe\x19h"\xe90\x8290\x0f\xf3v#\xea`=Z2\x8cT\xae\x85[0\x9e\x1e\xc13\xe4\x97\xf0\x01\x11\xc8\x06\xf8!\x1c\xc3\xc8I\xc58\xef\xc1\xfd5H\xa7\x15.F\xab\x87\xe1Q\xcc\x8e\xd7\x91I\x1c\xe9\x85,(@=}L\x12I\x157\x86\xfb\xd1<{\x17\xe6\xd9i\xe4\xe9w\xf0\x07\xcc\x1c1\xc6W!YH\x9a\xd1z=\xf07\x1a\xcb\xb8C\x05\xb4\x93\xfd\xb08v\x10=a\x054\xf3/\xc1\x7fB6\x9e\xae\x8d\x18\xa3\x0f\xe3\xban\xf4\x8dD\xc8\x84j\xe5\x9b\x84\x83\xc2\x99\x15\xb1*n\x80\x7f\x86\xa4\xe0i\x98\x88^\xb5\x16O\xf6Ed\x14\xb90\xa2\x1cg!\x99\xac\x84\xf2\x99%P\x8dg\xecNhW>"IR}\xdd\xa2\xda\x855\xd5U\x95\xe5\xbe\xb2\xd2\x05%\xde\xe2\xa2BOA~^ 

Во-первых, это разумно ожидать, что '__CURRENT_DATE_TIME__' (правильно закодирован) можно найти где-то там? Если да, то как я буду кодировать эту строку, чтобы я мог просто выполнить простой поиск и заменить?

+0

зависит от способа создания PDF-файла. например если PDF-файл хранит PICTURE-файлы текста, то __current_date_time__ чрезвычайно маловероятно, чтобы EVER появлялся в PDF-файле, и если это так, почти гарантированно не будет, где вы хотите. материал '\ x', который вы видите, это просто кодированный текст UTF-8, например. \ x94 является эквивалентом 0x94 в качестве шестнадцатеричного кода. –

+0

Спасибо Marc B. Они используют princexml для преобразования, если это помогает. Тем не менее, можете ли вы рассказать мне, какая серия команд приведет меня от «__CURRENT_DATE_TIME__» к \ x-экранированной версии текста UTF-8? – Josh

+1

теоретически, если pdf находится в utf-8, то current_date_time не нужно кодировать, потому что он не использует никаких «высоких» символов. –

ответ

1

я мог просто поставить маркер на место текущей даты и времени (например, «CURRENT_DATE_TIME»), и что я мог бы сделать текстовый поиск и замена в кэшированных PDF

Просто чтобы дать вам представление о том, почему это, скорее всего, не будет работать:

  1. в PDF-файлов чаще всего потоки содержимого страницы (и другие потоки, тоже), хранящихся в спущенном сжатом формате. Таким образом, обычный grep или любой сопоставимый текстовый поиск, применяемый к файлу, не имеет возможности найти ваш placeholder.

    Даже если настроить генерирующий PDF программного обеспечения не сжимают потоки контента, вы, скорее всего, находятся в беде, потому что:

  2. Кодирование строк в содержании страницы не обязательно является стандартом кодирования ASCII'ish. Особенно в случае частично встроенных шрифтов вы довольно часто видите пользовательскую кодировку, в которой первый глиф из этого шрифта, используемый в документе, закодирован как 0, второй кодируется как 1, ... Такая пользовательская кодировка обрывает ваш текст подход замены.

    Даже если вы находитесь в ситуации, когда используются только стандартные кодировки, например.WinAnsiEncoding, вы все еще, вероятно, находитесь в беде, потому что:

  3. Операции с текстовым рисунком в содержимом страницы не обязательно должны быть в порядке чтения. Например. ваш владелец места образца может быть нарисован в трех пакетах, сначала TIME, затем DATE, затем CURRENT. Это не позволяет вам распознавать местозаполнитель.

    Даже если это не происходит в вашем случае, вы все равно можете быть в беде, потому что:

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

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

Возможно, вы все еще можете удивиться: если ваше редактирование изменяет длину содержимого, вы также должны обновлять информацию о перекрестных ссылках в PDF, поскольку многие объекты в PDF ссылаются на их смещение от начало документа.

+0

Очень полезно и информативно. Благодаря! – Josh

1

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

Таким образом, вы можете использовать имеющийся у вас PDF-файл и добавлять необходимую информацию в любой момент. Я знаю, что PDFtk - это бесплатный инструмент, который вы можете использовать для этого, и, хотя это быстро и бесплатно, я не сторонник этого, потому что это не сохранение контента (оно меняет некоторые метаданные), но должно быть много другие инструменты, которые делают это.

Надеюсь, что этот подход сэкономит вам время.

+0

Хотел бы я отметить это как ответ. Я выбрал mkl, потому что он отвечает на реальный вопрос. Это отличный альтернативный подход. Благодарю. – Josh

Смежные вопросы