[日常] 使用PyPDF2合并多个PDF文件,并且加上文件名作为书签

Reference:
这个脚本是在某个某个脚本的基础上改的,但是链接找到不到了,如果找到了再补上引用
Problem solve : PyPDF2 编码问题 PyPDF2.utils.PdfReadError Illegal character in Name Object_kkcoder-CSDN博客_pypdf2.utils.pdfreaderror_ eof marker not found

1.使用之前

因为PyPDF2自己的问题,在输出中文编码的pdf时会报错。所以使用之前需要修改PyPDF2库。
在命令行输入

pip show PyPDF2

查看PyPDF2库的安装位置Location: xxxxx,打开这个位置下的PyPDF2文件夹。

1.1 修改generic.py

将generic.py第488行附近的

if not pdf.strict:
	warnings.warn("Illegal character in Name Object", utils.PdfReadWarning)
	return NameObject(name)

替换为(用#MODIFIED#做了标记)(注意缩进)

if not pdf.strict:
	warnings.warn("Illegal character in Name Object", utils.PdfReadWarning)
	#MODIFIED
	#return NameObject(name)
	return NameObject(name.decode('gbk'))
	#END MODIFIED

1.2 修改utils.py

将utils.py第237行附近的

else:
	r = s.encode('latin-1')
	if len(s) < 2:
	    bc[s] = r
	return r

替换为

else:
	#MODIFIED
	# r = s.encode('latin-1')
	# if len(s) < 2:
	#     bc[s] = r
	# return r
	try:
	    r = s.encode('latin-1')
	except Exception as e:
	    r = s.encode('utf-8')
	if len(s) < 2:
	    bc[s] = r
	return r
	#END MODIFIED

2. 脚本

import os,sys,codecs
from PyPDF2 import PdfFileReader,PdfFileWriter,PdfFileMerger

#path + name = filename

inputFilenames = []
outputFilename = ""

def getInputFiles():
    global inputFilenames
    userInput = input("输入需要合并的PDF文件路径,多个路径用空格隔开。建议拖入一个文件加一个空格,因为拖入多个有顺序问题\n")
    inputFilenames = userInput.split(' ')
    print("程序接受到的文件如下")
    for filename in inputFilenames:
        print(filename)
    print('\n')

def getOutputFilename():
    global outputFilename
    userInput = input("将会保存在桌面上。输入保存为的文件名(需要自己输入.pdf)\n")
    #os.path.expanduser('~')可以获取 用户目录
    #如果要输出到别的位置,可以自己修改代码
    outputFilename = os.path.join(os.path.expanduser('~'),'Desktop',userInput)
    print("程序收到的保存路径为:%s"%outputFilename)

def merge():
    global inputFilenames,outputFilename
    # 注意此处需要修改PyPDF2的源码,不然编码中文会报错
    # ref : https://blog.csdn.net/kmesky/article/details/102695520
    # 并且需要关闭严格模式(代码里的strict = False)
    merger = PdfFileMerger(strict = False)
    if len(inputFilenames) == 0:
        print("没有文件哦")
        sys.exit()
    for filename in inputFilenames:
        file = codecs.open(filename,'rb')
        file_read = PdfFileReader(file)
        if file_read.isEncrypted:
            print("%s是加密文件,将跳过"%filename)
            file.close()
            continue
        #os.path.splittext(filename)可以分离全路径的路径部分(含文件名)和扩展名(.xx)
        #os.path.basename(filename)可以从全路径中分离出最后一段
        short_name = os.path.basename(os.path.splitext(filename)[0])
        #增加文件,书签名为short_name,导入子pdf的所有书签
        merger.append(file_read,bookmark = short_name,import_bookmarks=True)
        print("已加入文件%s"%filename)
        file.close()
    merger.write(outputFilename)
    merger.close()
    print("已保存为%s"%outputFilename)

if __name__ == '__main__':
    getInputFiles()
    getOutputFilename()
    merge()

3. 使用方法

使用python pdfmerger.py运行
输入文件时,可以将文件拖入到命令行窗口中,会自动写上路径。不建议拖入多个文件,因为拖入的顺序和之后合并的顺序、书签的顺序有关系。
注意不同文件的路径之间需要加上空格隔开。
如果不希望保存在桌面,可以自己修改getOutputFilename()函数。

输入需要合并的PDF文件路径,多个路径用空格隔开。建议拖入一个文件加一个空格,因为拖入多个有顺序问题
D:\《第一篇》导学.pdf D:\《第二篇》导学.pdf D:\《第三篇》导学.pdf
程序接受到的文件如下
D:\《第一篇》导学.pdf
D:\《第二篇》导学.pdf
D:\《第三篇》导学.pdf


将会保存在桌面上。输入保存为的文件名(需要自己输入.pdf)
merge.pdf
程序收到的保存路径为:C:\Users\Someone\Desktop\merge.pdf
已加入文件D:\《第一篇》导学.pdf
已加入文件D:\《第二篇》导学.pdf
已加入文件D:\《第三篇》导学.pdf
PdfReadWarning: Illegal character in Name Object [generic.py:489]
已保存为C:\Users\Someone\Desktop\merge.pdf

你可能感兴趣的:(杂谈)