吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1812|回复: 12
收起左侧

[Python 原创] PDF分割合并

  [复制链接]
xiaobaice 发表于 2024-5-8 11:12
本帖最后由 xiaobaice 于 2024-5-8 11:13 编辑

提取指定页面并合到一起,输出到代码目录下

import os
import time
from PyPDF2 import PdfReader, PdfWriter

def extract_pages(pdf_path, page_numbers):
    # 创建PdfReader对象
    pdf_reader = PdfReader(open(pdf_path, "rb"))

    # 创建PdfWriter对象
    pdf_writer = PdfWriter()

    # 提取并合并指定页面
    try:
        for page_number in page_numbers:
            page = pdf_reader.pages[page_number - 1]  # 页面索引从0开始
            pdf_writer.add_page(page)
    except Exception as e:
        print(f"提取页面时发生错误: {e}")
        raise  # 保留异常,让程序终止

    return pdf_writer

def save_pdf(pdf_writer, output_path, increment=False):
    # 检查文件是否存在并询问用户是否替换或加编号
    while os.path.exists(output_path):
        response = input(f"文件 {output_path} 已存在,是否替换?(y或者回车) 或 输入 'n' 自动添加编号:").lower()
        if response == "y" or response == "":
            break
        elif response == "n":
            increment = True
            break
        else:
            print("无效输入,请重新选择。")

    if increment:
        base_name, ext = os.path.splitext(output_path)
        i = 1
        while os.path.exists(output_path):
            output_path = f"{base_name}_{i}{ext}"
            i += 1

    # 保存PDF文件
    with open(output_path, "wb") as out_file:
        pdf_writer.write(out_file)

def format_page_range_string(page_numbers):
    page_numbers.sort()  # 确保页码有序
    continuous_ranges = []

    current_start = page_numbers[0]
    current_end = page_numbers[0]

    for num in page_numbers[1:]:
        if num == current_end + 1:  # 如果当前页码与前一页面连续
            current_end = num  # 更新当前范围的结束页码
        else:  # 当前页码与前一页面不连续,开始新的范围
            continuous_ranges.append((current_start, current_end))
            current_start = current_end = num

    # 添加最后一个范围
    continuous_ranges.append((current_start, current_end))

    # 将连续范围转换为字符串形式并连接
    formatted_ranges = [f"{start}-{end}" if start != end else str(start) for start, end in continuous_ranges]
    return ",".join(formatted_ranges)

def parse_page_range(page_range_str):
    ranges = []
    for part in page_range_str.split(","):
        if "-" in part:
            start, end = map(int, part.split("-"))
            ranges.extend(range(start, end + 1))
        else:
            ranges.append(int(part))
    return sorted(ranges)

def list_pdf_files(directory):
    pdf_files = []
    for file in os.listdir(directory):
        if file.lower().endswith('.pdf'):
            pdf_files.append(file)
    return pdf_files

def prompt_to_continue():
    print("提取完成,是否继续提取?(回车继续/任意键退出)")
    user_input = input().strip()
    return user_input == ""

def main():
    # 获取用户选择的PDF文件
    directory = input("请输入当前目录路径或输入 'L/回车' 列出当前目录下的PDF文件:")
    if directory.lower() == 'l' or directory.lower() == "":
        pdf_files = list_pdf_files(os.getcwd())
        print("当前目录下的PDF文件:")
        for i, file in enumerate(pdf_files, start=1):
            print(f"{i}. {file}")
        selection = input("请选择一个PDF文件(输入序号):")
        if not selection.isdigit() or int(selection) < 1 or int(selection) > len(pdf_files):
            print("无效的选择,请输入有效的序号。")
            return
        pdf_path = os.path.join(os.getcwd(), pdf_files[int(selection) - 1])
    else:
        pdf_path = directory
        while not os.path.isfile(pdf_path):
            print("文件不存在,请检查路径是否正确。")
            pdf_path = input("请重新输入当前目录路径或输入 'L' 列出当前目录下的PDF文件:")
            if pdf_path.lower() == 'l':
                pdf_files = list_pdf_files(os.getcwd())
                print("当前目录下的PDF文件:")
                for i, file in enumerate(pdf_files, start=1):
                    print(f"{i}. {file}")
                selection = input("请选择一个PDF文件(输入序号):")
                if not selection.isdigit() or int(selection) < 1 or int(selection) > len(pdf_files):
                    print("无效的选择,请输入有效的序号。")
                    return
                pdf_path = os.path.join(os.getcwd(), pdf_files[int(selection) - 1])
                break

    # 获取用户选择的打印类型
    print_types = {
        "1": "黑白单面",
        "2": "黑白双面",
        "3": "彩色单面",
        "4": "彩色双面"
    }
    for key, value in print_types.items():
        print(f"{key}. {value}")
    while True:
        print_type = input("请选择打印类型(输入数字):")
        if print_type in print_types:
            break
        print("无效的打印类型,请输入正确的数字。")

    # 获取用户输入的页面范围
    while True:
        page_range = input("请输入需要提取的页面范围(例如:1,2-5):")
        try:
            page_numbers = parse_page_range(page_range)
            break
        except Exception as e:
            print(f"输入的页面范围格式错误,请输入例如:1,2-5。错误信息:{e}")

    formatted_page_range = format_page_range_string(page_numbers)

    # 提取指定页面
    pdf_writer = extract_pages(pdf_path, page_numbers)

    # 根据打印类型和页面范围命名输出文件
    output_dir, output_file = os.path.split(pdf_path)
    output_name = f"{os.path.splitext(output_file)[0]}_{print_types[print_type]}_{formatted_page_range}.pdf"
    output_path = os.path.join(output_dir, output_name)

    # 保存PDF文件
    save_pdf(pdf_writer, output_path)

    # 提示用户是否继续
    if prompt_to_continue():
        main()  # 重新调用main函数

    print("等待10秒后自动退出...")
    time.sleep(10)

if __name__ == "__main__":
    main()

免费评分

参与人数 2吾爱币 +3 热心值 +2 收起 理由
LuckyClover + 1 + 1 谢谢@Thanks!
Arcticlyc + 2 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

LuckyClover 发表于 2024-5-8 11:38
鼓励一下,谢谢分享
sinewtec 发表于 2024-5-8 11:39
zhzhx 发表于 2024-5-8 11:52
L__ 发表于 2024-5-8 13:17

支持原创,谢谢分享
tctctren 发表于 2024-5-8 13:51
能讲解一下吗,我保存到记事本改后缀使用后没什么反应
Snooker 发表于 2024-5-8 14:13
只有学习才会进步,谢谢!
Corgibro 发表于 2024-5-8 16:22
厉害了,这个感觉很方便了
hhxk123 发表于 2024-5-9 11:04
谢谢分享,学习研究
liuam428 发表于 2024-5-9 21:40
很厉害,学习学习。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-14 19:08

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表