是否有可能,使用Python,合并单独的PDF文件?

假设是这样,我需要进一步扩展它。我希望循环通过目录中的文件夹,并重复此过程。

我可能是得过其实了,但是否可以排除每个pdf文件中包含的一页(我的报告生成总是创建一个额外的空白页)。


当前回答

可以使用PyPdf2s PdfMerger类。

文件连接

您可以使用append方法简单地连接文件。

from PyPDF2 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()

如果需要,可以传递文件句柄而不是文件路径。

文件合并

如果您希望对合并进行更细粒度的控制,可以使用PdfMerger的合并方法,该方法允许您在输出文件中指定插入点,这意味着您可以在文件中的任何位置插入页面。可以将append方法看作是一个合并,其中插入点是文件的末尾。

e.g.

merger.merge(2, pdf)

在这里,我们将整个pdf插入到输出中,但在第2页。

页面范围

如果希望控制从特定文件中追加哪些页面,可以使用pages关键字参数append和merge,以(start, stop[, step])的形式传递一个元组(类似于常规的range函数)。

e.g.

merger.append(pdf, pages=(0, 3))    # first 3 pages
merger.append(pdf, pages=(0, 6, 2)) # pages 1,3, 5

如果你指定了一个无效的范围,你会得到一个IndexError。

注意:另外,为了避免文件处于打开状态,当合并文件被写入时,应该调用pdffilemergeners关闭方法。这确保及时关闭所有文件(输入和输出)。遗憾的是pdffil急诊没有作为上下文管理器实现,所以我们可以使用with关键字,避免显式的关闭调用,并获得一些简单的异常安全。

您可能还想看看作为pypdf2的一部分提供的pdfcat脚本。您可以潜在地避免完全编写代码的需要。

PyPdf2 github还包括一些演示合并的示例代码。

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")

有大量的选项,详细说明在项目维基。

注意:在旧版本的PyMuPDF中insert_pdf为insertPDF

其他回答

合并目录下的所有pdf文件

把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()

使用字典以获得更大的灵活性(例如sort, dedup):

import os
from PyPDF2 import PdfFileMerger
# use dict to sort by filepath or filename
file_dict = {}
for subdir, dirs, files in os.walk("<dir>"):
    for file in files:
        filepath = subdir + os.sep + file
        # you can have multiple endswith
        if filepath.endswith((".pdf", ".PDF")):
            file_dict[file] = filepath
# use strict = False to ignore PdfReadError: Illegal character error
merger = PdfFileMerger(strict=False)

for k, v in file_dict.items():
    print(k, v)
    merger.append(v)

merger.write("combined_result.pdf")

def pdf_merger(路径): """将pdf文件合并为一个pdf""" "

import logging
logging.basicConfig(filename = 'output.log', level = logging.DEBUG, format = '%(asctime)s %(levelname)s %(message)s' )

try:
    import glob, os
    import PyPDF2
    
    os.chdir(path)
    
    pdfs = []
    
    for file in glob.glob("*.pdf"):
        pdfs.append(file)
        
    if len(pdfs) == 0:
        logging.info("No pdf in the given directory")
        
    else:
        merger = PyPDF2.PdfFileMerger()
        
        for pdf in pdfs:
            merger.append(pdf)
            
        merger.write('result.pdf')
        merger.close()
        
except Exception as e:
    logging.error('Error has happened')
    logging.exception('Exception occured' + str(e))

使用正确的python解释器:

conda activate py_envs

pip install PyPDF2

Python代码:

from PyPDF2 import PdfMerger

#set path files
import os
os.chdir('/ur/path/to/folder/')
cwd = os.path.abspath('')
files = os.listdir(cwd)

def merge_pdf_files():
    merger = PdfMerger()
    pdf_files = [x for x in files if x.endswith(".pdf")]
    [merger.append(pdf) for pdf in pdf_files]
    with open("merged_pdf_all.pdf", "wb") as new_file:
        merger.write(new_file)

if __name__ == "__main__":
    merge_pdf_files()

pdfrw库可以很容易地做到这一点,假设您不需要保存书签和注释,并且您的pdf文件没有加密。Cat.py是一个示例拼接脚本,而子集.py是一个示例页面子集脚本。

串联脚本的相关部分——假设input是一个输入文件名列表,outfn是一个输出文件名:

from pdfrw import PdfReader, PdfWriter

writer = PdfWriter()
for inpfn in inputs:
    writer.addpages(PdfReader(inpfn).pages)
writer.write(outfn)

正如你所看到的,省略最后一页是很容易的,例如:

    writer.addpages(PdfReader(inpfn).pages[:-1])

免责声明:我是pdfrw的主要作者。