207

Pythonを使用して、別々のPDFファイルをマージすることは可能ですか?

そうだとすれば、これをもう少し拡張する必要があります。ディレクトリ内のフォルダをループして、この手順を繰り返すことを望んでいます。

そして、私は運を押しているかもしれませんが、各PDFに含まれているページを除外することは可能です(私のレポート生成は常に余分な空白のページを作成します)。

4

13 に答える 13

341

PyPdf2PdfMergerクラスを使用できます。

ファイルの連結

このメソッドを使用すると、ファイルを簡単に連結できます。append

from PyPDF2 import PdfFileMerger

pdfs = ['file1.pdf', 'file2.pdf', 'file3.pdf', 'file4.pdf']

merger = PdfFileMerger()

for pdf in pdfs:
    merger.append(pdf)

merger.write("result.pdf")
merger.close()

必要に応じて、ファイルパスの代わりにファイルハンドルを渡すことができます。

ファイルのマージ

マージをよりきめ細かく制御したい場合は、のmergeメソッドがPdfMergerあります。これを使用すると、出力ファイルに挿入ポイントを指定できます。つまり、ファイル内の任意の場所にページを挿入できます。このメソッドは、挿入ポイントがファイルの終わりであるappendと考えることができます。merge

例えば

merger.merge(2, pdf)

ここでは、PDF全体を出力に挿入しますが、2ページ目にあります。

ページ範囲

