# Import the required libraries.
import re
# Define a function to read the full content of a PDF file.
[docs]
def ReadFullPDF(filePath):
r'''
Reads the full content of a PDF file and returns it as a string.
Parameters:
filePath (str): The path to the PDF file to be read.
Returns:
str: The full text content of the PDF file.
'''
import fitz
# Open the PDF file using fitz (PyMuPDF).
doc = fitz.open(filePath)
# Initialize an empty string to hold the text.
fullText = ""
# Iterate through each page in the document.
for page in doc:
# Extract text from the current page and append it to fullText.
fullText += page.get_text()
# Close the document to free resources.
doc.close()
# Clean up the report text by removing newlines and extra spaces.
fullText = fullText.replace("\n", " ").strip()
# Replace multiple spaces with a single space using regular expressions.
fullText = re.sub(r"\s+", " ", fullText)
# Return the cleaned full text content of the PDF file.
return fullText
# Define a function to read the content of a specific page in a PDF file.
[docs]
def ReadPDFPage(filePath, pageNum):
r'''
Reads the content of a specific page in a PDF file.
Parameters:
filePath (str): The path to the PDF file.
pageNum (int): The page number to read (0-based).
Returns:
str: The text content of the specified page.
'''
import fitz
doc = fitz.open(filePath)
# Check if the page number is valid.
if (pageNum < 0 or pageNum >= doc.page_count):
doc.close()
raise IndexError("Page number out of range.")
# Extract text from the specified page.
text = doc.load_page(pageNum).get_text()
doc.close()
# Return the cleaned text.
return text.replace("\n", " ").strip()
# Define a function to get the total number of pages in a PDF file.
[docs]
def GetPDFPageCount(filePath):
r'''
Returns the total number of pages in a PDF file.
Parameters:
filePath (str): The path to the PDF file.
Returns:
int: The number of pages in the PDF.
'''
import fitz
doc = fitz.open(filePath)
count = doc.page_count
doc.close()
return count
# Define a function to extract all text matching a regex pattern from a PDF file.
# Define a function to extract metadata from a PDF file.
# Define a function to extract images from all pages of a PDF file.
# Define a function to extract tables from a PDF file using tabula-py.
# Define a function to save a range of pages from a PDF file as a new PDF.
[docs]
def SplitPDF(filePath, startPage, endPage, outputPath):
r'''
Saves a range of pages from a PDF file as a new PDF.
Parameters:
filePath (str): The path to the PDF file.
startPage (int): The starting page (0-based).
endPage (int): The ending page (exclusive, 0-based).
outputPath (str): The path to save the new PDF.
'''
import fitz
doc = fitz.open(filePath)
if ((startPage < 0) or (endPage < 0) or (startPage >= endPage) or (startPage >= doc.page_count)):
doc.close()
raise IndexError("Invalid page range.")
newDoc = fitz.open()
# Insert the specified range of pages into the new PDF.
for i in range(startPage, min(endPage, doc.page_count)):
newDoc.insert_pdf(doc, from_page=i, to_page=i)
newDoc.save(outputPath)
newDoc.close()
doc.close()
# Define a function to merge multiple PDF files into a single PDF.
[docs]
def MergePDFs(pdfPaths, outputPath):
r'''
Merges multiple PDF files into a single PDF.
Parameters:
pdfPaths (list): List of PDF file paths to merge.
outputPath (str): Path to save the merged PDF.
'''
import fitz
merged = fitz.open()
# Iterate through each PDF file and insert its pages.
for path in pdfPaths:
doc = fitz.open(path)
merged.insert_pdf(doc)
doc.close()
merged.save(outputPath)
merged.close()
# Define a function to delete specified pages from a PDF and save the result.
[docs]
def DeletePDFPages(filePath, pagesToDelete, outputPath):
r'''
Deletes specified pages from a PDF and saves the result.
Parameters:
filePath (str): Path to the PDF file.
pagesToDelete (list): List of 0-based page indices to delete.
outputPath (str): Path to save the new PDF.
'''
import fitz
doc = fitz.open(filePath)
doc.delete_pages(pagesToDelete)
doc.save(outputPath)
doc.close()
# Define a function to rotate specified pages in a PDF by a given angle.
[docs]
def RotatePDFPages(filePath, rotation, outputPath, pages=None):
r'''
Rotates specified pages in a PDF by a given angle.
Parameters:
filePath (str): Path to the PDF file.
rotation (int): Angle to rotate (90, 180, 270).
outputPath (str): Path to save the rotated PDF.
pages (list or None): List of 0-based page indices to rotate. If None, rotate all.
'''
import fitz
# Validate rotation.
if (rotation not in (90, 180, 270)):
raise ValueError("Invalid rotation angle.")
doc = fitz.open(filePath)
if (pages is None):
pages = list(range(doc.page_count))
# Validate pages.
for p in pages:
if (p < 0 or p >= doc.page_count):
doc.close()
raise IndexError("Page index out of range.")
for i in pages:
page = doc.load_page(i)
page.set_rotation(rotation)
doc.save(outputPath)
doc.close()
# Define a function to extract annotations/comments from all pages of a PDF file.
# Define a function to check if the PDF contains the specified text.
[docs]
def PDFContainsText(
filePath,
searchText,
caseSensitive=False,
useRegex=False,
returnPositions=False
):
r'''
Checks if the PDF contains the specified text, with options for case sensitivity, regex, and returning positions.
Parameters:
filePath (str): Path to the PDF file.
searchText (str): Text or regex pattern to search for.
caseSensitive (bool): If True, search is case sensitive.
useRegex (bool): If True, searchText is treated as a regex pattern.
returnPositions (bool): If True, returns list of (pageNum, position) for all occurrences.
Returns:
bool or list: True/False if found (default), or list of (pageNum, position) if returnPositions is True.
'''
import fitz
flags = 0 if (caseSensitive) else re.IGNORECASE
doc = fitz.open(filePath)
found = False
positions = []
# Iterate through each page in the document.
for pageNum in range(doc.page_count):
page = doc.load_page(pageNum)
text = page.get_text()
# Use regex if specified.
if (useRegex):
matches = list(re.finditer(searchText, text, flags))
if (matches):
found = True
if (returnPositions):
for m in matches:
positions.append((pageNum, m.start()))
else:
search = searchText if (caseSensitive) else searchText.lower()
pageText = text if (caseSensitive) else text.lower()
idx = 0
while (True):
idx = pageText.find(search, idx)
if (idx == -1):
break
found = True
if (returnPositions):
positions.append({
"page" : pageNum,
"index": idx,
})
idx += len(search)
doc.close()
if (returnPositions):
return positions
return found
# Define a function to add a bookmark to a specific page in the PDF.
[docs]
def AddPDFBookmark(filePath, pageNum, title, outputPath):
r'''
Adds a bookmark to a specific page in the PDF.
Parameters:
filePath (str): Path to the PDF file.
pageNum (int): Page number (0-based).
title (str): Bookmark title.
outputPath (str): Path to save the new PDF.
'''
import fitz
doc = fitz.open(filePath)
if ((pageNum < 0) or (pageNum >= doc.page_count)):
doc.close()
raise IndexError("Page number out of range.")
toc = doc.get_toc() or []
toc.append([1, title, pageNum])
doc.set_toc(toc)
doc.save(outputPath)
doc.close()
# Define a function to extract all hyperlinks from the PDF.
# Define a function to highlight all occurrences of a text string in the PDF.
[docs]
def HighlightPDFText(filePath, searchText, outputPath, color=(1, 1, 0)):
r'''
Highlights all occurrences of a text string in the PDF.
Parameters:
filePath (str): Path to the PDF file.
searchText (str): Text to highlight.
outputPath (str): Path to save the highlighted PDF.
color (tuple): RGB color tuple for highlight (default yellow).
Returns:
bool: True if any text was highlighted, False otherwise.
'''
import fitz
doc = fitz.open(filePath)
anyHighlighted = False
# Iterate through each page and search for the text.
for page in doc:
areas = page.search_for(searchText)
for area in areas:
annot = page.add_highlight_annot(area)
annot.set_colors(stroke=color)
annot.update()
anyHighlighted = True
# Always save output even if no matches.
doc.save(outputPath)
doc.close()
return anyHighlighted
# Define a function to encrypt the PDF with a password.
[docs]
def EncryptPDF(filePath, password, outputPath):
r'''
Encrypts the PDF with a password.
Parameters:
filePath (str): Path to the PDF file.
password (str): Password to set.
outputPath (str): Path to save the encrypted PDF.
'''
import fitz
doc = fitz.open(filePath)
doc.save(outputPath, encryption=fitz.PDF_ENCRYPT_AES_256, owner_pw=password, user_pw=password)
doc.close()
# Define a function to remove password protection from a PDF.
[docs]
def DecryptPDF(filePath, password, outputPath):
r'''
Removes password protection from a PDF.
Parameters:
filePath (str): Path to the encrypted PDF.
password (str): Password for decryption.
outputPath (str): Path to save the decrypted PDF.
'''
import fitz
doc = fitz.open(filePath)
# Authenticate using the provided password.
if (not doc.authenticate(password)):
doc.close()
raise ValueError("Incorrect password for PDF decryption.")
doc.save(outputPath)
doc.close()
# Define a function to list all fonts used in the PDF.
# Main block for example usage.
if __name__ == "__main__":
# Example PDF file path.
pdfPath = r"Example.pdf"
# Read the full content of the PDF.
fullContent = ReadFullPDF(pdfPath)
# Read the content of the first page.
page0Content = ReadPDFPage(pdfPath, 0)
# Get the total number of pages.
pageCount = GetPDFPageCount(pdfPath)
# Extract metadata from the PDF.
metadata = ExtractPDFMetadata(pdfPath)
# Extract email addresses using regex.
emails = ExtractPDFTextByRegex(pdfPath, r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
# Extract images from the PDF.
images = ExtractPDFImages(pdfPath)
# Extract tables from the PDF.
tables = ExtractPDFTables(pdfPath)
# Print the first 100 characters of the full text content.
print("Full Text Content (first 100 chars):", fullContent[:100])
# Print the length of the full text.
print("Length of Full Text:", len(fullContent))
# Print the first 100 characters of the first page content.
print("Page 0 Content (first 100 chars):", page0Content[:100])
# Print the length of the first page text.
print("Length of Page 0 Text:", len(page0Content))
# Print the total number of pages.
print("Total Number of Pages:", pageCount)
# Print the metadata.
print("Metadata:", metadata)
# Print the extracted email addresses.
print("Extracted Emails:", emails)
# Print the number of extracted images.
print("Number of Extracted Images:", len(images))
# Print the number of extracted tables.
print("Number of Extracted Tables:", len(tables))
# If tables are found, print a preview of the first table.
if (len(tables) > 0):
print("First Table Preview:\n", tables[0].head())
# Split the first 2 pages into a new PDF.
SplitPDF(pdfPath, 0, 2, r"ExtractedPages.pdf")
# Merge multiple PDFs into one.
MergePDFs(
[pdfPath, r"ExtractedPages.pdf"],
r"Merged.pdf"
)
# Delete the second page (index 1) from the PDF.
DeletePDFPages(pdfPath, [1], r"DeletedPage.pdf")
# Rotate the first page (index 0) by 90 degrees.
RotatePDFPages(pdfPath, 90, r"Rotated.pdf", pages=[0])
# Extract annotations from the PDF.
annotations = ExtractPDFAnnotations(pdfPath)
print("Extracted Annotations:", annotations)
# Check if the PDF contains a specific text.
containsText = PDFContainsText(pdfPath, "Lorem ipsum", caseSensitive=False)
print("Contains 'Lorem ipsum':", containsText)
# Get the positions of the word "Lorem" in the PDF.
positions = PDFContainsText(pdfPath, "Lorem", returnPositions=True)
print("First Found Positions of 'Lorem':", positions[:5])
# Add a bookmark to the first page.
AddPDFBookmark(pdfPath, 0, "Start of Document", r"Bookmarked.pdf")
# Extract all hyperlinks from the PDF.
links = ExtractPDFLinks(pdfPath)
print("Extracted Links:", links)
# Highlight the word "Lorem" in the PDF.
HighlightPDFText(pdfPath, "Lorem", r"Highlighted.pdf")
# Encrypt the PDF with a password.
EncryptPDF(pdfPath, "securepassword", r"Encrypted.pdf")
# Decrypt the previously encrypted PDF.
DecryptPDF(
r"Encrypted.pdf",
"securepassword",
r"Decrypted.pdf"
)
# Extract all fonts used in the PDF.
fonts = ExtractPDFFonts(pdfPath)
print("Extracted Fonts:", fonts)