合并PDF文件
用Python合并多个PDF文件可以吗?
假设可以,我想再深入一点。我希望能遍历一个文件夹里的所有文件,然后重复这个操作。
我可能有点贪心,但能不能在合并时排除掉每个PDF里都有的一页(因为我的报告生成总是会多出一页空白页)?
15 个回答
合并目录中的所有PDF文件
把你想合并的PDF文件放到一个文件夹里。然后运行这个程序。最后你会得到一个新的PDF文件,里面包含了所有合并后的内容。
import os
from PyPDF2 import PdfMerger
x = [a for a in os.listdir() if a.endswith(".pdf")]
merger = PdfMerger()
for pdf in x:
merger.append(open(pdf, 'rb'))
with open("result.pdf", "wb") as fout:
merger.write(fout)
我今天该如何写出上面的代码
from glob import glob
from PyPDF2 import PdfMerger
def pdf_merge():
''' Merges all the pdf files in current directory '''
merger = PdfMerger()
allpdfs = [a for a in glob("*.pdf")]
[merger.append(pdf) for pdf in allpdfs]
with open("Merged_pdfs.pdf", "wb") as new_file:
merger.write(new_file)
if __name__ == "__main__":
pdf_merge()
文件连接
from pypdf import PdfMerger
pdfs = ['file1.pdf', 'file2.pdf', 'file3.pdf', 'file4.pdf']
merger = PdfMerger()
for pdf in pdfs:
merger.append(pdf)
merger.write("result.pdf")
merger.close()
如果你想的话,可以传递文件句柄而不是文件路径。
文件合并
如果你想更精确地控制合并,可以使用 merge
方法,这样你可以指定输出文件中的插入点,也就是说你可以把页面插入到文件的任何位置。append
方法可以看作是一个在文件末尾插入的 merge
。
例如:
merger.merge(2, pdf)
这里我们把整个PDF插入到输出文件中,但插入在第2页。
页面范围
如果你想控制从特定文件中添加哪些页面,可以使用 append
和 merge
的 pages
关键字参数,传递一个元组,格式为 (start, stop[, step])
(就像普通的 range
函数)。
例如:
merger.append(pdf, pages=(0, 3)) # first 3 pages
merger.append(pdf, pages=(0, 6, 2)) # pages 1,3, 5
如果你指定了一个无效的范围,你会得到一个 IndexError
错误。
注意:为了避免文件保持打开状态,当合并文件写入完成后,应该调用 PdfMerger
的 close 方法。这可以确保所有文件(输入和输出)及时关闭。可惜的是,PdfMerger
没有实现为上下文管理器,所以我们不能使用 with
关键字,这样就可以避免显式调用关闭方法,并获得一些简单的异常安全。
你也可以看看 pdfly cat
命令,这是 pypdf 开发者提供的。这样你可能完全不需要写代码。
pypdf 的文档中还 包含 一些示例代码,演示了如何合并。
PyMuPdf
另一个值得关注的库是 PyMuPdf。合并同样简单。
从命令行:
python -m fitz join -o result.pdf file1.pdf file2.pdf file3.pdf
以及从代码:
import fitz
result = fitz.open()
for pdf in ['file1.pdf', 'file2.pdf', 'file3.pdf']:
with fitz.open(pdf) as mfile:
result.insert_pdf(mfile)
result.save("result.pdf")
有很多选项,详细信息可以在项目的 wiki 中找到。
注意:在旧版本的 PyMuPDF 中,insert_pdf
是 insertPDF
。
这是一个用纯Python写的库,主要用来处理PDF文件。它可以做到:
- 将文档按页拆分,
- 将文档按页合并,
(还有很多其他功能)
下面是一个可以同时在这两个版本上运行的示例程序。
#!/usr/bin/env python
import sys
try:
from PyPDF2 import PdfReader, PdfWriter
except ImportError:
from pyPdf import PdfFileReader, PdfFileWriter
def pdf_cat(input_files, output_stream):
input_streams = []
try:
# First open all the files, then produce the output file, and
# finally close the input files. This is necessary because
# the data isn't read from the input files until the write
# operation. Thanks to
# https://stackoverflow.com/questions/6773631/problem-with-closing-python-pypdf-writing-getting-a-valueerror-i-o-operation/6773733#6773733
for input_file in input_files:
input_streams.append(open(input_file, 'rb'))
writer = PdfWriter()
for reader in map(PdfReader, input_streams):
for n in range(len(reader.pages)):
writer.add_page(reader.pages[n])
writer.write(output_stream)
finally:
for f in input_streams:
f.close()
output_stream.close()
if __name__ == '__main__':
if sys.platform == "win32":
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
pdf_cat(sys.argv[1:], sys.stdout)