使用 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的使用

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

运行结果

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

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

运行结果

3、读取txt文件

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

 运行结果

D:\SoftProgram\JetBrains\anaconda3_202303\envs\py3_6_for_TimeSeries\python.exe E:\program\python\gitTemp\pdf\test\03_read_txt.py 
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
['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']
f.closed= True进程已结束,退出代码0

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

# https://blog.csdn.net/kobeyu652453/article/details/106876829
import pypdfwk_in_file_name = 'PythonTutorial.pdf'
writer = pypdf.PdfWriter()
input1 = open(wk_in_file_name, "rb")
writer.append(input1)f = open('dir.txt', 'r', encoding='utf8')
lines = f.readlines()  # 读取所有行
num_lines = len(lines)  # 标题的总个数txt = []
for line in lines:line = line.strip()  # 去掉末尾的'\n'pline = line.split(' ')  # 根据line中' '进行分割level = line.count('.')  # 有n个'.'就是n+1级标题if level == 0:bookmark_parent_0 = writer.add_outline_item(title=pline[0] + pline[1], page_number=int(pline[-1]), parent=None)elif level == 1:bookmark_parent_1 = writer.add_outline_item(title=pline[0] + pline[1], page_number=int(pline[-1]),parent=bookmark_parent_0)else:writer.add_outline_item(title=pline[0] + pline[1], page_number=int(pline[-1]), parent=bookmark_parent_1)# Write to an output PDF document
output = open('04_'+wk_in_file_name, "wb")
writer.write(output)# Close File Descriptors
writer.close()
output.close()f.close()  # 关闭文件
print('f.closed=', f.closed)

运行结果 

 5、添加偏置

# https://blog.csdn.net/kobeyu652453/article/details/106876829
import pypdfwk_in_file_name = 'PythonTutorial.pdf'
writer = pypdf.PdfWriter()
input1 = open(wk_in_file_name, "rb")
writer.append(input1)f = open('dir.txt', 'r', encoding='utf8')
lines = f.readlines()  # 读取所有行
num_lines = len(lines)  # 标题的总个数
offset = 5  # 添加偏置txt = []
bookmark_parent_0 = None
bookmark_parent_1 = Nonefor line in lines:line = line.strip()  # 去掉末尾的'\n'pline = line.split(' ')  # 根据line中' '进行分割level = line.count('.')  # 有n个'.'就是n+1级标题page_title = pline[0] + ' ' + pline[1]page_num = int(pline[-1]) + offsetif level == 0:bookmark_parent_0 = writer.add_outline_item(title=page_title, page_number=page_num, parent=None)elif level == 1:bookmark_parent_1 = writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_0)else:writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_1)print(line.strip())print(txt)# Write to an output PDF document
output = open('05_' + wk_in_file_name, "wb")
writer.write(output)# Close File Descriptors
writer.close()
output.close()f.close()  # 关闭文件
print('f.closed=', f.closed)

运行结果:

 

6、dir中没有页码的情况

# https://blog.csdn.net/kobeyu652453/article/details/106876829
import pypdfwk_in_file_name = 'PythonTutorial.pdf'
writer = pypdf.PdfWriter()
input1 = open(wk_in_file_name, "rb")
writer.append(input1)f = open('dir.txt', 'r', encoding='utf8')
lines = f.readlines()  # 读取所有行
num_lines = len(lines)  # 标题的总个数
offset = 5  # 添加偏置txt = []
bookmark_parent_0 = None
bookmark_parent_1 = Nonefor line in lines:line = line.strip()  # 去掉末尾的'\n'pline = line.split(' ')  # 根据line中' '进行分割level = line.count('.')  # 有n个'.'就是n+1级标题page_title = pline[0] + ' ' + pline[1]page_num = offsetif level == 0:bookmark_parent_0 = writer.add_outline_item(title=page_title, page_number=page_num, parent=None)elif level == 1:bookmark_parent_1 = writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_0)else:writer.add_outline_item(title=page_title, page_number=page_num, parent=bookmark_parent_1)print(line.strip())print(txt)# Write to an output PDF document
output = open('06_' + wk_in_file_name, "wb")
writer.write(output)# Close File Descriptors
writer.close()
output.close()f.close()  # 关闭文件
print('f.closed=', f.closed)