特定のファイルから追加されるページを制御する場合は、 andのpagesキーワード引数を使用して、フォームにタプルを渡すことができます(通常の関数のように)。appendmerge(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

注:ファイルが開いたままにPdfFileMergerならないように、マージされたファイルが書き込まれたときにscloseメソッドを呼び出す必要があることにも注意してください。これにより、すべてのファイルがタイムリーに閉じられます(入力と出力)。コンテキストマネージャーとして実装されていないのは残念です。そのPdfFileMergerため、キーワードを使用してwith、明示的なclose呼び出しを回避し、簡単な例外安全性を得ることができます。

pdfcatpypdf2の一部として提供されているスクリプトも確認することをお勧めします。コードを書く必要性を完全に回避できる可能性があります。

PyPdf2 githubには、マージを示すサンプルコードも含まれています。

PyMuPdf

おそらく一見の価値があるもう1つのライブラリは、積極的に保守されているように見える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.insertPDF(mfile)
    
result.save("result.pdf")

たくさんのオプションがあり、プロジェクトwikiで詳しく説明されています。

于 2016-06-21T13:12:13.840 に答える
151

Pypdfまたはその後継のPyPDF2を使用します。

PDFツールキットとして構築されたPure-Pythonライブラリ。次のことができます。

  • ドキュメントをページごとに分割し、
  • ドキュメントをページごとにマージし、

(およびはるかに)

これは、両方のバージョンで動作するサンプルプログラムです。

#!/usr/bin/env python
import sys
try:
    from PyPDF2 import PdfFileReader, PdfFileWriter
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 = PdfFileWriter()
        for reader in map(PdfFileReader, input_streams):
            for n in range(reader.getNumPages()):
                writer.addPage(reader.getPage(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)
于 2010-08-09T22:40:53.067 に答える
32

dirに存在するすべてのpdfファイルをマージします

PDFファイルをディレクトリに配置します。プログラムを起動します。すべてのPDFがマージされた1つのPDFを取得します。

import os
from PyPDF2 import PdfFileMerger

x = [a for a in os.listdir() if a.endswith(".pdf")]

merger = PdfFileMerger()

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 PdfFileMerger



def pdf_merge():
    ''' Merges all the pdf files in current directory '''
    merger = PdfFileMerger()
    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()
于 2017-11-17T17:40:50.023 に答える
13

ブックマークや注釈を保持する必要がなく、PDFが暗号化されていない場合、ライブラリはこれを非常に簡単に行うことができ ますpdfrwcat.pyは連結スクリプトの例でありsubset.py、ページサブセット化スクリプトの例です。

連結スクリプトの関連部分は、inputs入力ファイル名のリストであり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著者です。

于 2017-04-02T00:04:57.367 に答える
9

Pythonを使用して、個別のPDFファイルをマージすることは可能ですか?

はい。

次の例では、1つのフォルダー内のすべてのファイルを1つの新しいPDFファイルにマージします。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from argparse import ArgumentParser
from glob import glob
from pyPdf import PdfFileReader, PdfFileWriter
import os

def merge(path, output_filename):
    output = PdfFileWriter()

    for pdffile in glob(path + os.sep + '*.pdf'):
        if pdffile == output_filename:
            continue
        print("Parse '%s'" % pdffile)
        document = PdfFileReader(open(pdffile, 'rb'))
        for i in range(document.getNumPages()):
            output.addPage(document.getPage(i))

    print("Start writing '%s'" % output_filename)
    with open(output_filename, "wb") as f:
        output.write(f)

if __name__ == "__main__":
    parser = ArgumentParser()

    # Add more options if you like
    parser.add_argument("-o", "--output",
                        dest="output_filename",
                        default="merged.pdf",
                        help="write merged PDF to FILE",
                        metavar="FILE")
    parser.add_argument("-p", "--path",
                        dest="path",
                        default=".",
                        help="path of source PDF files")

    args = parser.parse_args()
    merge(args.path, args.output_filename)
于 2014-03-31T16:41:53.397 に答える
3
from PyPDF2 import PdfFileMerger
import webbrowser
import os
dir_path = os.path.dirname(os.path.realpath(__file__))

def list_files(directory, extension):
    return (f for f in os.listdir(directory) if f.endswith('.' + extension))

pdfs = list_files(dir_path, "pdf")

merger = PdfFileMerger()

for pdf in pdfs:
    merger.append(open(pdf, 'rb'))

with open('result.pdf', 'wb') as fout:
    merger.write(fout)

webbrowser.open_new('file://'+ dir_path + '/result.pdf')

Gitリポジトリ:https ://github.com/mahaguru24/Python_Merge_PDF.git

于 2018-07-27T02:24:48.900 に答える
2

ここで、http://pieceofpy.com/2009/03/05/concatenating-pdf-with-python/が解決策を提供します。

同様に:

from pyPdf import PdfFileWriter, PdfFileReader

def append_pdf(input,output):
    [output.addPage(input.getPage(page_num)) for page_num in range(input.numPages)]

output = PdfFileWriter()

append_pdf(PdfFileReader(file("C:\\sample.pdf","rb")),output)
append_pdf(PdfFileReader(file("c:\\sample1.pdf","rb")),output)
append_pdf(PdfFileReader(file("c:\\sample2.pdf","rb")),output)
append_pdf(PdfFileReader(file("c:\\sample3.pdf","rb")),output)

    output.write(file("c:\\combined.pdf","wb"))
于 2014-07-18T09:27:58.217 に答える
1

柔軟性を高めるために辞書を使用したわずかなバリエーション(並べ替え、重複排除など):

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")
于 2019-02-19T22:40:33.910 に答える
1

PyPDF2モジュールPdfFileMergerから使用できます。

たとえば、パスのリストから複数のPDFファイルをマージするには、次の関数を使用できます。

from PyPDF2 import PdfFileMerger

# pass the path of the output final file.pdf and the list of paths
def merge_pdf(out_path: str, extracted_files: list [str]):
    merger   = PdfFileMerger()
    
    for pdf in extracted_files:
        merger.append(pdf)

    merger.write(out_path)
    merger.close()

merge_pdf('./final.pdf', extracted_files)

そして、この関数は、親フォルダーからすべてのファイルを再帰的に取得します。

import os

# pass the path of the parent_folder
def fetch_all_files(parent_folder: str):
    target_files = []
    for path, subdirs, files in os.walk(parent_folder):
        for name in files:
            target_files.append(os.path.join(path, name))
    return target_files 

# get a list of all the paths of the pdf
extracted_files = fetch_all_files('./parent_folder')

最後に、parent_folder_path複数のドキュメントを含めることができるdeclaring.aとoutput_pdf_path、マージされたPDFの宛先用の2つの関数declaring.aを使用します。

# get a list of all the paths of the pdf
parent_folder_path = './parent_folder'
outup_pdf_path     = './final.pdf'

extracted_files = fetch_all_files(parent_folder_path)
merge_pdf(outup_pdf_path, extracted_files)

ここから完全なコードを入手できます(出典):Pythonを使用してPDFドキュメントをマージする方法

于 2021-11-13T18:43:40.577 に答える
0

サブプロセス(ディレクトリにone.pdfとtwo.pdfが存在すると仮定)を利用して、Linuxターミナルでpdf uniteを使用しました。目的は、それらをth​​ree.pdfにマージすることです。

 import subprocess
 subprocess.call(['pdfunite one.pdf two.pdf three.pdf'],shell=True)
于 2020-02-01T00:54:47.503 に答える
0

簡単に使用できる方法でのGiovanniG.PYからの回答(少なくとも私にとっては):

import os
from PyPDF2 import PdfFileMerger

def merge_pdfs(export_dir, input_dir, folder):
    current_dir = os.path.join(input_dir, folder)
    pdfs = os.listdir(current_dir)
    
    merger = PdfFileMerger()
    for pdf in pdfs:
        merger.append(open(os.path.join(current_dir, pdf), 'rb'))

    with open(os.path.join(export_dir, folder + ".pdf"), "wb") as fout:
        merger.write(fout)

export_dir = r"E:\Output"
input_dir = r"E:\Input"
folders = os.listdir(input_dir)
[merge_pdfs(export_dir, input_dir, folder) for folder in folders];
于 2021-03-24T15:39:29.060 に答える
0

これが私の特定のユースケースの最も一般的な答えの時間比較です:5つの大きな単一ページのpdfファイルのリストを組み合わせます。各テストを2回実行しました。

(免責事項:この機能はFlask内で実行しました。マイレージは異なる場合があります)

TL; DR

pdfrw私がテストした3つのうちpdfを組み合わせるための最速のライブラリです。

PyPDF2

start = time.time()
merger = PdfFileMerger()
for pdf in all_pdf_obj:
    merger.append(
        os.path.join(
            os.getcwd(), pdf.filename # full path
                )
            )
formatted_name = f'Summary_Invoice_{date.today()}.pdf'
merge_file = os.path.join(os.getcwd(), formatted_name)
merger.write(merge_file)
merger.close()
end = time.time()
print(end - start) #1 66.50084733963013 #2 68.2995400428772

PyMuPDF

start = time.time()
result = fitz.open()

for pdf in all_pdf_obj:
    with fitz.open(os.path.join(os.getcwd(), pdf.filename)) as mfile:
        result.insertPDF(mfile)
formatted_name = f'Summary_Invoice_{date.today()}.pdf'

result.save(formatted_name)
end = time.time()
print(end - start) #1 2.7166640758514404 #2 1.694727897644043

pdfrw

start = time.time()
result = fitz.open()

writer = PdfWriter()
for pdf in all_pdf_obj:
    writer.addpages(PdfReader(os.path.join(os.getcwd(), pdf.filename)).pages)

formatted_name = f'Summary_Invoice_{date.today()}.pdf'
writer.write(formatted_name)
end = time.time()
print(end - start) #1 0.6040127277374268 #2 0.9576816558837891
于 2021-07-30T05:31:38.890 に答える
0

pikepdfも使用できます(ソースコード のドキュメント)。

サンプルコードは次のようになります(ドキュメントから取得)。

from glob import glob

from pikepdf import Pdf

pdf = Pdf.new()

for file in glob('*.pdf'):  # you can change this to browse directories recursively
    with Pdf.open(file) as src:
        pdf.pages.extend(src.pages)

pdf.save('merged.pdf')
pdf.close()

ページを除外する場合は、別の方法に進むことができます。たとえば、ページを新しいpdfにコピーします(コピーしないページを選択すると、pdf.pagesオブジェクトがリストのように動作します)。

それはまだ活発に維持されており、2022年2月の時点では、PyPDF2やpdfrwの場合には当てはまらないようです。

私はそれをベンチマークしていないので、他のソリューションよりも速いか遅いかわかりません。

私の場合、PyMuPDFに対する利点の1つは、公式のUbuntuパッケージ(python3-pikepdf)が利用できることです。これは、それに応じて自分のソフトウェアをパッケージ化するのに実用的です。

于 2022-02-22T18:01:20.263 に答える