8

I am trying to edit an existing pdf file using PyPDF and ReportLab. When I try to position the red circle and red text, it appears to be hiding behind a white container or something. If I position it anywhere else, it works fine. What is causing this?

sample pdf = https://www.puc.nh.gov/regulatory/CASEFILE/2010/10-246/INITIAL%20FILING%20-%20PETITION/10-246%202010-09-13%20BAYRING%20ATT%20TO%20PET%20FOR%20AUTH%20TO%20CONSTRUCT%20UTILITY%20CABLE%20OVER%20AND%20ACROSS%20SUNCOOK%20RIVER.PDF

WHAT THE ERROR IS:

WHAT THE FINAL RESULT SHOULD BE:

from PyPDF2 import PdfWriter, PdfReader
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.colors import red

def main():
    packet = io.BytesIO()
    can = canvas.Canvas(packet, pagesize=letter)
    can.setFillColorRGB(1, 0, 0)
    can.circle(370,780,20,fill=1)
    can.setFillColor(red)
    can.setFont("Times-Roman", 14)
    can.drawString(352, 785, "Customer Group #22")
    can.save()

    packet.seek(0)
    new_pdf = PdfReader(packet)

    existing_pdf = PdfReader(open("samplePDF.pdf", "rb"))
    output = PdfWriter()

    page = existing_pdf.pages[1]
    page.merge_page(new_pdf.pages[0])
    output.add_page(page)

    outputStream = open("finalPDF.pdf", "wb")
    output.write(outputStream)
    outputStream.close()
if __name__ == "__main__":
    main()
zachjohn987
  • 103
  • 7
  • 4
    Is it possible to share the PDF file? – Hoang Minh Quang FX15045 Mar 14 '23 at 01:39
  • @HoangMinhQuangFX15045, how can I upload a pdf file? – zachjohn987 Mar 14 '23 at 14:52
  • 1
    I think the simplest way is to upload the file to your Google Drive (or any other cloud storage method). Right-click and choose the share link. Then you can copy and paste the link on the post – Hoang Minh Quang FX15045 Mar 14 '23 at 15:28
  • @HoangMinhQuangFX15045, I added a sample pdf link to my post. Please see my post. Thank you – zachjohn987 Mar 14 '23 at 17:26
  • @KJ you wont see the red circle or text because sample pdf is the file I start with and then copy it to ```finalPDF.pdf``` which is where the red circle and text will be. This line ```page = existing_pdf.pages[1]``` will only print so you dont have to worry about the rest 9 pages when you run the code. Thank you – zachjohn987 Mar 14 '23 at 17:55
  • @KJ ok gotcha. I updated the post with the image that contains the error – zachjohn987 Mar 14 '23 at 18:00
  • @KJ okay i updated my post to show an image of the error and an image of what I want the final results to look like – zachjohn987 Mar 14 '23 at 18:09
  • @KJ, perfect that is what I am looking for. Please answer my post with the code so I can give you the bounty points. Thank you – zachjohn987 Mar 14 '23 at 19:09
  • 1
    I see. Yeah I do not know why the red circle or text get cut off. Its like hiding behind a container of the header or something – zachjohn987 Mar 14 '23 at 19:35
  • 1
    When I open the pdf with LibreOffice Draw, I can see a different landscape canvas and portrait page content. I am not sure if this is the exact issue, but I have previously faced such issues. – SajanGohil Mar 20 '23 at 07:05
  • 1
    PyPDF2 is deprecated. Use pypdf. – Martin Thoma Mar 22 '23 at 22:13

2 Answers2

1

Try using PdfFileWriter and PdfFileReader instead of not PdfWriter and PdfReader, and The merge_page method should be called on a PdfFileWriter object, not a PdfFileReader object.

Try this code :

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

def main():
    packet = io.BytesIO()
    can = canvas.Canvas(packet, pagesize=letter)
    can.setFillColorRGB(1, 0, 0)
    can.circle(370,780,20,fill=1)
    can.setFillColor(red)
    can.setFont("Times-Roman", 14)
    can.drawString(352, 785, "Customer Group #22")
    can.save()

    packet.seek(0)
    new_pdf_reader = PdfFileReader(packet)

    existing_pdf_reader = PdfFileReader(open("samplePDF.pdf", "rb"))
    output = PdfFileWriter()

    page = existing_pdf_reader.getPage(0)
    page.mergePage(new_pdf_reader.getPage(0))
    output.addPage(page)

    outputStream = open("finalPDF.pdf", "wb")
    output.write(outputStream)
    outputStream.close()

if __name__ == "__main__":
    main()
1

PROBABLE CAUSE

Your isses is most likely due to the existing PDF document contains a white background on top of which you are trying to add the red circle and text. Since the circle and text are also red, they are not visible against the white background.

FIX

  • you can add a transparent layer on top of the existing PDF document, and
  • then add the circle and text on this layer.
  • This will ensure that the white background does not interfere with the visibility of the circle and text.

CODE EXPLAIN

  • You should first create a transparent layer using the rect function with an alpha value of 0.5.
  • This creates a rectangle with a black fill that is 50% transparent.
  • Then you merge this transparent layer with the content from the existing PDF page using the mergePage function.
  • This ensures that the red circle and text are added on top of the transparent layer and are visible even against the white background of the existing PDF document.

CODE

from PyPDF2 import PdfWriter, PdfReader
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.colors import red

def main():
    packet = io.BytesIO()
    can = canvas.Canvas(packet, pagesize=letter)

    # Create a transparent layer
    can.setFillColorRGB(0, 0, 0, alpha=0.5)
    can.rect(0, 0, letter[0], letter[1], fill=1)

    can.setFillColorRGB(1, 0, 0)
    can.circle(370,780,20,fill=1)
    can.setFillColor(red)
    can.setFont("Times-Roman", 14)
    can.drawString(352, 785, "Customer Group #22")
    can.save()

    packet.seek(0)
    new_pdf = PdfReader(packet)

    existing_pdf = PdfReader(open("samplePDF.pdf", "rb"))
    output = PdfWriter()

    # Merge the transparent layer and the content from the existing PDF page
    page = existing_pdf.pages[1]
    page.mergePage(new_pdf.pages[0])
    output.addPage(page)

    outputStream = open("finalPDF.pdf", "wb")
    output.write(outputStream)
    outputStream.close()

if __name__ == "__main__":
    main()
sogu
  • 2,738
  • 5
  • 31
  • 90