24.01.2020

Rotate PDF files with PyPdf2 and Tkinter!

Rotating PDF files with PyPDF2 and Tkinter

Introduction

Sometimes we need simple and basic tools to get the job done. At work, we have people that use pdf files daily, on which they need to perform certain manual operations. One of these operations is rotating pages. Thinking of programming a pdf rotator can look quite massive at first, but is it really?

To build our tool, we need to be able to rotate the pdf in three ways, clockwise, counterclockwise and 180 degrees. For simplicity, we want to rotate all pdf files in our current working directory. The user shall also be able to use the finished script, without installing Python or any dependencies on Windows. Let us walk through the steps in creating our tool.

Step 1 - PyPDF2 for rotating pages

Rotating a pdf with PyPDF2 can be done with the PageObject class's method RotateClockwise. The method takes one Int parameter, anglewhich defines the rotation degrees. Note that the angle have to be specified in incremetns of 90°. There is no possibility of rotating a PDF page for example 55°.

Ok, we know how to rotate our page, now we need to load our PDF file into memory. After that, we need to initialize our PdfFileReader and PdfFileWriter objects. We can then loop through our pages by using the readers numPages variable. We get the page, rotate it, write it to our new PDF and then save it to disc.

import PyPDF2
with open("test.pdf", "rb") as pdf_file: pdf_reader = PyPDF2.PdfFileReader(pdf_file) pdf_writer = PyPDF2.PdfFileWriter() print("Rotating", degrees) for page_num in range(pdf_reader.numPages): pdf_page = pdf_reader.getPage(page_num) pdf_page.rotateClockwise(degrees) pdf_writer.addPage(pdf_page) with open("test_rotated.pdf", "wb") as pdf_file_rotated: pdf_writer.write(pdf_file_rotated)

Step 2 - Giving the user an interface

A command line interface might work for many users, but believe me, a Graphical USer Interface (GUI) beats a Command Line Interface (CLI) by lightyears for the average user. To easily create our interface, we use Tkinter. We need three Radiobuttons for specifying the rotations, Left, Right and 180 degrees. We also need some kind of descripte text to guide the user, as well as a Button for being able to start the rotation. See the code comments for further descriptions.

import tkinter as tk
# Create our root widget, set title and size
master = tk.Tk()
master.title("PDF rotator")
master.geometry("400x100")

# Create a IntVar for getting our rotate values
master.degrees = tk.IntVar()

# Create a description label and a couple radiobuttons, add them to the widget
tk.Label(master, text="Rotates all pdf in the current folder the selected degrees.").grid(row=0,columnspan=4)
tk.Radiobutton(master, text="Right 90 degrees", variable=master.degrees, value=90).grid(row=1,column=1)
tk.Radiobutton(master, text="Left 90 degrees", variable=master.degrees, value=-90).grid(row=1,column=2)
tk.Radiobutton(master, text="180 degrees", variable=master.degrees, value=180).grid(row=1,column=3)

# Create a button for calling our function
master.ok_button = tk.Button(master, command=rotate_pdf, text="Rotate pdf files")
master.ok_button.grid(row=2,column=1)

# Run
tk.mainloop()

Step 3 - Getting the files

We want to rotate all pdf files in the folder where our script is contained. 

import os
# Get all the files in current folder from where we are running the script
files = [f for f in os.listdir('.') if os.path.isfile(f)]
files = list(filter(lambda f: f.lower().endswith(('.pdf')), files))

Step 4 - Putting it all together

Here is the complete code for rotating our pdf files. Enjoy!

#!/usr/bin/env python3
# -*- coding: <utf-8> -*-

import PyPDF2
import tkinter as tk
import os
import sys

# Get all the files in current folder from where we are running the script
files = [f for f in os.listdir('.') if os.path.isfile(f)]
files = list(filter(lambda f: f.lower().endswith(('.pdf')), files))

# main rotate pdf function
def rotate_pdf(*args):
    degrees = master.degrees.get()
    pdf_rotator(files, degrees)

# The pdf rotator
def pdf_rotator(files, degrees):
    
    for filename in files:
        if degrees != 0 and degrees != "":
            with open(filename, "rb") as pdf_file:
                pdf_reader = PyPDF2.PdfFileReader(pdf_file)
                pdf_writer = PyPDF2.PdfFileWriter()

                print("Rotating", degrees)

                for page_num in range(pdf_reader.numPages):
                    pdf_page = pdf_reader.getPage(page_num)
                    pdf_page.rotateClockwise(degrees)
                    
                    pdf_writer.addPage(pdf_page)

                with open(filename[:-4]+"rotated_"+str(degrees)+".pdf", "wb") as pdf_file_rotated:
                    pdf_writer.write(pdf_file_rotated)
    sys.exit()

# Create our root widget, set title and size
master = tk.Tk()
master.title("PDF rotator")
master.geometry("400x100")

# Create a IntVar for getting our rotate values
master.degrees = tk.IntVar()

# Create a description label and a couple radiobuttons, add them to the widget
tk.Label(master, text="Rotates all pdf in the current folder the selected degrees.").grid(row=0,columnspan=4)
tk.Radiobutton(master, text="Right 90 degrees", variable=master.degrees, value=90).grid(row=1,column=1)
tk.Radiobutton(master, text="Left 90 degrees", variable=master.degrees, value=-90).grid(row=1,column=2)
tk.Radiobutton(master, text="180 degrees", variable=master.degrees, value=180).grid(row=1,column=3)

# Create a button for calling our function
master.ok_button = tk.Button(master, command=rotate_pdf, text="Rotate pdf files")
master.ok_button.grid(row=2,column=1)

# Run
tk.mainloop()

 

 

Leave a Reply

Your email address will not be published.

linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram