Thêm văn bản vào PDF hiện có bằng Python


106

Tôi cần thêm một số văn bản bổ sung vào tệp PDF hiện có bằng Python, cách tốt nhất để thực hiện điều này là gì và tôi sẽ cần cài đặt thêm những mô-đun nào.

Lưu ý: Lý tưởng nhất là tôi muốn có thể chạy tính năng này trên cả Windows và Linux, nhưng chỉ Linux mới có thể chạy được.

Chỉnh sửa: pyPDFReportLab trông đẹp nhưng không ai cho phép tôi chỉnh sửa tệp PDF hiện có, có tùy chọn nào khác không?

Câu trả lời:


88

Tôi biết đây là một bài viết cũ hơn, nhưng tôi đã dành một thời gian dài để cố gắng tìm ra giải pháp. Tôi đã tìm thấy một cái tốt chỉ sử dụng ReportLab và PyPDF nên tôi nghĩ tôi sẽ chia sẻ:

  1. đọc PDF của bạn bằng cách sử dụng PdfFileReader(), chúng tôi sẽ gọi đầu vào này
  2. tạo một pdf mới có chứa văn bản của bạn để thêm bằng cách sử dụng ReportLab, lưu tệp này dưới dạng đối tượng chuỗi
  3. đọc đối tượng chuỗi bằng cách sử dụng PdfFileReader(), chúng tôi sẽ gọi văn bản này
  4. tạo một đối tượng PDF mới bằng cách sử dụng PdfFileWriter(), chúng tôi sẽ gọi đầu ra này
  5. lặp lại thông qua đầu vào và áp dụng .mergePage(*text*.getPage(0))cho từng trang bạn muốn thêm văn bản vào, sau đó sử dụng output.addPage()để thêm các trang đã sửa đổi vào tài liệu mới

Điều này hoạt động tốt cho các bổ sung văn bản đơn giản. Xem mẫu của PyPDF để đánh dấu tài liệu.

Đây là một số mã để trả lời câu hỏi dưới đây:

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

Từ đây, bạn có thể hợp nhất các trang của tệp đầu vào với một tài liệu khác.


2
"tạo một pdf mới chứa văn bản của bạn để thêm bằng ReportLab, lưu nó dưới dạng đối tượng chuỗi" Bạn làm điều đó như thế nào? Đó là một phiên bản canvas.
Lakshman Prasad

1
Tôi đã thêm một số mã mẫu ở trên để trả lời câu hỏi của Lakshman.
dwelch

Tôi khuyên bạn nên sử dụng PyPDF2 vì nó được cập nhật nhiều hơn, cũng kiểm tra mã mẫu của họ: github.com/mstamy2/PyPDF2/blob/…
blaze

2
Mã này sẽ tạo một tệp pdf mới và sẽ bỏ qua tất cả siêu dữ liệu. Vì vậy, nó không thêm vào pdf hiện có.
Anton Kukoba

124

Ví dụ cho [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()

Ví dụ cho 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
Đối với python3, gói phải được io.BytesIOvà sử dụng PyPDF2 chứ không phải pyPDF (không rõ ràng). Câu trả lời chính xác!
Noufal Ibrahim

4
Cám ơn vì đã chia sẻ. Nó hoạt động tuyệt vời. Một lưu ý: Tôi tin rằng tốt hơn là sử dụng openthay vì file.
mitenka

Tôi tin rằng đây là một câu trả lời dễ chấp nhận hơn, đặc biệt là vì nó bao gồm một ví dụ hoạt động.
Casey

1
Cẩn thận: Tài liệu mới chỉ bao gồm trang đầu tiên của tài liệu gốc! Thật dễ dàng để sao chép phần còn lại của các trang từ existing_pdfsang output, mã mẫu thì không.
alexis

@alexis: Bạn sẽ sửa đổi mã như thế nào để đưa thứ gì đó lên trang thứ hai của pdf? Tôi có một biểu mẫu sử dụng hai trang và tôi bị kẹt ở trang đầu tiên. Cảm ơn trước.
DavidV

11

pdfrw sẽ cho phép bạn đọc các trang từ một tệp PDF hiện có và vẽ chúng vào canvas bảng báo cáo (tương tự như vẽ một hình ảnh). Có các ví dụ cho điều này trong thư mục con pdfrwamples / rl1 trên github. Tuyên bố từ chối trách nhiệm: Tôi là tác giả pdfrw.


Tôi nghĩ bạn có thể đặt một liên kết ở đó
The6thSense

Điểm tốt! Tôi đã không thực hiện nhiều việc SO khi đăng bài đó và lo lắng về "chính sách liên kết cộng với văn bản tối thiểu." (Đại diện của tôi chỉ 46 là vào thời điểm đó, và IIRC Tôi vừa nhận được một -2 trên một câu trả lời, vì vậy tôi có một chút lo lắng về câu trả lời mới về các vấn đề cũ 5 năm :)
Patrick Maupin

những câu hỏi cũ được xem nhiều hơn :) và sự chú ý
The6thSense

