From da0833d64afad7753214e0c1f571ef22eb7e6ac9 Mon Sep 17 00:00:00 2001 From: Craig Jones Date: Mon, 10 Aug 2020 15:11:55 -0700 Subject: [PATCH 1/3] Annotated the sample code. Renamed them to be consistent snake_case. Changed the README to markdown. --- Sample_Code/README.md | 38 +++++++++++++++++++++++++++++++++ Sample_Code/README.txt | 14 ------------ Sample_Code/basic_features.py | 9 ++++++++ Sample_Code/basic_merging.py | 5 +++++ Sample_Code/make_simple.py | 40 +++++++++++++++++++++++++++++++++++ Sample_Code/make_simple.sh | 20 ++++++++++++++++++ Sample_Code/makesimple.py | 38 --------------------------------- Sample_Code/makesimple.sh | 19 ----------------- 8 files changed, 112 insertions(+), 71 deletions(-) create mode 100644 Sample_Code/README.md delete mode 100644 Sample_Code/README.txt create mode 100755 Sample_Code/make_simple.py create mode 100755 Sample_Code/make_simple.sh delete mode 100755 Sample_Code/makesimple.py delete mode 100755 Sample_Code/makesimple.sh diff --git a/Sample_Code/README.md b/Sample_Code/README.md new file mode 100644 index 000000000..3c040bf00 --- /dev/null +++ b/Sample_Code/README.md @@ -0,0 +1,38 @@ +# PyPDF2 Sample Code Folder + +This folder contains demonstrations of just a few of PyPDF2's many features. + + +## `basic_features.py` + +Sample code that demonstrates: + +* Getting metadata from a PDF. +* Copying a PDF, one page at a time, and performing different operations on each page (resize, rotate, add a watermark). +* Encrypting a PDF. +* Adding javascript that runs when the PDF is opened. + + +## `basic_merging.py` + +Sample code that demonstrates merging together three PDFs into one, picking and choosing which pages appear in which order. +Selected pages can be added to the end of the output PDF being built, or inserted in the middle. + + +## `make_simple.py` + +Sample code to make a few simple PDF files of various page counts. + + +## `make_simple.sh` + +An example shell script that does the exact same thing as `makesimple.py`, +but by using the `ps2pdf` script on the command line. + + +To contribute more... + +Feel free to add any type of PDF file or sample code, either by + + 1) sending it via email to PyPDF2@phaseit.net + 2) including it in a pull request on GitHub \ No newline at end of file diff --git a/Sample_Code/README.txt b/Sample_Code/README.txt deleted file mode 100644 index ea0430c8a..000000000 --- a/Sample_Code/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -PyPDF2 Sample Code Folder -------------------------- - -This will contain demonstrations of the many features -PyPDF2 is capable of. Example code should make it easy -for users to know how to use all aspects of PyPDF2. - - - -Feel free to add any type of PDF file or sample code, -either by - - 1) sending it via email to PyPDF2@phaseit.net - 2) including it in a pull request on GitHub \ No newline at end of file diff --git a/Sample_Code/basic_features.py b/Sample_Code/basic_features.py index 5e874970d..0c212daad 100644 --- a/Sample_Code/basic_features.py +++ b/Sample_Code/basic_features.py @@ -1,3 +1,12 @@ +""" +Sample code that demonstrates: + +* Getting metadata from a PDF. +* Copying a PDF, one page at a time, and performing different operations on each page (resize, rotate, add a watermark). +* Encrypting a PDF. +* Adding javascript that runs when the PDF is opened. +""" + from PyPDF2 import PdfFileWriter, PdfFileReader output = PdfFileWriter() diff --git a/Sample_Code/basic_merging.py b/Sample_Code/basic_merging.py index 86562effc..ebff3000d 100644 --- a/Sample_Code/basic_merging.py +++ b/Sample_Code/basic_merging.py @@ -1,3 +1,8 @@ +""" +Sample code that demonstrates merging together three PDFs into one, picking and choosing which pages appear in which order. +Selected pages can be added to the end of the output PDF being built, or inserted in the middle. +""" + from PyPDF2 import PdfFileMerger merger = PdfFileMerger() diff --git a/Sample_Code/make_simple.py b/Sample_Code/make_simple.py new file mode 100755 index 000000000..9c5390e89 --- /dev/null +++ b/Sample_Code/make_simple.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +"""Sample code to make a few simple pdf files of various page counts.""" + +from __future__ import print_function +from sys import argv + +from reportlab.pdfgen import canvas + +POINT = 1 +INCH = 72 + +TEXT = """%s page %d of %d + +a wonderful file +created with Sample_Code/makesimple.py""" + + +def make_pdf_file(output_filename, page_count): + title = output_filename + c = canvas.Canvas(output_filename, pagesize=(8.5 * INCH, 11 * INCH)) + c.setStrokeColorRGB(0,0,0) + c.setFillColorRGB(0,0,0) + c.setFont("Helvetica", 12 * POINT) + for page_no in range(1, page_count + 1): + # The x-axis is at the bottom of the page, so 10 * INCH is 1 inch from the top. + vertical_pos = 10 * INCH + left_margin = 1 * INCH + for text_line in (TEXT % (output_filename, page_no, page_count)).split( '\n' ): + c.drawString(left_margin, vertical_pos, text_line) + vertical_pos -= 12 * POINT + c.showPage() + c.save() + +if __name__ == "__main__": + target_page_counts = [None, 5, 11, 17] + for i, target_page_count in enumerate(target_page_counts): + if target_page_count: + filename = "simple%d.pdf" % i + make_pdf_file(filename, target_page_count) + print ("Wrote", filename) diff --git a/Sample_Code/make_simple.sh b/Sample_Code/make_simple.sh new file mode 100755 index 000000000..4a06daf55 --- /dev/null +++ b/Sample_Code/make_simple.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# An example shell script that demonstrates using `ps2pdf` on the command line +sample=1 +for pagecount in 5 11 17; do + page=1 + f=simple$sample.pdf + while expr $page \<= $pagecount > /dev/null; do + if [ $page != 1 ]; then + echo " \c" + fi + echo "$f page $page of $pagecount" + echo "" + echo "an incredible, yet simple example" + echo "Created with Sample_Code/makesimple.sh" + page=$(expr $page + 1) + done | enscript --no-header -o - |ps2pdf - $f + echo $f + sample=$(expr $sample + 1) + done \ No newline at end of file diff --git a/Sample_Code/makesimple.py b/Sample_Code/makesimple.py deleted file mode 100755 index a05ac7c94..000000000 --- a/Sample_Code/makesimple.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -"Make some simple multipage pdf files." - -from __future__ import print_function -from sys import argv - -from reportlab.pdfgen import canvas - -point = 1 -inch = 72 - -TEXT = """%s page %d of %d - -a wonderful file -created with Sample_Code/makesimple.py""" - - -def make_pdf_file(output_filename, np): - title = output_filename - c = canvas.Canvas(output_filename, pagesize=(8.5 * inch, 11 * inch)) - c.setStrokeColorRGB(0,0,0) - c.setFillColorRGB(0,0,0) - c.setFont("Helvetica", 12 * point) - for pn in range(1, np + 1): - v = 10 * inch - for subtline in (TEXT % (output_filename, pn, np)).split( '\n' ): - c.drawString( 1 * inch, v, subtline ) - v -= 12 * point - c.showPage() - c.save() - -if __name__ == "__main__": - nps = [None, 5, 11, 17] - for i, np in enumerate(nps): - if np: - filename = "simple%d.pdf" % i - make_pdf_file(filename, np) - print ("Wrote", filename) diff --git a/Sample_Code/makesimple.sh b/Sample_Code/makesimple.sh deleted file mode 100755 index c0407a127..000000000 --- a/Sample_Code/makesimple.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -n=1 -for np in 5 11 17; do - p=1 - f=simple$n.pdf - while expr $p \<= $np > /dev/null; do - if [ $p != 1 ]; then - echo " \c" - fi - echo "$f page $p of $np" - echo "" - echo "an incredible, yet simple example" - echo "Created with Sample_Code/makesimple.sh" - p=$(expr $p + 1) - done | enscript --no-header -o - |ps2pdf - $f - echo $f - n=$(expr $n + 1) - done \ No newline at end of file From c2ca121a99ab25c62f6d2c6678af91f560d30c7b Mon Sep 17 00:00:00 2001 From: Craig Jones Date: Mon, 10 Aug 2020 20:41:23 -0700 Subject: [PATCH 2/3] Sample_Code/basic_features.py -- Syntax error: Tried to call file() instead of open(). --- Sample_Code/basic_features.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sample_Code/basic_features.py b/Sample_Code/basic_features.py index 0c212daad..c2509b901 100644 --- a/Sample_Code/basic_features.py +++ b/Sample_Code/basic_features.py @@ -50,5 +50,5 @@ output.encrypt(password) # finally, write "output" to document-output.pdf -outputStream = file("PyPDF2-output.pdf", "wb") +outputStream = open("PyPDF2-output.pdf", "wb") output.write(outputStream) From ab0884d98de2b90ca5479b100e2be7b1e1d95e1e Mon Sep 17 00:00:00 2001 From: Craig Jones Date: Mon, 10 Aug 2020 20:46:17 -0700 Subject: [PATCH 3/3] Added sample code for filling in the text fields of a PDF form. This required a few modifications to PdfFileWriter. (FYI: The example `fillable_form.pdf` was created in LibreOffice from the enclosed `fillable_form.odt`.) --- PyPDF2/pdf.py | 56 +++++++++++++++++++---------- Sample_Code/fillable_fields.py | 63 +++++++++++++++++++++++++++++++++ Sample_Code/fillable_form.odt | Bin 0 -> 10776 bytes Sample_Code/fillable_form.pdf | Bin 0 -> 19884 bytes 4 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 Sample_Code/fillable_fields.py create mode 100644 Sample_Code/fillable_form.odt create mode 100644 Sample_Code/fillable_form.pdf diff --git a/PyPDF2/pdf.py b/PyPDF2/pdf.py index c5cae9e67..3d0c2509b 100644 --- a/PyPDF2/pdf.py +++ b/PyPDF2/pdf.py @@ -250,17 +250,17 @@ def addAttachment(self, fname, fdata): :param str fname: The filename to display. :param str fdata: The data in the file. - + Reference: https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf Section 7.11.3 """ - + # We need 3 entries: # * The file's data # * The /Filespec entry # * The file's name, which goes in the Catalog - + # The entry for the file """ Sample: @@ -272,7 +272,7 @@ def addAttachment(self, fname, fdata): stream Hello world! endstream - endobj + endobj """ file_entry = DecodedStreamObject() file_entry.setData(fdata) @@ -291,14 +291,14 @@ def addAttachment(self, fname, fdata): """ efEntry = DictionaryObject() efEntry.update({ NameObject("/F"):file_entry }) - + filespec = DictionaryObject() filespec.update({ NameObject("/Type"): NameObject("/Filespec"), NameObject("/F"): createStringObject(fname), # Perhaps also try TextStringObject NameObject("/EF"): efEntry }) - + # Then create the entry for the root, as it needs a reference to the Filespec """ Sample: 1 0 obj @@ -309,13 +309,13 @@ def addAttachment(self, fname, fdata): /Names << /EmbeddedFiles << /Names [(hello.txt) 7 0 R] >> >> >> endobj - + """ embeddedFilesNamesDictionary = DictionaryObject() embeddedFilesNamesDictionary.update({ NameObject("/Names"): ArrayObject([createStringObject(fname), filespec]) }) - + embeddedFilesDictionary = DictionaryObject() embeddedFilesDictionary.update({ NameObject("/EmbeddedFiles"): embeddedFilesNamesDictionary @@ -329,7 +329,7 @@ def appendPagesFromReader(self, reader, after_page_append=None): """ Copy pages from reader to writer. Includes an optional callback parameter which is invoked after pages are appended to the writer. - + :param reader: a PdfFileReader object from which to copy page annotations to this writer object. The writer's annots will then be updated @@ -351,7 +351,7 @@ def appendPagesFromReader(self, reader, after_page_append=None): # Trigger callback, pass writer page as parameter if callable(after_page_append): after_page_append(writer_page) - def updatePageFormFieldValues(self, page, fields): + def updatePageFormFieldValues(self, page, fields, read_only = False): ''' Update the form field values for a given page from a fields dictionary. Copy field texts and values from fields to page. @@ -360,20 +360,39 @@ def updatePageFormFieldValues(self, page, fields): and field data will be updated. :param fields: a Python dictionary of field names (/T) and text values (/V) + + Credit for figuring out that it sometimes helps to set the field to + read-only: https://stackoverflow.com/users/8382028/viatech ''' # Iterate through pages, update field values for j in range(0, len(page['/Annots'])): writer_annot = page['/Annots'][j].getObject() for field in fields: if writer_annot.get('/T') == field: - writer_annot.update({ - NameObject("/V"): TextStringObject(fields[field]) - }) + writer_annot.update({NameObject("/V"): TextStringObject(fields[field])}) + if read_only: + writer_annot.update({NameObject("/Ff"): NumberObject(1)}) + + def have_viewer_render_fields(self): + """ + Some PDF viewers need to be coaxed into rendering field values. + This does so by setting a `/NeedAppearances` attribute to True + (which adds to the processing time slightly). + Credit for figuring this out: https://stackoverflow.com/users/8382028/viatech + """ + try: + catalog = self._root_object + if "/AcroForm" not in catalog: + self._root_object.update({NameObject("/AcroForm"): IndirectObject(len(self._objects), 0, self)}) + need_appearances = NameObject("/NeedAppearances") + self._root_object["/AcroForm"][need_appearances] = BooleanObject(True) + except Exception as e: + warnings.warn("Unable to set the /NeedAppearances flag. Filled-in field values may not render correctly. [{}]".format(repr(e))) def cloneReaderDocumentRoot(self, reader): ''' Copy the reader document root to the writer. - + :param reader: PdfFileReader from the document root should be copied. :callback after_page_append ''' @@ -1342,10 +1361,11 @@ def getFormTextFields(self): ''' # Retrieve document form fields formfields = self.getFields() - return dict( - (formfields[field]['/T'], formfields[field].get('/V')) for field in formfields \ - if formfields[field].get('/FT') == '/Tx' - ) + if formfields: + return dict( + (formfields[field]['/T'], formfields[field].get('/V')) for field in formfields \ + if formfields[field].get('/FT') == '/Tx') + return None def getNamedDestinations(self, tree=None, retval=None): """ diff --git a/Sample_Code/fillable_fields.py b/Sample_Code/fillable_fields.py new file mode 100644 index 000000000..1fed6494a --- /dev/null +++ b/Sample_Code/fillable_fields.py @@ -0,0 +1,63 @@ +""" +Sample code that copies a PDF, changing field values along the way (i.e. using a PDF with fillable fields as a template). +""" +import sys +from PyPDF2 import PdfFileWriter, PdfFileReader + +root_folder = "Sample_Code/" +template_name = "fillable_form.pdf" + + +def discover_fields(template_pdf, just_text=True): + if just_text: + available_fields = template_pdf.getFormTextFields() + else: + available_fields = template_pdf.getFields() + if available_fields: + for fieldname in available_fields: + print(fieldname) + else: + print("ERROR: '" + template_name + "' has no text fields.") + sys.exit(1) + +def fill_in_pdf(template_pdf, field_values, filename): + output = PdfFileWriter() + output.have_viewer_render_fields() + for page_no in range(template_pdf.getNumPages()): + template_page = template_pdf.getPage(0) + output.addPage(template_page) + page = output.getPage(page_no) + output.updatePageFormFieldValues(page, field_values, read_only=True) + output_stream = open(filename, "wb") + output.write(output_stream) + output_stream.close() + +template_pdf = PdfFileReader(open(root_folder + template_name, "rb"), strict=False) + +employee_john = { + "employee_name": "John Hardworker", + "employee_id": "0123", + "department": "Human Resources", + "manager_name": "Doris Stickler", + "manager_id": "0072" +} +employee_cyndi = { + "employee_name": "Cyndi Smartworker", + "employee_id": "0199", + "department": "Engineering", + "manager_name": "Steven Wright", + "manager_id": "0051" +} + + +discover_fields(template_pdf) + +fill_in_pdf(template_pdf, employee_john, root_folder + "JohnHardworder.pdf") + +# fill_in_pdf(template_pdf, employee_cyndi, root_folder + "CyndiSmartworker.pdf") +# FIXME: If you uncomment this second call, you get: +# File "C:\forks\PyPDF2\PyPDF2\pdf.py", line 594, in _sweepIndirectReferences +# if data.pdf.stream.closed: +# AttributeError: 'PdfFileWriter' object has no attribute 'stream' + + diff --git a/Sample_Code/fillable_form.odt b/Sample_Code/fillable_form.odt new file mode 100644 index 0000000000000000000000000000000000000000..e4fa56b9a1c0fa95b24d4dd020745dde918374e9 GIT binary patch literal 10776 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 z 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