![]() |
How many times have you needed to merge two PDF documents or extract a few specific pages and resorted to the first free website found on Google?
While these services are convenient, they bring along two major issues:
- Privacy and Security: You are uploading potentially confidential documents (invoices, contracts, personal data) to third-party servers whose data management policies you often don't know.
- Operational limits: Maximum file size, limited number of daily operations, or annoying ad banners.
The solution? Build your own local Python utility. Not only is it incredibly simple to create, but it works instantly, is 100% secure, and imposes no limits.
The Ingredients: Why we use pypdf
For this project, we use pypdf (the modern, actively maintained successor to the historic PyPDF2 library). It is a lightweight, fast, pure-Python library that is super easy to integrate.
To install it, open your terminal and run:
pip install pypdf
Script Architecture
Our script covers two main needs:
- Merging (Merge): Scans a target folder, finds all
.pdffiles, and merges them into a single alphabetically sorted document. - Extraction (Split/Extract): Takes a PDF file and generates a new document keeping only the desired page range (e.g., from page 2 to 5).
We structured the code both as a reusable module and with a guided, interactive Command Line Interface (CLI).
The Complete Code
Here is the complete source code ready to use. Save it as pdf_merger_splitter.py:
import os
from pathlib import Path
from pypdf import PdfReader, PdfWriter
def merge_pdfs(input_folder: str, output_file: str) -> None:
"""Merges all PDF files in the specified folder into a single file."""
input_folder = input_folder.strip().strip('"').strip("'")
folder_path = Path(input_folder)
if not folder_path.exists() or not folder_path.is_dir():
print(f"❌ Error: The folder '{input_folder}' does not exist.")
return
# Retrieve and sort all .pdf files in the folder
pdf_files = sorted([f for f in folder_path.glob("*.pdf")])
if not pdf_files:
print(f"⚠️ No PDF files found in '{input_folder}'.")
return
merger = PdfWriter()
print(f"🔍 Found {len(pdf_files)} PDF files. Starting merge...")
for pdf in pdf_files:
print(f" └─ Adding: {pdf.name}")
merger.append(str(pdf))
output_file = output_file.strip().strip('"').strip("'")
merger.write(output_file)
merger.close()
print(f"✅ Merge completed successfully! Saved to: {output_file}\n")
def extract_pages(
input_file: str, output_file: str, start_page: int, end_page: int
) -> None:
"""Extracts a specific range of pages (1-based) from a PDF and saves them to a new file."""
input_file = input_file.strip().strip('"').strip("'")
file_path = Path(input_file)
if not file_path.exists():
print(f"❌ Error: The file '{input_file}' does not exist.")
return
reader = PdfReader(file_path)
writer = PdfWriter()
total_pages = len(reader.pages)
# Range validation
if start_page < 1 or end_page > total_pages or start_page > end_page:
print(
f"❌ Error: Invalid range. The document contains {total_pages} pages."
)
return
# pypdf uses 0-based indexing, convert from 1-based
for idx in range(start_page - 1, end_page):
writer.add_page(reader.pages[idx])
output_file = output_file.strip().strip('"').strip("'")
with open(output_file, "wb") as f_out:
writer.write(f_out)
print(
f"✅ Pages from {start_page} to {end_page} successfully extracted!"
)
print(f"📂 Saved to: {output_file}\n")
def main():
print("=" * 50)
print(" 📄 PDF MANAGEMENT UTILITY (Local & Private)")
print("=" * 50)
print("1. Merge all PDFs (alphabetically) in a folder")
print("2. Extract page range from a PDF")
print("3. Exit")
choice = input("\nSelect an option (1-3): ").strip()
if choice == "1":
folder = input("Path to the folder containing PDFs: [Drag & drop folder here to save time]").strip()
output = input(
"Output file name (e.g. merged.pdf) [Default: merged.pdf]: "
).strip()
if not output:
output = "merged.pdf"
merge_pdfs(folder, output)
elif choice == "2":
file_in = input("Path to the source PDF file: [Drag & drop file here to save time]").strip()
file_out = input(
"Output file name [Default: extracted.pdf]: "
).strip()
if not file_out:
file_out = "extracted.pdf"
try:
p_start = int(input("Start page (from 1): "))
p_end = int(input("End page: "))
extract_pages(file_in, file_out, p_start, p_end)
except ValueError:
print("❌ Error: Please enter valid integer numbers for pages.")
elif choice == "3":
print("Goodbye!")
else:
print("Invalid option.")
if __name__ == "__main__":
main()
How to Use It
- Run the script: Open the terminal in the folder where the script is located and execute:
python pdf_merger_splitter.py - To merge multiple PDFs: Enter the folder where the files are located. The script will read them in alphabetical order and generate the combined file.
- To extract pages: Specify the source file and indicate the range (e.g., from page
1to3).
📍 Where is the final file saved?
It depends on how you type the output file name:- Simple name (e.g.
merged.pdf): The file will be saved in the same folder where you are running the Python script (the current working directory of the terminal). - Full path (e.g.
C:\Users\John\Desktop\merged.pdfor/Users/john/Desktop/merged.pdf): The file will be generated exactly in the specified destination folder.
Practical Guide to Paths: How to never make a mistake
File paths have always been the main obstacle when using command-line tools. A small typo or a wrong space is enough to make the script fail.
Here is a practical guide with the easiest methods to specify paths without hassle, on both Windows and Mac.
💡 The Ultimate Trick: Drag & Drop
No need to type the path manually. When the script asks you:
Path to the folder... or Path to the source PDF file...
- Open the folder or file in your File Explorer (Windows) or Finder (Mac).
- Drag and drop it directly into the Terminal window.
- The terminal will automatically write the complete and correct path for you!
- Press Enter.
🛠️ How to get the path manually
If you prefer to copy and paste it, here is how to do it on different systems:
🪟 On Windows
- Select the file or folder.
- Press the key combination
Ctrl + Shift + C(Copy as path).- Alternatively: Right-click the file/folder and select "Copy as path".
- Paste into the terminal with
Ctrl + V.
Note for Windows: If the path contains quotation marks (e.g.,
"C:\My Documents\file.pdf"), you can leave them or remove them: the Python script or shell will handle them seamlessly.
🍎 On Mac
- Right-click (or two-finger tap on the trackpad) the file or folder.
- Hold down the
Option(⌥) key on your keyboard. - The menu item "Copy [Name] as Pathname" will appear.
- Paste into the terminal with
Cmd + V.
📌 Practical Syntax Examples
Paths can be written in two ways: Absolute (starting from the drive root) or Relative (starting from where you currently are).
1. Absolute Paths (Recommended to avoid errors)
They point to the exact location on the computer, regardless of where the Python script is saved.
- Windows:
- File:
C:\Users\John\Desktop\invoice.pdf - Folder:
C:\Users\John\Documents\PDFs_To_Merge
- File:
- Mac / Linux:
- File:
/Users/john/Desktop/invoice.pdf - Folder:
/Users/john/Documents/PDFs_To_Merge
- File:
2. Paths with Spaces
If the folder or file contains spaces (e.g., My Documents), make sure to enclose the path in quotation marks if typing manually, or simply use the Drag & Drop method mentioned above, which handles spaces automatically.
3. Relative Paths (For advanced users)
If you open the terminal already inside the folder where your PDFs are located, simply use the file names or a dot .:
- For the current folder: just type
.(a single dot means "the folder I am currently in"). - For a file in the same folder: just write the name, e.g.,
document.pdf.
🧱 Step-by-Step Usage Example
Here is what you will see on screen while running the program using drag & drop:
==================================================
📄 PDF MANAGEMENT UTILITY (Local & Private)
==================================================
1. Merge all PDFs (alphabetically) in a folder
2. Extract page range from a PDF
3. Exit
Select an option (1-3): 1
Path to the folder containing PDFs: [Drag & drop folder here to save time] -> C:\Users\John\Desktop\Contracts
Output file name (e.g. merged.pdf) [Default: merged.pdf]: contracts_2026_complete.pdf
🔍 Found 3 PDF files. Starting merge...
└─ Adding: 01_january.pdf
└─ Adding: 02_february.pdf
└─ Adding: 03_march.pdf
✅ Merge completed successfully! Saved to: contracts_2026_complete.pdf
Why this tool's approach wins
- 100% Offline: Your data stays exclusively on your computer.
- No Limits: You can merge 5 GB files or thousands of pages without slowdowns or running out of trial attempts.
- Extensible Automation: You can import the
merge_pdfsandextract_pagesfunctions into other more complex scripts (e.g., to automatically process monthly reports or invoices).
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
