I have been looking for a basic PDF page remover. What I am looking for is something that will let me put in the page numbers I want removed from the file I select. Still really new I am reading a few books to learn, but wanting to use this to make my job a bit easier as the current program is very stupid where I have to make sure to remember to subtract a number from the page given due to how PDF is.
I have to basic codes I would love some critical review of so I can hopefully refine it and make it to something that is easy to use. I thank anyone for their time and help loving how python reads and feels.
from PyPDF2 import PdfFileWriter, PdfFileReader
pages_delete = [4]
input = PdfFileReader('example.pdf', 'rb')
output = PdfFileWriter()
for i in range(input.getNumPages()):
if i not in pages_delete:
p = input.getPage(i)
output.addPage(p)
with open('pages_deleted.pdf', 'wb') as f:
output.write(f)
this is the second one
import PyPDF2 import PdfFileWriter, PdfFileReader
pdf1File = open('*file_name*')
pdf1Reader = PyPDF2.PdfFileReader(pdf1File)
pdfWriter = PyPDF2.PdfFileWriter()
for pageNum in range(pdf1Reader.numPages):
pageObj - pdf1Reader.getPage(pageNum)
pdfWriter.removePage(pageObj)
pdfOutputFile = open('*filename*-Edit')
pdfWriter.write(pdfOutputFile)
pdfOutFile.close()
Related
My Situation
Hi, I'm relatively new to coding with Python, and I'm currently working on a "PDF-Writer" which should read in PDF files and then draw a certain String to it plus some other stuff. I'm doing this with canvas and PyPDF2 and it works fine.
My question is referring to this question:
(Add text to Existing PDF using Python)
Others already commented under the post but didn't post any answers there that's why I'm asking this question. I would have commented under the post, but sadly, I don't have the reputation to comment. But I think resolving the issue by asking a new question is also fine.
My problems
My first problem is that I can only write on the first page of the document. I would like to write on all pages of the document.
My second problem is that the first page of the document is also the last page for some reason.
Here my Code:
from PyPDF2 import PdfFileWriter, PdfFileReader
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.units import cm
file = input("Give path to the file >> ")
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
# register font
pdfmetrics.registerFont(TTFont('Arial', 'Arial.ttf'))
can.setFont(psfontname= "Arial",size = 10)
# create a new string
can.drawString(93, 54.5, "2022-12-21")
# create a white rectangle
can.setFillColorRGB(254,254,254)
can.rect(92.5,65,2*cm,0.34*cm, fill=1,stroke=0)
# save the pdf
can.save()
# move to the beginning of the StringIO buffer
packet.seek(0)
# create a new PDF with Reportlab
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(open(file, "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.pages[0]
page.merge_page(new_pdf.pages[0])
output.append_pages_from_reader(existing_pdf)
output.add_page(page)
# finally, write "output" to a real file
output_stream = open("destination3.pdf", "wb")
output.write(output_stream)
output_stream.close()
print("PDF created!")
What I've tried
Well, I added output.append_pages_from_reader(existing_pdf) to the code which led to the problems. Now I'm searching after a properly working Code :)
Well I got the answer, here is an excerpt:
existing_pdf = PdfFileReader(open(filename2, "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing pages
for x in range(existing_pdf.getNumPages()):
page = existing_pdf.pages[x]
page.merge_page(new_pdf.pages[0])
output.add_page(page)
# finally, write "output" to a real file
output_stream = open(outputPath, "wb")
output.write(output_stream)
output_stream.close()
print("PDF created!")
This code does exactly what I was expecting in my question above.
I would like to take a multi-page pdf file and create separate pdf files per page.
I have downloaded reportlab and have browsed the documentation, but it seems aimed at pdf generation. I haven't yet seen anything about processing PDF files themselves.
Is there an easy way to do this in python?
from PyPDF2 import PdfWriter, PdfReader
inputpdf = PdfReader(open("document.pdf", "rb"))
for i in range(len(inputpdf.pages)):
output = PdfWriter()
output.add_page(inputpdf.pages[i])
with open("document-page%s.pdf" % i, "wb") as outputStream:
output.write(outputStream)
etc.
I missed here a solution where you split the PDF to two parts consisting of all pages so I append my solution if somebody was looking for the same:
from PyPDF2 import PdfFileWriter, PdfFileReader
def split_pdf_to_two(filename,page_number):
pdf_reader = PdfFileReader(open(filename, "rb"))
try:
assert page_number < pdf_reader.numPages
pdf_writer1 = PdfFileWriter()
pdf_writer2 = PdfFileWriter()
for page in range(page_number):
pdf_writer1.addPage(pdf_reader.getPage(page))
for page in range(page_number,pdf_reader.getNumPages()):
pdf_writer2.addPage(pdf_reader.getPage(page))
with open("part1.pdf", 'wb') as file1:
pdf_writer1.write(file1)
with open("part2.pdf", 'wb') as file2:
pdf_writer2.write(file2)
except AssertionError as e:
print("Error: The PDF you are cutting has less pages than you want to cut!")
The PyPDF2 package gives you the ability to split up a single PDF into multiple ones.
import os
from PyPDF2 import PdfFileReader, PdfFileWriter
pdf = PdfFileReader(path)
for page in range(pdf.getNumPages()):
pdf_writer = PdfFileWriter()
pdf_writer.addPage(pdf.getPage(page))
output_filename = '{}_page_{}.pdf'.format(fname, page+1)
with open(output_filename, 'wb') as out:
pdf_writer.write(out)
print('Created: {}'.format(output_filename))
Source: https://www.blog.pythonlibrary.org/2018/04/11/splitting-and-merging-pdfs-with-python/
I know that the code is not related to python, however i felt like posting this piece of R code which is simple, flexible and works amazingly. The PDFtools package in R is amazing in splitting merging PDFs at ease.
library(pdftools) #Rpackage
pdf_subset('D:\\file\\20.02.20\\22 GT 2017.pdf',
pages = 1:51, output = "subset.pdf")
The earlier answers with PyPDF2 for splitting pdfs are not working anymore with the latest version update. The authors recommend using pypdf instead and this version of PyPDF2==3.0.1 will be the last version of PyPDF2. The function needs to be modified as follows:
import os
from PyPDF2 import PdfReader, PdfWriter
def split_pdfs(input_file_path):
inputpdf = PdfReader(open(input_file_path, "rb"))
out_paths = []
if not os.path.exists("outputs"):
os.makedirs("outputs")
for i, page in enumerate(inputpdf.pages):
output = PdfWriter()
output.add_page(page)
out_file_path = f"outputs/{input_file_path[:-4]}_{i}.pdf"
with open(out_file_path, "wb") as output_stream:
output.write(output_stream)
out_paths.append(out_file_path)
return out_paths
Note: The same function will work with pypdf as well. Import PdfReader and PdfWriter from pypdf rather than PyPDF2.
import fitz
src = fitz.open("source.pdf")
for page in src:
tar = fitz.open() # output PDF for 1 page
# copy over current page
tar.insert_pdf(src, from_page=page.number, to_page=page.number)
tar.save(f"page-{page.number}.pdf")
tar.close()
I am trying to use this class to append a page from one PDF to another by specifying the page position.
Does anyone have experience with this? I couldn't find any example of using PdfFileMerger.merge over internet
with open(orig_pdf, 'rb') as orig, open(amend_pdf, 'rb') as new:
pdf = PdfFileMerger()
pdf.merge(2, new)
pdf.write('.pdf')
Consider using merge and passing the position, which is the page number you wish to add the pdf file
There are (probably) many ways of achieving the same results. Heres a basic working example:
from PyPDF2 import PdfFileMerger, PdfFileReader
orig_pdf = r'C:\temp\old.pdf'
amend_pdf = r'C:\temp\new.pdf'
with open(orig_pdf, 'rb') as orig, open(amend_pdf, 'rb') as new:
merger = PdfFileMerger()
merger.append(PdfFileReader(orig_pdf))
# Add amend_pdf after page 2
merger.merge(2, PdfFileReader(amend_pdf))
merger.write("results.pdf")
For more info, have a look at the official documentation https://pythonhosted.org/PyPDF2/PdfFileMerger.html
Is anybody has experience merging two page of PDF file into one using python lib PyPDF2.
When I try page1.mergePage(page2) it results with page2 overlayed page1. How to make it to add page2 to the bottom of the page1?
As I'm searching the web for python pdf merging solution, I noticed that there's a general misconception with merging versus appending.
Most people call the appending action a merge but it's not. What you're describing in your question is really the intended use of mergePage which should be called applyPageOnTopOfAnother but that's a little long. What you are (were) looking for is really appending two files/pages into a new file.
Appending PDF files
Using the PdfFileMerger class and its append method.
Identical to the merge() method, but assumes you want to concatenate
all pages onto the end of the file instead of specifying a position.
Here's one way to do it taken from pypdf Merging multiple pdf files into one pdf:
from PyPDF2 import PdfFileMerger, PdfFileReader
# ...
merger = PdfFileMerger()
merger.append(PdfFileReader(file(filename1, 'rb')))
merger.append(PdfFileReader(file(filename2, 'rb')))
merger.write("document-output.pdf")
Appending specific PDF pages
And to append specific pages of different PDF files, use the PdfFileWriter class with the addPage method.
Adds a page to this PDF file. The page is usually acquired from a
PdfFileReader instance.
file1 = PdfFileReader(file(filename1, "rb"))
file2 = PdfFileReader(file(filename2, "rb"))
output = PdfFileWriter()
output.addPage(file1.getPage(specificPageIndex))
output.addPage(file2.getPage(specificPageIndex))
outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()
Merging two pages into one page
Using mergePage
Merges the content streams of two pages into one. Resource references
(i.e. fonts) are maintained from both pages. The mediabox/cropbox/etc
of this page are not altered. The parameter page’s content stream will
be added to the end of this page’s content stream, meaning that it
will be drawn after, or “on top” of this page.
file1 = PdfFileReader(file(filename1, "rb"))
file2 = PdfFileReader(file(filename2, "rb"))
output = PdfFileWriter()
page = file1.getPage(specificPageIndex)
page.mergePage(file2.getPage(specificPageIndex))
output.addPage(page)
outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()
If the 2 PDFs do not exist on your local machine, and instead are normally accessed/download via a URL (i.e. http://foo/bar.pdf & http://bar/foo.pdf), we can fetch both PDFs from remote locations and merge them together in memory in one-fell-swoop.
This eliminates the assumed step of downloading the PDF to begin with, and allows us to generalize beyond the simple case of both PDFs existing on disk. Specifically, it generalizes the solution to any HTTP-accessible PDF.
The example:
from PyPDF2 import PdfFileMerger, PdfFileReader
pdf_content_1 = requests.get('http://foo/bar.pdf').content
pdf_content_2 = requests.get('http://bar/foo.pdf').content
# Write to in-memory file-like buffers
pdf_buffer_1 = StringIO.StringIO().write(pdf_content_1)
pdf_buffer_2 = StringIO.StringIO().write(pdf_content_2)
pdf_merged_buffer = StringIO.StringIO()
merger = PdfFileMerger()
merger.append(PdfFileReader(pdf_buffer_1))
merger.append(PdfFileReader(pdf_buffer_2))
merger.write(pdf_merged_buffer)
# Option 1:
# Return the content of the buffer in an HTTP response (Flask example below)
response = make_response(pdf_merged_buffer.getvalue())
# Set headers so web-browser knows to render results as PDF
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = \
'attachment; filename=%s.pdf' % 'Merged PDF'
return response
# Option 2: Write to disk
with open("merged_pdf.pdf", "w") as fp:
fp.write(pdf_merged_buffer.getvalue())
Did it this way:
reader = PyPDF2.PdfFileReader(open("input.pdf",'rb'))
NUM_OF_PAGES = reader.getNumPages()
page0 = reader.getPage(0)
h = page0.mediaBox.getHeight()
w = page0.mediaBox.getWidth()
newpdf_page = PyPDF2.pdf.PageObject.createBlankPage(None, w, h*NUM_OF_PAGES)
for i in range(NUM_OF_PAGES):
next_page = reader.getPage(i)
newpdf_page.mergeScaledTranslatedPage(next_page, 1, 0, h*(NUM_OF_PAGES-i-1))
writer = PdfFileWriter()
writer.addPage(newpdf_page)
with open('output.pdf', 'wb') as f:
writer.write(f)
It works when every page has the same height and width. Otherwise, it needs some modifications.
Maybe Emile Bergeron solution is better. Didn't try it.
The pdfrw library can do this. There is a 4up example in the examples directory that places 4 input pages on every output page, and a booklet example that takes 8.5x11 input and creates 11x17 output. Disclaimer -- I am the pdfrw author.
The code posted in this following link accomplished your objective.
Using PyPDF2 to merge files into multiple output files
I believe the trick is:
merger.append(input)
I am writing a script that parses an internet site (maya.tase.co.il) for links, downloads pdf file and merges them. It works mostly, but merging gives me different kinds of errors depending on the file. I cant seem to figure out why. I cut out the relevant code and built a test only for two specific files that are causing a problem. The script uses pypdf, but I am willing to try anything that works. Some files are encrypted, some are not.
def is_incry(pdf):
from pyPdf import PdfFileWriter, PdfFileReader
input=PdfFileReader(pdf)
try:
input.getNumPages()
return input
except:
input.decrypt("")
return input
def merg_pdf(to_keep,to_lose):
import os
from pyPdf import PdfFileWriter, PdfFileReader
if os.path.exists(to_keep):
in1=file(to_keep, "rb")
in2=file(to_lose, "rb")
input1 = is_incry(in1)
input2 = is_incry(in2)
output = PdfFileWriter()
loop1=input1.getNumPages()
for i in range(0,loop1):
output.addPage(input1.getPage(i))#
loop2=input2.getNumPages()
for i in range(0,loop2):
output.addPage(input2.getPage(i))#
outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()
pdflen=loop1+loop2
in1.close()
in2.close()
os.remove(to_lose)
os.remove(to_keep)
os.rename("document-output.pdf",to_keep)
else:
os.rename(to_lose,to_keep)
in1=file(to_keep, "rb")
input1 = PdfFileReader(in1)
try:
pdflen=input1.getNumPages()
except:
input1.decrypt("")
pdflen=input1.getNumPages()
in1.close()
#input1.close()
return pdflen
def test():
import urllib
urllib.urlretrieve ('http://mayafiles.tase.co.il/RPdf/487001-488000/P487028-01.pdf', 'temp1.pdf')
urllib.urlretrieve ('http://mayafiles.tase.co.il/RPdf/488001-489000/P488170-00.pdf', 'temp2.pdf')
merg_pdf('temp1.pdf','temp2.pdf')
test()
I thank anyone that even took the time to read this.
Al.
I once wrote a complex PDF generation/merging stuff which I have now open-sourced.
You can have a look at it: https://github.com/becomingGuru/nikecup/blob/master/reg/models.py#L71
def merge_pdf(self):
from pyPdf import PdfFileReader,PdfFileWriter
pdf_file = file_names['main_pdf']%settings.MEDIA_ROOT
pdf_obj = PdfFileReader(open(pdf_file))
values_page = PdfFileReader(open(self.make_pdf())).getPage(0)
mergepage = pdf_obj.pages[0]
mergepage.mergePage(values_page)
signed_pdf = PdfFileWriter()
for page in pdf_obj.pages:
signed_pdf.addPage(page)
signed_pdf_name = file_names['dl_done']%(settings.MEDIA_ROOT,self.phash)
signed_pdf_file = open(signed_pdf_name,mode='wb')
signed_pdf.write(signed_pdf_file)
signed_pdf_file.close()
return signed_pdf_name
It then works like a charm. Hope it helps.
I tried the documents with pyPdf - it looks like both the pdfs in this document are encrypted, and a blank password ("") is not valid.
Looking at the security settings in adobe, you're allowed to print and copy - however, when you run pyPdf's input.decrypt(""), the files are still encrypted (as in, input.getNumPages() after this still returns 0).
I was able to open this in OSX's preview, and save the pdfs without encryption, and then the assembly works fine. pyPdf deals in pages though, so I don't think you can do this through pyPdf. Either find the correct password, or perhaps use another application, such as using a batch job to OpenOffice, or another pdf plugin would work.