Додайте текст до існуючого PDF за допомогою Python


106

Мені потрібно додати трохи зайвого тексту до наявного PDF за допомогою Python, який найкращий спосіб зробити це та які додаткові модулі мені знадобиться встановити.

Примітка. В ідеалі я хотів би мати можливість це запустити і в Windows, і в Linux, але тільки при натисканні Linux це зробить.

Edit: pyPDF і ReportLab добре виглядати , але жоден з них не дозволить мені редагувати існуючий PDF, чи є інші варіанти?

Відповіді:


88

Я знаю, що це старіший пост, але я довго пробував, намагаючись знайти рішення. Я натрапив на пристойного, використовуючи лише ReportLab та PyPDF, тому я подумав, що поділюсь:

  1. читати ваш PDF за допомогою PdfFileReader(), ми будемо називати це введення
  2. створити новий pdf, що містить ваш текст, який потрібно додати за допомогою ReportLab, збережіть це як рядковий об'єкт
  3. читаючи рядовий об’єкт за допомогою PdfFileReader(), ми називаємо цей текст
  4. створити новий об'єкт PDF з допомогою PdfFileWriter(), ми будемо називати цей висновок
  5. ітерайте через введення та застосуйте .mergePage(*text*.getPage(0))для кожної сторінки, до якої потрібно додати текст, а потім використовуйте output.addPage()для додавання змінених сторінок до нового документа

Це добре працює для простих текстових доповнень. Дивіться зразок PyPDF для водного маркування документа.

Ось код, щоб відповісти на запитання нижче:

packet = StringIO.StringIO()
can = canvas.Canvas(packet, pagesize=letter)
<do something with canvas>
can.save()
packet.seek(0)
input = PdfFileReader(packet)

Звідси ви можете об'єднати сторінки вхідного файлу з іншим документом.


2
"створити новий pdf, що містить ваш текст, який потрібно додати за допомогою ReportLab, збережіть це як рядковий об'єкт" Як це зробити? Його полотно.
Лакшман Прасад

1
Я додав вище зразок коду, щоб відповісти на запитання Лакшмана.
пробувати

Я рекомендую використовувати PyPDF2, оскільки вона оновлюється, також перевірте їх зразок коду: github.com/mstamy2/PyPDF2/blob/…
blaze

2
Цей код створить новий pdf-файл та пропустить усі метадані. Отже, він не додається до існуючих PDF-файлів.
Антон Кукоба

124

Приклад для [Python 2.7]:

from pyPdf import PdfFileWriter, PdfFileReader
import StringIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

packet = StringIO.StringIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(10, 100, "Hello world")
can.save()

#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(file("original.pdf", "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = file("destination.pdf", "wb")
output.write(outputStream)
outputStream.close()

Приклад для Python 3.x:


from PyPDF2 import PdfFileWriter, PdfFileReader
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

packet = io.BytesIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(10, 100, "Hello world")
can.save()

#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(open("original.pdf", "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = open("destination.pdf", "wb")
output.write(outputStream)
outputStream.close()

13
Для python3, пакет повинен бути io.BytesIOта використовувати PyPDF2, а не pyPDF (що не підтримується). Чудова відповідь!
Нуфал Ібрагім

4
Дякую, що поділились. Це чудово працює. Одна примітка: Я вважаю, що краще використовувати openзамість цього file.
mitenka

Я вважаю, що це більш прийнятна відповідь, тим більше, що вона включає робочий приклад.
Кейсі

1
Обережно: новий документ містить лише першу сторінку оригіналу! Копіювати решту сторінок з, досить existing_pdfпросто output, зразок коду просто не містить.
alexis

@alexis: Як би ви змінили код, щоб щось розмістити на другій сторінці pdf? У мене форма, яка використовує дві сторінки, і я застряг на першій сторінці. Заздалегідь спасибі.
DavidV

11

pdfrw дозволить вам читати на сторінках із існуючого PDF та малювати їх на полотні звіту (аналогічно малюванню зображення). Приклади для цього є у підкаталозі pdfrw / rl1 на github. Відмова: Я автор pdfrw.


Я думаю, ви можете покласти там посилання
The6thSense

Гарна думка! Коли я розміщував це, я не робив багато чого, і хвилювався з приводу "мінімальної політики щодо тексту плюс посилання". (Моєму представнику тоді було лише 46, а в IIRC я ​​щойно отримав -2 на одну відповідь, тому мене трохи хвилювали нові відповіді на 5-річні запитання :)
Патрік Мопін,

старі питання отримує більше перегляду :) та уваги
The6thSense

FWIW, є ще кілька прикладів reportlab / pdfrw, якщо ви почнете переходити за цим посиланням . Я відповів там, грунтуючись на відповіді в цілі дупи.
Патрік Мопін

7

Використовуючи Девід Дегхан «s відповідь вище, такі роботи в Python 2.7.13:

from PyPDF2 import PdfFileWriter, PdfFileReader, PdfFileMerger

import StringIO

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

packet = StringIO.StringIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(290, 720, "Hello world")
can.save()

#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader("original.pdf")
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = open("destination.pdf", "wb")
output.write(outputStream)
outputStream.close()

3

cpdf виконає роботу з командного рядка. Це не пітон, хоча (afaik):

cpdf -add-text "Line of text" input.pdf -o output .pdf

0

Можливо, вам пощастить усунути проблему в перетворенні PDF-файлу у формат, який можна редагувати, внесення змін, а потім перетворення його в PDF. Я не знаю про бібліотеку, яка дозволяє вам безпосередньо редагувати PDF, але є багато конверторів, наприклад, між DOC і PDF.


1
Проблема полягає в тому, що у мене є лише джерело у форматі PDF (від третьої сторони), а PDF -> DOC -> PDF багато втратить при перетворенні. Також мені це потрібно для роботи на Linux, щоб DOC не був найкращим вибором.
Frozenskys

Я вважаю, що Adobe зберігає можливість редагування PDF досить закритою та захищеною, щоб вони могли продавати ліцензії на свої кращі версії Acrobat. Можливо, ви можете знайти спосіб автоматизувати використання Acrobat Pro для редагування, використовуючи якийсь інтерфейс макросу.
aehlke

Якщо частини, в які ви хочете записати, поля поля, у них є XML-інтерфейси для їх редагування - інакше я нічого не можу знайти.
aehlke

Ні, я просто хотів додати кілька рядків тексту на кожну сторінку.
Frozenskys

0

Якщо ви працюєте в Windows, це може працювати:

Пілот-експериментатор PDF

На Python також є документ про створення файлів та редагування PDF-файлів. Це трохи застаріло, але, можливо, може дати вам корисну інформацію:

Використання Python як рамки редагування та обробки PDF


Біла книга виглядає добре, але трохи полегшує код, і я не маю ресурсу, щоб сам реалізувати цілі рамки PDF! ;)
Frozenskys

-4

Ви спробували pyPdf ?

На жаль, він не має можливості змінювати вміст сторінки.


Схоже, це може спрацювати, хтось ним користувався? Яке використання пам'яті?
Frozenskys

Він має можливість додавати текстовий водяний знак, і якщо він був правильно відформатований, він може працювати.
Frozenskys
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.