运行结果

参考

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/92915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

91、Redis - 事务 与 订阅-发布 相关的命令 及 演示

★ 事务相关的命令 Redis事务保证事务内的多条命令会按顺序作为整体执行,其他客户端发出的请求绝不可能被插入到事务处理的中间, 这样可以保证事务内所有命令作为一个隔离操作被执行。 Redis事务同样具有原子性,事务内所有命令要么全部被执…

年度顶级赛事来袭:2023 CCF大数据与计算智能大赛首批赛题上线!

久等了! 大数据与人工智能领域年度顶级盛事——2023 CCF大数据与计算智能大赛——首批赛题已上线,大赛火力全开,只等你来挑战! 大赛介绍 CCF大数据与计算智能大赛(CCF Big Data & Computing Intelligence Contes…

深入学习git

1、git原理及整体架构图 一些常用的命令 git add . 或 git add src/com/ygl/hello/hello.java 指定文件 git commit . 或 git commit src/com/ygl/hello/hello.java 指定文件 git push origin 分支名称 2、git stash的应用场景 场景一:你正在当前分支A开发&…

多目标平衡黏菌算法(MOEOSMA)求解八个现实世界受约束的工程问题

目录 1 受约束的工程问题 1.1 减速器设计问题(Speed reducer design problem) 1.2 弹簧设计问题(Spring design problem) 1.3 静压推力轴承设计问题(Hydrostatic thrust bearing design problem) 1.4 振动平台设计问题(Vibrating platform design problem) 1.5 汽车侧面碰…

云安全【阿里云ECS攻防】

关于VPC的概念还请看:记录一下弹性计算云服务的一些词汇概念 - 火线 Zone-安全攻防社区 一、初始化访问 1、元数据 1.1、SSRF导致读取元数据 如果管理员给ECS配置了RAM角色,那么就可以获得临时凭证 如果配置RAM角色 在获取ram临时凭证的时候&#xff…

铁道货车通用技术条件

声明 本文是学习GB-T 5600-2018 铁道货车通用技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 90 mm90 mm。 B.2 制造要求 B.2.1 车体钢结构组成后: a) 敞车钢质侧、端板的平面度公差应小于或等于15 mm/m; 压型侧、端板的平面度…

python生成中金所期权行权价

参考沪深300股指期权的合约表,写一个工具函数: 使用方法 def get_format_option_gap(value: float, deviation: int 0): # 根据中证1000指数获取点位"""根据标准的行权价,生成不同档位的期权列表,适合中金所:…

[红明谷CTF 2021]write_shell %09绕过过滤空格 ``执行

