My code merges two PDFs but in trying to set the desktop of the user as the destination of the new PDF the result is an unreadable PDF.
from PyPDF2 import *
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import LETTER
from datetime import datetime
from PyPDF2 import PdfFileReader, PdfFileMerger
import io
from tkinter.filedialog import askopenfilename
import os
from tkinter import *
root=Tk()
root.withdraw()\
#CREATE THE CARB PDF PAGE##################################
currentDay = datetime.now().day
currentMonth = datetime.now().month
currentYear = datetime.now().year
c = canvas.Canvas("CARB.pdf", pagesize=LETTER)
c.drawString(10, 170, "TEST")
c.drawString(45, 160, "TEST")
c.drawString(25, 150, "TEST")
c.drawString(50, 140, "___________ MONTH __________ YEAR")
c.drawString(80, 140, str(currentMonth))
c.drawString(200, 140, str(currentYear))
c.save()
#########################################################
username = os.getenv('username')
packet = io.BytesIO()
filename = askopenfilename()
packet.seek(0)
new_pdf = PdfFileReader(filename)
name = (os.path.basename(filename))
name = name[:-4]
#MERGE THE CREATED PDF WITH THE EXESTING PDF##############
existing_pdf = "CARB.pdf"
f1 = new_pdf
f2 = PdfFileReader(open('carb.pdf', 'rb'))
merger = PdfFileMerger(strict=True)
merger.append(f1)
merger.append(f2)
#merger.write(name + "-CARB.pdf")
output = PdfFileWriter()
outputStream = open("C:\\Users\\" + username + "\\Desktop\\" + name + "-CARB.pdf", "wb")
output.write(outputStream)
outputStream.close()
Related
I wrote code to add watermark to pdf files however, the resulting files do not contain the watermark.
import os
import io
from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
folder_path = 'D:/pdf/input/'
output_folder = 'D:/pdf/output/'
image_path = 'D:/pdf/watermark.jpg'
x, y = 50, 50
page_number = 1
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for pdf_file in os.listdir(folder_path):
if pdf_file.endswith(".pdf"):
pdf_reader = PdfReader(open(os.path.join(folder_path, pdf_file), "rb"))
pdf_writer = PdfWriter()
for page_num in range(len(pdf_reader.pages)):
pdf_page = pdf_reader.pages[page_num]
pdf_writer.add_page(pdf_page)
if page_num == page_number - 1:
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
can.drawImage(image_path, x, y)
can.save()
packet.seek(0)
new_pdf = PdfReader(packet)
pdf_page.merge_page(new_pdf.pages[0])
with open(os.path.join(output_folder, pdf_file), "wb") as output_file:
pdf_writer.write(output_file)
print("Image added to the specified page of all pdf files and saved in the output folder.")
I've tried changing the image position and page number, but still no effect. I expect watermark to be added at a specific place in the pdf file.
FIXED
import os
import io
from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
folder_path = 'D:/pdf/pliki/'
output_folder = 'D:/pdf/output/'
sign_path = 'D:/pdf/obraz/podpis.png'
x_position = 300
y_position = 260
width = 150
height = 150
if not os.path.exists(output_folder):
os.makedirs(output_folder)
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
can.drawImage(sign_path, x_position, y_position, width, height, [112,113,112,113,112,113])
can.save()
packet.seek(0)
new_pdf = PdfReader(packet)
for pdf_file in os.listdir(folder_path):
if pdf_file.endswith(".pdf"):
pdf_reader = PdfReader(open(os.path.join(folder_path, pdf_file), "rb"))
pdf_merged = pdf_reader.pages[0]
pdf_merged.merge_page(new_pdf.pages[0])
pdf_writer = PdfWriter()
for i in range(len(pdf_reader.pages)):
if i == 0:
pdf_writer.add_page(pdf_merged)
else:
pdf_writer.add_page(pdf_reader.pages[i])
with open(os.path.join(output_folder, pdf_file), "wb") as output_file:
pdf_writer.write(output_file)
print("Watermark added to the specified page of all pdf files and saved in the output folder.")
I have a function that asks the user for a PDF file and receive the page number the user wish to convert into an image. The function usually works fine however with a few PDFs it does not work, the image that is returned is blank and it has 4 mega bytes. Apparently it has something to do with the size of the file. Is there a way to solve this problem?
from PyPDF2 import PdfFileReader, PdfFileWriter
from tkinter.filedialog import askopenfilename
from pdf2image import convert_from_path
import os
import PIL
PIL.Image.MAX_IMAGE_PIXELS = None
def convert_pdf(page_number):
filename = askopenfilename()
pdf_file_path = filename
file_base_name = pdf_file_path.replace('.pdf', '')
pdf = PdfFileReader(pdf_file_path)
pages = [page_number]
pdfWriter = PdfFileWriter()
for page_num in pages:
pdfWriter.addPage(pdf.getPage(page_num))
with open('{0}_subset.pdf'.format(file_base_name[:-5]), 'wb') as f:
pdfWriter.write(f)
f.close()
n = file_base_name[:-5]
nome = f'{n}_subset.pdf'
pages = convert_from_path(nome, poppler_path=r'C:\Program Files\poppler-0.68.0\bin')
i = 1
name = os.path.basename(nome).split('/')[-1][:-4]
for page in pages:
image_name = "Page_" + str(i) + f"{name}.jpg"
page.save(image_name, "JPEG")
i = i + 1
The solution to this problem was to change the DPI parameter of convert_from_path function. It is important to leave the DPI as it is, since I found that certain images become really small, and therefore unreadable.
try:
pages = convert_from_path(nome, poppler_path=r'C:\Program Files\poppler-0.68.0\bin')
i = 1
except:
PIL.Image.MAX_IMAGE_PIXELS = None
pages = convert_from_path(nome, 25,poppler_path=r'C:\Program Files\poppler-0.68.0\bin')
i = 1
Desired: watermark multiple PDF files on each page
Issue: I can't seem to find a way to close a stream and open new stream for file (f), the end result is output of the PDF files but each preposit PDF contains the content of the preceding PDF file - this is not the desired outcome.
Here is my code:
# -*- coding: utf-8 -*-
import os
import re
from PyPDF4 import PdfFileWriter, PdfFileReader
from reportlab.pdfgen import canvas
from datetime import datetime
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from dotenv import load_dotenv
load_dotenv()
def put_watermark(input_files, output_files):
pdfmetrics.registerFont(TTFont('English', 'Arial.ttf'))
now = datetime.now()
hebrew = (" some string ")
dt_string = now.strftime("%d/%m/%Y %H:%M")
dt_string = dt_string + hebrew
genmark = canvas.Canvas("watermark.pdf")
genmark.setFont("Hebrew", 12)
genmark.drawString(350,15, dt_string)
genmark.save()
watermark_instance = PdfFileReader("watermark.pdf")
watermark_page = watermark_instance.getPage(0)
pdf_writer = PdfFileWriter()
for filename in os.listdir(input_files):
f = os.path.join(input_files, filename)
# Generate canvas with timestamp
pdf_reader = PdfFileReader(f)
for page in range(pdf_reader.getNumPages()):
page = pdf_reader.getPage(page)
page.mergePage(watermark_page)
pdf_writer.addPage(page)
output_file = os.path.join(output_files, filename)
with open(output_file, 'wb') as out:
pdf_writer.write(out)
os.remove('watermark.pdf')
if __name__ == '__main__':
put_watermark(input_files = os.environ["PYPDF_INPUT"],
output_files = os.environ["PYPDF_OUTPUT"])
Change to pyPDF2 from pyPDF4 solved this issue.
I have an issue with my program.
Whenever I encrypt multiple files, it works flawlessly; when I decrypt the files however, it fails pretty hard. No errors or anything.
The issue is just;
Only one file decrypts, no more. The rest of the files do look decrypted, but at the same time ?not?
Here is an example image of what shows when I decrypted a text file with pi to 1m digits. This only happens when decrypting multiple files.
Finally, here is the code. Big thanks to anyone willing to be helpfull!!! :)
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
import sys
import os.path
from tkinter import *
import tkinter.filedialog as fd
from tkinter import ttk
from tkinter import messagebox
from PIL import ImageTk,Image
from os import startfile
# Just some path defining stuff
user_profile = os.environ['USERPROFILE']
user_desktop = user_profile + "\\Documents"
os.chdir(sys.path[0])
save_path = f'{sys.path[0]}/TestEncrypted'.replace("\\","/")
save_path2 = f'{sys.path[0]}/TestDecrypted'.replace("\\","/")
# Create directories for encrypted/decrypted files
try:
os.mkdir(save_path)
except:
print(f'Directory: {save_path} already exists')
try:
os.mkdir(save_path2)
except:
print(f'Directory: {save_path2} already exists')
def padkey(key):
global oldkey
oldkey = key
while len(key)% 16 != 0:
key+= " "
return key
def encrypt1():
"""
Loops over files for encryption.
"""
newkey = padkey('testpass').encode('UTF-8')
cipher = AES.new(newkey,AES.MODE_CBC)
# Create for loop here!!!
filez = fd.askopenfilenames(parent=root, title='Choose files to encrypt',initialdir = user_desktop)
for filename in filez:
try:
with open(filename, 'rb') as f:
rfile = f.read()
f.close()
except:
messagebox.showerror("ITExtra Popup", "You didn't select a file")
ciphertext = cipher.encrypt(pad(rfile, AES.block_size))
encryptfilename = filename.split('/')[-1]+'.ENCRYPTED'
completeName = os.path.join(save_path, encryptfilename).replace("\\","/")
print(completeName)
with open(completeName,'wb') as c_file:
c_file.write(cipher.iv)
c_file.write(ciphertext)
c_file.close()
label2=Label(root,text=(save_path+"/"+encryptfilename).replace('\\','/').lower(),font='Helvetica 13 bold italic',fg='BLUE',bg='black').place(relx=0,rely=0.88)
return
def decrypt1():
"""
Loops over files for decryption.
"""
faildec = 0
succdec = 0
filez2 = fd.askopenfilenames(parent=root, title='Choose files to decrypt',initialdir = save_path)
for decryptfilename in filez2:
newkey = padkey('testpass').encode('UTF-8')
# Decrypt file
try:
with open(decryptfilename,'rb') as c_file:
iv = c_file.read(16)
ciphertext = c_file.read()
c_file.close()
except:
faildec +=1
cipher = AES.new(newkey,AES.MODE_CBC, iv)
rfile = unpad(cipher.decrypt(ciphertext),AES.block_size)
# Input extension and save file
filename = decryptfilename.split('/')[-1].replace('.ENCRYPTED', '')
completeName2 = os.path.join(save_path2, filename)
with open(completeName2, 'wb') as writefile:
writefile.write(rfile)
writefile.close()
label2=Label(root,text=(save_path2+"/"+filename).replace("\\","/").lower(),font='Helvetica 10 bold italic',fg='BLUE',bg='black').place(relx=0,rely=0.88)
succdec +=1
response2 = messagebox.askyesno("ITExtra Popup", f"""Do you want to open the 'Decrypted' directory?\n{save_path2}
Successful decryptions = {succdec}
Failed decryptions = {faildec}
""")
if response2 == 1:
startfile(save_path2)
return
print(sys.path[0])
print(save_path)
print(save_path2)
print(user_desktop)
root = Tk()
w = 850 # width for the Tk root
h = 310 # height for the Tk root
ws = root.winfo_screenwidth() # width of the screen
hs = root.winfo_screenheight() # height of the screen
x = (ws/2) - (w/2)
y = (hs/3) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
frame1=LabelFrame(root,bd=0,bg='#000000')
but1 = Button(frame1, text="ENCRYPT file", padx=30, pady=10, bg="#1f1f1f",fg="red",font='Helvetica 15 bold', command=encrypt1,relief=FLAT)
but2 = Button(frame1, text="DECRYPT file", padx=30, pady=10, bg="#1f1f1f",fg="green",font='Helvetica 15 bold', command=decrypt1,relief=FLAT)
but1.grid(row=2,column=0,padx=1,pady=5) # Encrypt FILE #
but2.grid(row=2,column=2,pady=5) # Decrypt FILE #
frame1.place(relx=0.20,rely=0.5)
root.mainloop()
Edit
Removed except statements for debugging purposes.
How could I save dfa as a pdf?
So far I was able to have each of the elements saved separately in each file. How now can I have the whole file saved as a single pdf?
dfa = pd.DataFrame({'STREAM':['EAGLE','HAWK','HAWK','HAWK','EAGLE','HAWK','EAGLE'],'MAT':['A','D','F','D','C','C','E'],'KIS':['B','D','E','D','A','C','D'],'GEO':['B','C','E','E','F','A','B']})
dfa.to_csv('results.csv',index=False)
students_data = csv.reader(open("results.csv", 'r'))
for row in students_data:
STREAM = row[0]
MAT = row[1]
GEO = row[2]
KIS = row[3]
c = canvas.Canvas(MAT +".pdf")
c.drawString(60, 700, "STREAM: " + STREAM)
c.drawString(60, 600, "MAT: " + MAT)
c.drawString(60, 500, "KIS: " + KIS)
c.drawString(60, 400, "GEO: " + GEO)
c.save()
My suggestion would be to create a blank PDF as your template page and then
merge the new PDF to it
packet = io.BytesIO()
# Create the initial canvas.
c = canvas.Canvas(packet)
# your code for adding to the canvas
packet.seek(0)
new_pdf = PdfFileReader(packet)
# Import The Template
template = PdfFileReader(open('path_to_template'), "rb")
output = PdfFileWriter()
# add the created PDF as a watermark to the template
page = template.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = open(output_path, "wb")
output.write(outputStream)
outputStream.close()
you will need these imports
from PyPDF2 import PdfFileWriter, PdfFileReader
import io