PDF合并脚本的应用

年初购入了一台二手喷墨打印机后,最近在帮同学打印文件时遇到了一些小麻烦。同学一次性发来了十几到二十个文件,每个文件页数在5到10页之间,且要求进行双面打印。这台打印机的双面打印功能需要手动操作——正反面打印完一面后,得将纸张取下翻面再放回打印机继续打印。由于是喷墨打印机,打印速度不算快,连续处理这么多文件大概需要一小时左右的时间。

最初的想法是能不能直接批量打印这些文件,以减少操作次数。但很快发现一个问题:部分PDF文件的页数是单数。如果直接批量打印,可能会导致不同文件的内容被印在同一张纸上,造成混淆。为了避免这种情况,初步考虑是想办法让所有PDF文件的页数都变成偶数页,比如在单数页的文件末尾添加一个空白页,这样打印时就不会出现内容交叉的问题。

解决了页数的问题后,又浮现出另一个难点:十几个文件需要逐一打印反面,也就是说,每次打印完正面后,都得手动调整纸张位置,然后再打印反面。重复这个操作十几次,既繁琐又费时,还得一直守在打印机旁边。这时,想到一个更简便的办法——如果能把所有文件合并成一个大的PDF文件,只需要调整一次纸张,就能完成所有文件的双面打印。市面上有些软件,比如WPS Office,提供了PDF合并功能,但需要开通会员才能使用。虽然网上也有一些免费的在线工具可以实现类似操作,但考虑到文件可能涉及隐私或保密内容,这种方式并不理想。

为了同时解决页数调整和文件合并这两个问题,最终决定尝试用Python脚本来处理。我使用了一个AI工具——DeepSeek R1,把需求描述清楚后,让它帮忙生成一个基础脚本。AI给出的代码已经能基本满足要求:它可以检查PDF页数并在需要时添加空白页,同时将多个文件合并为一个PDF。不仅如此,AI还提供了一些改进建议,比如优化脚本的逻辑和功能。

在AI生成的基础脚本上,又做了一些完善。比如,添加了任务完成后的提示功能,让脚本运行时能清楚地显示当前进度和结果,这样使用起来更直观,也方便排查问题。

经过调整后,脚本在PyCharm中成功运行,功能完全符合预期。最终的PDF文件生成后,双面打印的过程变得简单多了,只需要操作一次纸张翻面,整个流程效率提高不少。为了方便有兴趣的朋友们参考和学习,python脚本的完整源码也附在了这里。

import os
import datetime
import tkinter as tk
from tkinter import filedialog, messagebox
from PyPDF2 import PdfReader, PdfWriter, errors

def add_blank_page(writer, last_page):
    """添加与最后一页相同尺寸的空白页"""
    width = float(last_page.mediabox.width)
    height = float(last_page.mediabox.height)
    writer.add_blank_page(width, height)

def merge_pdfs():
    # 创建输出文件夹
    output_dir = "PDF_Merge"
    os.makedirs(output_dir, exist_ok=True)
    
    # 生成时间戳文件名
    timestamp = datetime.datetime.now().strftime("%y-%m-%d_%H%M")
    output_file = os.path.join(output_dir, f"{timestamp}.pdf")
    
    # 设置文件对话框
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口
    file_paths = filedialog.askopenfilenames(
        title="选择要合并的PDF文件",
        filetypes=[("PDF文件", "*.pdf")]
    )
    
    if not file_paths:
        print("操作取消:未选择任何文件")
        return
    
    writer = PdfWriter()
    success_count = 0
    failure_count = 0
    error_messages = []
    
    for path in file_paths:
        try:
            with open(path, 'rb') as f:
                reader = PdfReader(f)
                if len(reader.pages) == 0:
                    raise errors.EmptyFileError(f"文件为空: {os.path.basename(path)}")
                
                num_pages = len(reader.pages)
                
                # 添加所有页面
                for i in range(num_pages):
                    writer.add_page(reader.pages[i])
                
                # 添加空白页如果是奇数页
                if num_pages % 2 == 1:
                    add_blank_page(writer, reader.pages[-1])
                
                success_count += 1
                print(f"✓ 已处理: {os.path.basename(path)} ({num_pages}页)")
                
        except Exception as e:
            failure_count += 1
            error_msg = f"处理失败: {os.path.basename(path)} - {str(e)}"
            error_messages.append(error_msg)
            print(f"✗ {error_msg}")
    
    # 检查是否有页面可写入
    if len(writer.pages) > 0:
        try:
            with open(output_file, 'wb') as f:
                writer.write(f)
            
            result_message = (
                f"全部合并完成!\\n"
                f"成功合并: {success_count}份文件\\n"
                f"失败文件: {failure_count}份\\n"
                f"输出文件: {os.path.abspath(output_file)}"
            )
            
            if error_messages:
                result_message += "\\n\\n错误详情:\\n" + "\\n".join(error_messages)
            
            print("\\n" + "="*50)
            print(result_message)
            print("="*50)
            
            # 显示结果对话框
            messagebox.showinfo("PDF合并完成", result_message)
            
        except Exception as e:
            error_msg = f"文件保存失败: {str(e)}"
            print(f"✗ {error_msg}")
            messagebox.showerror("保存失败", error_msg)
    else:
        error_msg = "没有可合并的有效PDF页面"
        print(f"✗ {error_msg}")
        messagebox.showerror("合并失败", error_msg)

if __name__ == "__main__":
    print("="*50)
    print("PDF合并工具 - 开始运行")
    print("="*50)
    merge_pdfs()

使用说明:

通过这次尝试,可以看到Python在处理简单重复性任务时确实很实用,尤其是结合AI工具后,不仅能快速生成代码,还能根据需求进一步优化。类似的文件处理问题其实挺常见,如果有兴趣,不妨试试用Python和AI来解决,既能节省时间,也能学到一些实用技能。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部