PDF Dir(ectory) Generator,PDF 目录生成器, 是基于 wxpython 和 PyPDF2 开发的一个简易的 GUI 程序,主要功能是给未添加书签的 PDF 添加目录书签。
首先必须保证 Python 运行版本不低于 3.7, 推荐使用的 Python 版本为 3.9.12.
运行本程序需要使用两个模块: PyPDF2 和 wxpython, 我们可以通过 pip
进行安装.
如果你不需要 GUI 界面,可以只安装 PyPDF2
.
pip install PyPDF2
pip install wxPython
安装完 PyPDF2 需要对 _writer.py
的 get_outline_roor()
函数进行修改, 不然运行时可能会如下报错:
File "C:\Users\q2799\.conda\envs\py36\lib\site-packages\PyPDF2\_writer.py", line 1195, in addBookmark
title, pagenum, parent, color, bold, italic, fit, *args
File "C:\Users\q2799\.conda\envs\py36\lib\site-packages\PyPDF2\_writer.py", line 1174, in add_bookmark
parent = self.get_outline_root()
File "C:\Users\q2799\.conda\envs\py36\lib\site-packages\PyPDF2\_writer.py", line 1008, in get_outline_root
idnum = self._objects.index(outline) + 1
ValueError: {'/Type': '/Outlines', '/First': IndirectObject(1006, 0, 3019818315728), '/Count': 493, '/Last': IndirectObject(1498, 0, 3019818315728)} is not in list
根据报错信息,找到 _writer.py
的 get_outline_roor()
的位置(不同版本的 PyPDF2 可能的位置不一样),修改如下:
def get_outline_root(self) -> TreeObject:
if CO.OUTLINES in self._root_object:
# TABLE 3.25 Entries in the catalog dictionary
outline = cast(TreeObject, self._root_object[CO.OUTLINES])
try:
idnum = self._objects.index(outline) + 1
except ValueError:
if not isinstance(outline, TreeObject):
def _walk(node):
node.__class__ = TreeObject
for child in node.children():
_walk(child)
_walk(outline)
outline_ref = self._add_object(outline)
self._add_object(outline_ref.get_object())
self._root_object[NameObject('/Outlines')] = outline_ref
idnum = self._objects.index(outline) + 1
outline_ref = IndirectObject(idnum, 0, self)
assert outline_ref.get_object() == outline
else:
outline = TreeObject()
outline.update({})
outline_ref = self._add_object(outline)
self._root_object[NameObject(CO.OUTLINES)] = outline_ref
return outline
运行之前,推荐先阅读这篇博客, 在运行之前我们需要准备好:
Offset
(一般是目录页的最后一页的页码)格式化目录
python .\dirFormat.py <dir_input_path> [<-option> <params>]
参数 | 选项 | 说明 |
---|---|---|
DIR_INPUT_PATH | 必需参数 | 目录文件的路径 |
DIR_FORMAT_PATH | -o | 格式化目录的输出文件夹 |
DIR_LOG_PATH | -l | 格式化目录文件的输出日志存放文件夹 |
DELIMITER | -d | 单词分隔符 |
PREFIX | -p | 目录文件每行的前缀 |
PRE_LEVEL | -pl | 预定义级别 |
PRE_TITLE | -pt | 预定义标题, 使用 ; 隔开 |
【例子】
python .\dirFormator.py test/test_dir.txt -pl 2 -pt 参考文献
输出结果:
---------------------------- Format Dir -----------------------------------
运行时间: 2022-10-05 15:45:33
目录源文件路径: test/test_dir.txt
格式化目录路径:
日志路径:
单词分隔符:
级别标志符: .
前缀:
预定义级别: 2
预定义标题: 参考文献
---------------------------------------------------------------------------
[Line 29] 缩略语对照表 395 ==> 无法判断级别信息
[Line 30] 符号表 398 ==> 无法判断级别信息
[Line 31] 参考书目 401 ==> 无法判断级别信息
[Line 32] 索引 415 ==> 无法判断级别信息
---------------------------------------------------------------------------
Dir-log Path : test/test_dir.log
Dir format Path : test/test_dir_format.txt
---------------------------------- Done! ----------------------------------
修改目录
格式程序的同时会进行简单的检查,并输出日志信息. 可以根据这些信息对格式化后的目录进一步的修改.
生成目录
修改完后的目录文件,作为这一步的输入目录文件;同时需要删除待添加书签的 PDF 原先的书签。 然后执行指令:
python .\pdfDirGenerator.py <dir_input_path> <pdf_input_path> [<-option> <params>]
参数 | 选项 | 说明 |
---|---|---|
DIR_INPUT_PATH | 必需参数 | 目录文件的路径 |
PDF_INPUT_PATH | 必须参数 | 待添加书签的PDF路径 |
PDF_OUTPUT_PATH | -o | PDF输出目录 |
DELIMITER | -d | 单词分隔符 |
PREFIX | -p | 目录文件每行的前缀 |
OFFSET | -O | 页码偏移量 |
【例子】
python .\pdfDirGenerator.py test\format\pdg_normal_dir.txt test\pdg_test.pdf -O 5
输出结果:
--------------------------- Adding the bookmark ---------------------------
PDF input path: test\pdg_test.pdf
PDF output path:
Dir path: test\format\pdg_normal_dir.txt
Offset: 5
Prefix:
Delimiter:
---------------------------------------------------------------------------
[ 1/ 23 finished] level: 0, title: 第1章 计算机网络概论, page: 6
[ 2/ 23 finished] level: 1, title: 1.1 计算机网络的形成与发展, page: 6
[ 3/ 23 finished] level: 2, title: 1.1.1 分组交换技术的研究, page: 6
[ 4/ 23 finished] level: 2, title: 1.1.2 互联网的形成, page: 9
[ 5/ 23 finished] level: 2, title: 1.1.3 互联网的高速发展, page: 13
[ 6/ 23 finished] level: 2, title: 1.1.4 移动互联网的发展 , page: 14
[ 7/ 23 finished] level: 1, title: 1.2 计算机网络定义与分类, page: 17
[ 8/ 23 finished] level: 1, title: 1.3 各种类型网络 y 的特点, page: 20
[ 9/ 23 finished] level: 2, title: 1.3.1 广域网, page: 20
[ 10/ 23 finished] level: 2, title: 1.3.2 城域网, page: 23
[ 11/ 23 finished] level: 2, title: 1.3.3 局域网, page: 25
[ 12/ 23 finished] level: 0, title: 小结, page: 26
[ 13/ 23 finished] level: 1, title: 习题, page: 26
[ 14/ 23 finished] level: 0, title: 第2章 物理层, page: 27
[ 18/ 23 finished] level: 1, title: 2.2 数据通信 x 的基本概念 , page: 31
[ 19/ 23 finished] level: 2, title: 2.2.1 测试, page: 32
[ 20/ 23 finished] level: 3, title: 2.2.1.1 测试, page: 33
[ 21/ 23 finished] level: 0, title: 小结, page: 34
[ 22/ 23 finished] level: 1, title: 习题, page: 34
[ 23/ 23 finished] level: 0, title: 附录, page: 35
---------------------------------------------------------------------------
Save: test\pdg_test(书签).pdf
---------------------------------- Done! ----------------------------------
运行 main.py
启动 GUI 界面
python .\main.py
演示
主界面
参数设置
参数说明
这里通常需要设置的是 Offset 以及 Pre-title,设置完成后记得点击 Finish
。
除了这种设置方式外,还支持直接导入配置文件(文件后缀名为 .conf
):
配置文件
###########################################################################
#
# 这是一个配置文件, 以行为基本单元, 可以分为注释行, 赋值行和空行.
#
# 注释行以字符 '#' 开头, 程序会忽略以'#'开头的行; 行首直接回车,则是空行; 注释行
# 和空行可以提高配置文件的可读性.
#
# 赋值行的格式为: 字段名 = 值:
# 1. "值"可以修改, 但不要修改"字段名";
# 2. "="两边的空格可有可无, 数量没有限制;
#
###########################################################################
# str, 待添加书签的PDF路径
PDF_INPUT_PATH = "C:\Users\q2799\Project\PDFDirGenerator2\test\pdg_test.pdf"
# str, 目录文件的路径
DIR_INPUT_PATH = "C:\Users\q2799\Project\PDFDirGenerator2\test\pdg_normal_dir.txt"
# int, 页码偏移量, 通常是PDF目录页最后一页的页码
OFFSET = 5
# char, 目录文件每行的前缀, 生成书签时用于判断书签的级别
PREFIX = "\t"
# char, 单词分隔符, 通常是空格, 不建议修改
DELIMITER = " "
# char, 级别标志符, 格式化书签时用于判断书签的级别
LEVEL_MARKER = "."
# int, 预定义级别
PRE_LEVEL = 2
# str, 预定义标题, 使用';'隔开
PRE_TITLE = "本章小结;习题"
# str, 格式化目录文件的输出日志存放文件夹,留空则与原目录在同一文件夹
DIR_LOG_PATH = "C:\Users\q2799\Project\PDFDirGenerator2\test\log"
# str, 格式化目录的输出文件夹,留空则与原目录在同一文件夹
DIR_FORMAT_PATH = "C:\Users\q2799\Project\PDFDirGenerator2\test\format"
# PDF输出目录, 留空会根据输入PDF名自动生成
PDF_OUTPUT_PATH = "C:\Users\q2799\Project\PDFDirGenerator2\test\outpdf"
# int, 是否只显示目录日志
IS_PRINT_ACTICE_ONLY = 0
# int, 生成日志前默认先进行格式化
IS_FORMAT_DIR_FIRST = 1
# int, 是否打印生成书签过程中的信息
IS_PRINT_PROCESS = 1
dirFormator.py
格式化目录脚本pdfDirGenerator
PDF 目录生成脚本main.py
GUI 运行脚本utils.py
存放一些公共函数和全局变量wxb_*.py
通过 wxFormBuilder 自动生成的脚本(用于图像界面的设计)
mainFrame.py
主窗口runningDialog.py
运行弹窗settingsDialog.py
设置弹窗aboutDialog
关于弹窗assets\
存放一些图片等附件design_gui\
存放 wxFormBuilder 工程文件,可用 wxFormBuilder 打开test\
存放一些测试数据
conf\
包含一个配置文件 pdg_settings.conf
format\
包含一个格式化目录 pdg_normal_dir.txt
log\
包含格式化目录的日志信息 pdg_normal_dir.log
outpdf\
存放运行结果 pdg_test(书签).pdf
pdg_test.pdf
测试 PDF*_dir.txt
测试目录文件PDFDirGenerator2
├─ aboutDialog.py
├─ assets
├─ blog.md
├─ design_gui
│ ├─ noname.cpp
│ ├─ noname.h
│ └─ pdg2.fbp
├─ dirFormator.py
├─ main.py
├─ mainFrame.py
├─ pdfDirGenerator.py
├─ README.md
├─ runningDialog.py
├─ settingsDialog.py
├─ test
│ ├─ conf
│ │ └─ pdg_settings.conf
│ ├─ format
│ │ └─ pdg_normal_dir.txt
│ ├─ log
│ │ └─ pdg_normal_dir.log
│ ├─ outpdf
│ │ └─ pdg_test(书签).pdf
│ ├─ pdg_invalidnum_dir.txt
│ ├─ pdg_normal_dir.txt
│ ├─ pdg_test.pdf
│ └─ test_dir.txt
├─ utils.py
├─ wxb_mainFrame.py
├─ wxb_runningDialog.py
└─ wxb_settingsDialog.py
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。