目录 1.正常短标签 2.短标签配合内联执行 看看代码 <?php error_reporting(0); highlight_file(__FILE__); function check($input){if(preg_match("/| |_|php|;|~|\\^|\\|eval|{|}/i",$input)){ 过滤了 木马类型的东西// if(preg_match("/| |_||php/&quo…

最新AI智能创作系统源码V2.6.2/AI绘画系统/支持GPT联网提问/支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…

验证曲线(validation_curve)项目实战

验证曲线 validation_curve 一、简介 validation_curve验证曲线&#xff0c;可确定不同参数值下的训练和测试分数 根据指定参数的不同值计算估计器的得分 这与使用一个参数的网格搜索类似。不过&#xff0c;这也会计算训练得分&#xff0c;只是一个用于绘制结果的工具。 二、…

【AI视野·今日Robot 机器人论文速览 第四十五期】Mon, 2 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Mon, 2 Oct 2023 Totally 42 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Learning Decentralized Flocking Controllers with Spatio-Temporal Graph Neural Network Authors Siji Chen, Yanshen Sun, …

R语言中更改R包安装路径

看到这些包下载到我的C盘&#xff0c;我蛮不爽的&#xff1a; 所以决定毫不犹豫的改到D盘&#xff1a; 首先&#xff0c;我们需要在RStudio中新建一个初始启动文件&#xff1a; file.edit(~/.Rprofile) 然后去你喜欢的环境新建一个文件夹存放安装的包的位置&#xff0c;我喜欢…

uboot启动流程-涉及board_init_f 函数

一. uboot启动流程 _main 函数中会调用 board_init_f 函数&#xff0c;本文简单分析一下 board_init_f 函数。 二. board_init_f 函数 board_init_f 函数主要有两个工作&#xff1a; (1) 初始化一系列外设&#xff0c;比如串口、定时器&#xff0c;或者打印一些消息等。…

动态规划算法(2)--最大子段和与最长公共子序列

目录 一、最大子段和 1、什么是最大子段和 2、暴力枚举 3、分治法 4、动态规划 二、最长公共子序列 1、什么是最长公共子序列 2、暴力枚举法 3、动态规划法 4、完整代码 一、最大子段和 1、什么是最大子段和 子段和就是数组中任意连续的一段序列的和&#xff0c;而…

阿里云服务器方升架构、自研硬件、AliFlash技术创新

阿里云服务器技术创新&#xff1a;服务器方升架构及自研硬件、自研存储硬件AliFlash和阿里云异构计算加速平台&#xff0c;阿里云百科分享阿里云服务器有哪些技术创新&#xff1a; 目录 服务器技术创新 服务器方升架构及自研硬件 自研存储硬件AliFlash 阿里云异构计算加速…

【Excel】快速提取某个符号前面的数据内容

【问题描述】 在使用excel整理数据过程中&#xff0c;经常与需要调整数据后&#xff0c;进行使用。 例如凭证导出后&#xff0c;科目列是包含科目编码和科目名称的。 但由于要将数据复制到其他的导入模板上使用&#xff0c;对应的模板只需要科目编码&#xff0c;不需要科目名称…

常说的I2C协议是干啥的(电子硬件)

I2C&#xff08;Inter-Integrated circuit&#xff09;协议是电子传输信号中常用的一种协议。 它是一种两线式串行双向总线&#xff0c;用于连接微控制器和外部设备&#xff0c;也因为它所需的引脚数只需要两条&#xff08;CLK和DATA&#xff09;&#xff0c;硬件实现简单&…

Acwing 906. 区间分组

Acwing 906. 区间分组 知识点题目描述思路讲解代码展示 知识点 贪心 题目描述 思路讲解 这段代码是用来维护一个最小堆&#xff0c;以确保右边界不相交的区间被正确地保留在堆中。让我详细解释这段代码&#xff1a; heap.empty()&#xff1a;这个条件检查最小堆 heap 是否为…

【牛客网】JZ39 数组中出现次数超过一半的数字

题目 思路 思路1 将数组排序,再保证有结果的情况下,此时数组中间的数字就是想要的结果 思路2 在保证有结果的情况下,此时数组的的众数是数组长度的一半以上 所以我们可以通过抵消的做法来找到最终的结果 我们可以从头遍历这个数组,如果两个数不相同,则消去这两个数,最坏的…

Bug:elementUI样式不起作用、Vue引入组件报错not found等(Vue+ElementUI问题汇总)

前端问题合集&#xff1a;VueElementUI 1. Vue引用Element-UI时&#xff0c;组件无效果解决方案 前提&#xff1a; 已经安装好elementUI依赖 //安装依赖 npm install element-ui //main.js中导入依赖并在全局中使用 import ElementUI from element-ui Vue.use(ElementUI)如果此…