• 使用 Python 给 PDF 添加目录书签


    0、库的选择——pypdf

    原因:Python Version Support

    Python

    3.11

    3.10

    3.9

    3.8

    3.7

    3.6

    2.7

    pypdf>=3.0

    YES

    YES

    YES

    YES

    YES

    YES

    PyPDF2>=2.0

    YES

    YES

    YES

    YES

    YES

    YES

    PyPDF2 1.20.0 - 1.28.4

    YES

    YES

    YES

    YES

    YES

    YES

    PyPDF2 1.15.0 - 1.20.0

    YES

    我的版本

    Python=3.6.13

    pypdf=3.16.2

    1、添加书签——方法add_outline_item的使用

    1. # https://zhuanlan.zhihu.com/p/603340639
    2. import pypdf #
    3. import sys
    4. wk_in_file_name = 'PythonTutorial.pdf'
    5. input1 = open(wk_in_file_name, "rb") # 打开需要添加书签的PDF
    6. writer = pypdf.PdfWriter() # 创建一个PdfWriter类
    7. writer.append(input1) # 将PDF读入writer中,然后进行书签的编辑
    8. writer.add_outline_item(title='10', page_number=10, parent=None) # 添加第一个书签
    9. writer.add_outline_item(title='11', page_number=11, parent=None) # 添加第二个书签
    10. # Write to an output PDF document
    11. output = open('01_' + wk_in_file_name, "wb") # 如果wk_out_file_name不存在,则创建一个
    12. writer.write(output) # 将添加书签后的PDF保存
    13. # Close File Descriptors
    14. writer.close()
    15. output.close()
    16. print('pypdf.__version__=', pypdf.__version__)
    17. print('sys.version=', sys.version)
    18. pass

    运行结果

    2、添加子书签——参数parent的使用

    1. # https://zhuanlan.zhihu.com/p/603340639
    2. import pypdf
    3. wk_in_file_name = 'PythonTutorial.pdf'
    4. writer = pypdf.PdfWriter()
    5. input1 = open(wk_in_file_name, "rb")
    6. writer.append(input1)
    7. parent_bookmark_0 = writer.add_outline_item(title='10', page_number=10, parent=None) # 添加第一个书签
    8. writer.add_outline_item(title='10_1', page_number=11, parent=parent_bookmark_0) # 添加第一个书签的子书签
    9. parent_bookmark_1 = writer.add_outline_item(title='11', page_number=20, parent=None) # 添加第二个书签
    10. writer.add_outline_item(title='11_1', page_number=21, parent=parent_bookmark_1) # 添加第二个书签的子书签
    11. # Write to an output PDF document
    12. output = open('02_'+wk_in_file_name, "wb")
    13. writer.write(output)
    14. # Close File Descriptors
    15. writer.close()
    16. output.close()
    17. pass

    运行结果

    3、读取txt文件

    1. # https://blog.csdn.net/kobeyu652453/article/details/106876829
    2. f = open('dir.txt', 'r', encoding='utf8')
    3. # f = open('dir.txt', encoding='gbk', errors='ignore'), errors='ignore'
    4. # f = open('dir.txt', encoding='gb18030', errors='ignore')
    5. line1 = f.readline() # 读取第一行,大文件readline
    6. # https://blog.csdn.net/andyleo0111/article/details/87878784
    7. lines = f.readlines() # 读取所有行,小文件readlines
    8. num_lines = len(lines) # 标题的总个数
    9. txt = []
    10. for line in lines:
    11. txt.append(line.strip())
    12. print(line.strip())
    13. line.strip() # 去掉末尾的'\n'
    14. line.split(' ') # 根据line中' '进行分割
    15. line.count('.') # 有n个'.'就是n+1级标题
    16. print(txt)
    17. f.close() # 关闭文件
    18. print('f.closed=', f.closed)

     运行结果

    1. D:\SoftProgram\JetBrains\anaconda3_202303\envs\py3_6_for_TimeSeries\python.exe E:\program\python\gitTemp\pdf\test\03_read_txt.py
    2. 1 课前甜点 3
    3. 2 使用Python解释器 5
    4. 2.1 调用解释器 5
    5. 2.1.1 传入参数 6
    6. 2.1.2 交互模式 6
    7. 2.2 解释器的运行环境 6
    8. 2.2.1 源文件的字符编码 6
    9. 3 Python的非正式介绍 9
    10. 3.1 Python作为计算器使用 9
    11. 3.1.1 数字 9
    12. 3.1.2 字符串 11
    13. 3.1.3 列表 14
    14. 3.2 走向编程的第一步 15
    15. 4 其他流程控制工具 17
    16. 4.1 if语句 17
    17. 4.2 for语句 17
    18. 4.3 range()函数 18
    19. 4.4 breakcontinue语句,以及循环中的else子句 19
    20. 4.5 pass 语句 20
    21. 4.6 定义函数 20
    22. 4.7 函数定义的更多形式 22
    23. 4.8 小插曲:编码风格 29
    24. ['1 课前甜点 3', '2 使用Python解释器 5', '2.1 调用解释器 5', '2.1.1 传入参数 6', '2.1.2 交互模式 6', '2.2 解释器的运行环境 6', '2.2.1 源文件的字符编码 6', '3 Python的非正式介绍 9', '3.1 Python作为计算器使用 9', '3.1.1 数字 9', '3.1.2 字符串 11', '3.1.3 列表 14', '3.2 走向编程的第一步 15', '4 其他流程控制工具 17', '4.1 if语句 17', '4.2 for语句 17', '4.3 range()函数 18', '4.4 break和continue语句,以及循环中的else子句 19', '4.5 pass 语句 20', '4.6 定义函数 20', '4.7 函数定义的更多形式 22', '4.8 小插曲:编码风格 29']
    25. f.closed= True
    26. 进程已结束,退出代码0

    4、从txt中读取目录与页码并写入PDF的书签

    1. # https://blog.csdn.net/kobeyu652453/article/details/106876829
    2. import pypdf
    3. wk_in_file_name = 'PythonTutorial.pdf'
    4. writer = pypdf.PdfWriter()
    5. input1 = open(wk_in_file_name, "rb")
    6. writer.append(input1)
    7. f = open('dir.txt', 'r', encoding='utf8')
    8. lines = f.readlines() # 读取所有行
    9. num_lines = len(lines) # 标题的总个数
    10. txt = []
    11. for line in lines:
    12. line = line.strip() # 去掉末尾的'\n'
    13. pline = line.split(' ') # 根据line中' '进行分割
    14. level = line.count('.') # 有n个'.'就是n+1级标题
    15. if level == 0:
    16. bookmark_parent_0 = writer.add_outline_item(title=pline[0] + pline[1], page_number=int(pline[-1]), parent=None)
    17. elif level == 1:
    18. bookmark_parent_1 = writer.add_outline_item(title=pline[0] + pline[1], page_number=int(pline[-1]),
    19. parent=bookmark_parent_0)
    20. else:
    21. writer.add_outline_item(title=pline[0] + pline[1], page_number=int(pline[-1]), parent=bookmark_parent_1)
    22. # Write to an output PDF document
    23. output = open('04_'+wk_in_file_name, "wb")
    24. writer.write(output)
    25. # Close File Descriptors
    26. writer.close()
    27. output.close()
    28. f.close() # 关闭文件
    29. print('f.closed=', f.closed)

    运行结果 

     5、添加偏置

    1. # https://blog.csdn.net/kobeyu652453/article/details/106876829
    2. import pypdf
    3. wk_in_file_name = 'PythonTutorial.pdf'
    4. writer = pypdf.PdfWriter()
    5. input1 = open(wk_in_file_name, "rb")
    6. writer.append(input1)
    7. f = open('dir.txt', 'r', encoding='utf8')
    8. lines = f.readlines() # 读取所有行
    9. num_lines = len(lines) # 标题的总个数
    10. offset = 5 # 添加偏置
    11. txt = []
    12. bookmark_parent_0 = None
    13. bookmark_parent_1 = None
    14. for line in lines:
    15. line = line.strip() # 去掉末尾的'\n'
    16. pline = line.split(' ') # 根据line中' '进行分割
    17. level = line.count('.') # 有n个'.'就是n+1级标题
    18. page_title = pline[0] + ' ' + pline[1]
    19. page_num = int(pline[-1]) + offset
    20. if level == 0:
    21. bookmark_parent_0 = writer.add_outline_item(title=page_title, page_number=page_num, parent=None)
    22. elif level == 1:
    23. bookmark_parent_1 = writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_0)
    24. else:
    25. writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_1)
    26. print(line.strip())
    27. print(txt)
    28. # Write to an output PDF document
    29. output = open('05_' + wk_in_file_name, "wb")
    30. writer.write(output)
    31. # Close File Descriptors
    32. writer.close()
    33. output.close()
    34. f.close() # 关闭文件
    35. print('f.closed=', f.closed)

    运行结果:

     

    6、dir中没有页码的情况

    1. # https://blog.csdn.net/kobeyu652453/article/details/106876829
    2. import pypdf
    3. wk_in_file_name = 'PythonTutorial.pdf'
    4. writer = pypdf.PdfWriter()
    5. input1 = open(wk_in_file_name, "rb")
    6. writer.append(input1)
    7. f = open('dir.txt', 'r', encoding='utf8')
    8. lines = f.readlines() # 读取所有行
    9. num_lines = len(lines) # 标题的总个数
    10. offset = 5 # 添加偏置
    11. txt = []
    12. bookmark_parent_0 = None
    13. bookmark_parent_1 = None
    14. for line in lines:
    15. line = line.strip() # 去掉末尾的'\n'
    16. pline = line.split(' ') # 根据line中' '进行分割
    17. level = line.count('.') # 有n个'.'就是n+1级标题
    18. page_title = pline[0] + ' ' + pline[1]
    19. page_num = offset
    20. if level == 0:
    21. bookmark_parent_0 = writer.add_outline_item(title=page_title, page_number=page_num, parent=None)
    22. elif level == 1:
    23. bookmark_parent_1 = writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_0)
    24. else:
    25. writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_1)
    26. print(line.strip())
    27. print(txt)
    28. # Write to an output PDF document
    29. output = open('06_' + wk_in_file_name, "wb")
    30. writer.write(output)
    31. # Close File Descriptors
    32. writer.close()
    33. output.close()
    34. f.close() # 关闭文件
    35. print('f.closed=', f.closed)

    运行结果

    参考

    使用 python 给 PDF 添加目录书签_pypdf2.errors.deprecationerror: pdffilereader is d_Wreng我是002的博客-CSDN博客

    python 操作合并pdf 文件并建立书签目录 - 知乎 

  • 相关阅读:
    Github每日精选(第36期):find简单、快速和用户友好的替代工具fd
    CTFshow wbe41 教你写脚本
    风格迁移adaIN 和iT的adaLN
    如何在Windows上配置OpenVPN,使客户端能够访问服务器端内网其他主机?
    关于CSS 优先级布局应用的教程
    震惊!阿里卷成这样?不吃饭了,上厕所、团建都要聊工作,人均上厕所小于一天三次...
    垃圾收集器与内存分配策略
    JavaEE-多线程-锁
    【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(5月26日论文合集)
    30 天 Pandas 挑战 Day16:reset_index()将结果从 Series转为DataFrame
  • 原文地址:https://blog.csdn.net/qq_35629563/article/details/133499112