FWIW, có một số ví dụ về reportlab / pdfrw khác nếu bạn bắt đầu theo liên kết này . Tôi đã trả lời ở đó, dựa trên một câu trả lời trong mục tiêu dupe.
Patrick Maupin

7

Tận dụng câu trả lời của David Dehghan ở trên, các hoạt động sau đây hoạt động trong 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 sẽ thực hiện công việc từ dòng lệnh. Tuy nhiên, nó không phải là python (afaik):

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

0

Bạn có thể gặp may mắn hơn khi giải quyết vấn đề khi chuyển đổi PDF thành định dạng có thể chỉnh sửa, viết các thay đổi của bạn, sau đó chuyển đổi lại thành PDF. Tôi không biết thư viện cho phép bạn chỉnh sửa trực tiếp PDF nhưng có rất nhiều trình chuyển đổi giữa DOC và PDF chẳng hạn.


1
Vấn đề là tôi chỉ có nguồn ở dạng PDF (từ bên thứ 3) và PDF -> DOC -> PDF sẽ mất rất nhiều trong việc chuyển đổi. Ngoài ra, tôi cần nó chạy trên Linux nên DOC có thể không phải là lựa chọn tốt nhất.
Frozenskys

Tôi tin rằng Adobe giữ khả năng chỉnh sửa PDF khá khép kín và độc quyền để họ có thể bán giấy phép cho các phiên bản Acrobat tốt hơn của họ. Có thể bạn có thể tìm cách tự động hóa việc sử dụng Acrobat Pro để chỉnh sửa nó, bằng cách sử dụng một số loại giao diện macro.
aehlke

Nếu các phần bạn muốn ghi vào là các trường biểu mẫu, thì sẽ có các giao diện XML để chỉnh sửa chúng - nếu không thì tôi không thể tìm thấy gì cả.
aehlke

Không, tôi chỉ muốn thêm một vài dòng văn bản vào mỗi trang.
Frozenskys

0

Nếu bạn đang sử dụng Windows, điều này có thể hoạt động:

Thử nghiệm trình tạo PDF

Ngoài ra còn có một báo cáo chính thức về một khuôn khổ tạo và chỉnh sửa PDF bằng Python. Nó hơi cũ nhưng có thể cung cấp cho bạn một số thông tin hữu ích:

Sử dụng Python làm Khung xử lý và chỉnh sửa PDF


Sách trắng trông đẹp nhưng hơi nhạt về mã và tôi thực sự không có đủ tài nguyên để tự triển khai toàn bộ khung PDF! ;)
Frozenskys

-4

Bạn đã thử pyPdf chưa?

Xin lỗi, nó không có khả năng sửa đổi nội dung của trang.


Có vẻ như nó có thể làm việc, có ai đã sử dụng nó? Việc sử dụng bộ nhớ như thế nào?
Frozenskys

Nó có khả năng thêm hình mờ văn bản và nếu nó được định dạng đúng, nó có thể hoạt động.
Frozenskys
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.