Gabungkan file PDF

126

Apakah mungkin, menggunakan Python, untuk menggabungkan file PDF yang terpisah?

Dengan asumsi demikian, saya perlu memperpanjang ini sedikit lebih jauh. Saya berharap untuk mengulang melalui folder dalam direktori dan mengulangi prosedur ini.

Dan saya mungkin mendorong keberuntungan saya, tetapi apakah mungkin untuk mengecualikan halaman yang terkandung dalam PDF (pembuatan laporan saya selalu membuat halaman kosong tambahan).

Btibert3
sumber

Jawaban:

122

Gunakan Pypdf atau penerusnya PyPDF2 :

Pustaka Pure-Python dibangun sebagai toolkit PDF. Ia mampu:
* memisahkan dokumen halaman demi halaman,
* menggabungkan dokumen halaman demi halaman,

(dan banyak lagi)

Berikut adalah contoh program yang bekerja dengan kedua versi tersebut.

#!/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
        # /programming/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()

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)
Gilles 'SO- berhenti menjadi jahat'
sumber
19
Dan sekarang, pypi.python.org/pypi/PyPDF2 yang merupakan proyek penerus PyPDF
David Fraser
Bekerja untuk saya hanya dengan membuka dalam mode biner (aliran input dan juga aliran output). open(input_file), 'r+b', dan bukannya sys.stdout yang saya gunakan output_stream = open('result.pdf', 'w+b').
Simeon Borko
@SimeonBorko Lepaskan +, artinya "baca dan tulis" dan tidak ada file yang dibaca dan ditulis. Saya telah menambahkan dukungan output dukungan Windows berdasarkan stackoverflow.com/questions/2374427/… .
Gilles 'SO- berhenti menjadi jahat'
PyPDF2 / 3 tidak stabil, bagaimana saya bisa menggabungkan file pdf tanpa PyPDF2 / 3.
GoingMyWay
2
Saya harus sys.stdout.buffermenggunakan Python 3.6.8 (Linux)
Greyshack
197

Anda dapat menggunakan PyPdf2 s PdfMergerkelas.

File Concatenation

Anda cukup menggabungkan file dengan menggunakan appendmetode ini.

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

Anda dapat meneruskan file menangani sebagai gantinya jalur file jika Anda mau.

Penggabungan File

Jika Anda ingin kontrol penggabungan yang lebih halus, ada mergemetode PdfMerger, yang memungkinkan Anda menentukan titik penyisipan dalam file output, yang berarti Anda dapat memasukkan halaman di mana saja di file. The appendMetode dapat dianggap sebagai mergemana titik penyisipan adalah akhir file.

misalnya

merger.merge(2, pdf)

Di sini kami memasukkan seluruh pdf ke dalam output tetapi di halaman 2.

Rentang Halaman

Jika Anda ingin mengontrol halaman mana yang ditambahkan dari file tertentu, Anda dapat menggunakan pagesargumen kata kunci dari appenddan merge, meneruskan tupel dalam formulir (start, stop[, step])(seperti rangefungsi biasa ).

misalnya

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

Jika Anda menentukan rentang yang tidak valid, Anda akan mendapatkan IndexError.

Catatan: juga untuk menghindari file dibiarkan terbuka, metode PdfFileMergers close harus dipanggil ketika file yang digabungkan telah ditulis. Ini memastikan semua file ditutup (input dan output) pada waktu yang tepat. Ini memalukan karena PdfFileMergertidak diimplementasikan sebagai pengelola konteks, jadi kita dapat menggunakan withkata kunci, menghindari panggilan tutup eksplisit dan mendapatkan keamanan pengecualian yang mudah.

Anda mungkin juga ingin melihat pdfcatskrip yang disediakan sebagai bagian dari pypdf2. Anda berpotensi menghindari kebutuhan untuk menulis kode sama sekali.

Github PyPdf2 juga menyertakan beberapa kode contoh yang menunjukkan penggabungan.

Paul Rooney
sumber
14

Gabungkan semua file pdf yang ada di dir

Letakkan file pdf di direktori. Luncurkan program. Anda mendapatkan satu pdf dengan semua pdf digabungkan.

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)
Giovanni G. PY
sumber
8

The pdfrwperpustakaan dapat melakukan ini cukup mudah, dengan asumsi Anda tidak perlu melestarikan bookmark dan anotasi, dan PDF Anda tidak dienkripsi. cat.pyadalah contoh skrip penggabungan, dan subset.pymerupakan contoh skrip subset halaman.

Bagian yang relevan dari skrip penggabungan - mengasumsikan inputsadalah daftar nama file input, dan outfnmerupakan nama file output:

from pdfrw import PdfReader, PdfWriter

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

Seperti yang Anda lihat dari sini, akan sangat mudah untuk meninggalkan halaman terakhir, misalnya sesuatu seperti:

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

Penafian: Saya adalah pdfrwpenulis utama .

Patrick Maupin
sumber
1
Ini yang paling stabil.
GoingMyWay
1
Perpustakaan ini layak mendapatkan reputasi lebih.
GoingMyWay
6

Apakah mungkin, menggunakan Python, untuk menggabungkan file PDF yang terpisah?

Iya.

Contoh berikut menggabungkan semua file dalam satu folder ke satu file PDF baru:

#!/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)
Martin Thoma
sumber
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 Repo: https://github.com/mahaguru24/Python_Merge_PDF.git

guruprasad mulay
sumber
2

disini, http://pieceofpy.com/2009/03/05/concatenating-pdf-with-python/ , memberikan solusinya.

demikian pula:

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"))
Mark K
sumber
0

Variasi kecil menggunakan kamus untuk fleksibilitas yang lebih besar (mis. Sortir, 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")
Ogaga Uzoh
sumber
0

Saya menggunakan pdf bersatu di terminal linux dengan memanfaatkan subproses (mengasumsikan one.pdf dan two.pdf ada di direktori) dan tujuannya adalah untuk menggabungkannya menjadi three.pdf

 import subprocess
 subprocess.call(['pdfunite one.pdf two.pdf three.pdf'],shell=True)
pengguna8291021
sumber