добавление текста в PDF с помощью PyMuPDF

Я пытаюсь добавить текст в PDF-файл, открыв PDF-файл, добавив текстовое поле и сохранив его. Когда я запускаю код, ничего не происходит. на рабочем столе он показывает, что файл был обновлен, но на нем нет текста.

Вот код:

import fitz 
doc = fitz.open("/Users/khaylablack/Desktop/participant_certificate.pdf")           
page = doc[0]                         # choose some page
rect = fitz.Rect(50, 100, 200, 200)   # rectangle (left, top, right, bottom) in pixels

text = "absolutely not"

rc = page.insertTextbox(rect, text, fontsize = 48, # choose fontsize (float)
                   fontname = "Times-Roman",       # a PDF standard font
                   fontfile = None,                # could be a file on your system
                   align = 1)                      # 0 = left, 1 = center, 2 = right

#doc.saveIncr()   # update file. Save to new instead by doc.save("new.pdf",...)
doc.save("/Users/khaylablack/Desktop/watermarked_participant_cert.pdf")

3 ответа

При использовании метода insertTextbox() вы должны быть уверены, что создаваемый прямоугольник может содержать текст, потому что в противном случае вы не увидите текст. Один из способов сделать это - проверить длину текста для вашей реализации, например:

text = "absolutely not"
text_lenght = fitz.getTextlength(text, fontname="Times-Roman", fontsize=48))

text_lenght будет 270,67.

Но ширина прямоугольника у вас всего 150 (200-150). Кроме того, даже изменение ширины прямоугольника не сработает, потому что он все еще слишком короткий, поэтому вам также нужно увеличить его высоту. Еще вы можете просто изменить размер шрифта, который вы используете. Эти две альтернативы будут выглядеть так:

  • Альтернатива 1, больший прямоугольник:
fontsize_to_use = 48

text = "absolutely not"
fontname_to_use = "Times-Roman"

text_lenght = fitz.getTextlength(text, 
                                 fontname=fontname_to_use, 
                                 fontsize=fontsize_to_use)

rect_x1 = 50
rect_y1 = 100
rect_x2 = rect_x1 + text_lenght + 2  # needs margin
rect_y2 = rect_y1 + fontsize_to_use + 2  # needs margin


rect = (rect_x1, rect_y1, rect_x2, rect_y2)

## Uncomment if you wish to display rect
# page.drawRect(rect,color=(.25,1,0.25)) 

rc = page.insertTextbox(rect, text,
                        fontsize=fontsize_to_use,
                        fontname=fontname_to_use,
                        align=1)

Альтернатива 2, меньший размер шрифта:

text = "absolutely not"
fontname_to_use = "Times-Roman"

rect_x1 = 50
rect_y1 = 100
rect_x2 = 200
rect_y2 = 200

rect_width = rect_x2 - rect_x1
rect_height = rect_y2 - rect_y1

rect = (rect_x1, rect_y1, rect_x2, rect_y2)

fontsize_to_use = rect_width/len(text)*2  # *2 just because 1pt is too small for a char. It mantains a good ratio for rect's width with larger text, but behaviour is not assured.

## Uncomment if you wish to display rect
# page.drawRect(rect,color=(.25,1,0.25))

rc = page.insertTextbox(rect, text,
                        fontsize=fontsize_to_use,
                        fontname=fontname_to_use,
                        align=1)

Примечание: rc - это неиспользуемая высота прямоугольника, она также может быть отрицательной, в вашем случае это было -5,59, что означает, что текст превышал высоту прямоугольника.

У меня была та же проблема, и благодаря @JorjMcKie я смог ее решить, добавив вызов

      page.clean_contents(False)

после загрузки страницы.

Из официальной документации pyMuPDF :

Page.clean_contents(sanitize=True)

  • Изменено в версии 1.17.6

Только PDF: очистите и объедините все объекты, связанные с этой страницей. «Чистка» включает в себя синтаксические исправления, стандартизацию и «красивую печать» потока содержимого. Расхождения междуcontentsиresourcesобъекты также будут исправлены, если Sanitize имеет значение true. См. Page.get_contents() для более подробной информации.

Изменено в версии 1.16.0: аннотации больше не очищаются этим методом неявно. ИспользоватьAnnot.clean_contents()в отдельности.

Параметры: sanitize (bool) – (новое в версии 1.17.6), если true, синхронизация между ресурсами и их фактическим использованием в объекте содержимого синхронизируется. Например, если шрифт фактически не используется ни в каком тексте страницы, он будет удален из объекта /Resources/Font.

Предупреждение:

Это сложная функция, которая может генерировать большие объемы новых данных и делать старые данные неиспользованными. Не рекомендуется использовать его вместе с опцией инкрементного сохранения. Также обратите внимание, что полученный одноэлементный новый объект /Contents не сжат. Поэтому вам следует сохранить в новый файл, используя параметры «deflate=True, мусор=3» .

Вы установили и pymupdf, и fitz? Если нет, попробуйте запустить их в командной строке.

pip install pymupdf
pip install fitz

Другие вопросы по тегам