PDF dosyalarını birleştirin


126

Python kullanarak ayrı PDF dosyalarını birleştirmek mümkün mü?

Öyle varsayarsak, bunu biraz daha genişletmem gerekiyor. Bir dizindeki klasörler arasında geçiş yapmayı ve bu prosedürü tekrarlamayı umuyorum.

Ve şansımı zorluyor olabilirim, ancak PDF'lerde bulunan bir sayfayı dışarıda bırakmak mümkün mü (rapor oluşturmam her zaman fazladan boş bir sayfa oluşturur).

Yanıtlar:


122

Pypdf veya halefi PyPDF2'yi kullanın :

PDF araç takımı olarak oluşturulmuş bir Pure-Python kitaplığı. Şu özelliklere sahiptir:
* belgeleri sayfa sayfa bölme,
* belgeleri sayfa sayfa birleştirme,

(ve daha fazlası)

İşte her iki sürümle de çalışan örnek bir program.

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

19
Ve şimdi, PyPDF'nin halefi olan pypi.python.org/pypi/PyPDF2
David Fraser

Benim için sadece ikili modda açıldığında çalışır (giriş akışları ve ayrıca çıkış akışı). open(input_file), 'r+b've sys.stdout yerine kullanıyorum output_stream = open('result.pdf', 'w+b').
Simeon Borko

@SimeonBorko Bırakın, +"oku ve yaz" anlamına gelir ve hiçbir dosya hem okunmaz hem de yazılmaz. Stackoverflow.com/questions/2374427/… temelinde Windows destek çıktı desteği ekledim .
Gilles 'SO- kötü olmayı bırak'

PyPDF2 / 3 kararlı değil, pdf dosyalarını PyPDF2 / 3 olmadan nasıl birleştirebilirim.
GoingMyWay

2
sys.stdout.bufferPython 3.6.8 (Linux) kullanmak zorunda kaldım
Greyshack

198

PyPdf2 s PdfMergersınıfını kullanabilirsiniz .

Dosya Birleştirme

Yöntemi kullanarak dosyaları basitçe birleştirebilirsinizappend .

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

İsterseniz dosya yollarının yerine dosya tutamaçlarını iletebilirsiniz.

Dosya Birleştirme

Daha hassas birleştirme kontrolü istiyorsanız, çıktı dosyasında bir ekleme noktası belirlemenize izin veren, yani sayfaları dosyanın herhangi bir yerine ekleyebileceğiniz bir mergeyöntemi vardır PdfMerger. appendYöntem A olarak düşünülebilir mergeekleme noktası dosya sonu.

Örneğin

merger.merge(2, pdf)

Burada tüm pdf'yi çıktıya ekliyoruz ama 2. sayfada.

Sayfa Aralıkları

Belirli bir dosyadan eklenir hangi sayfaların kontrol etmek isterseniz, kullanabilirsiniz pagesanahtar kelime argüman appendve mergeformda bir demet geçirerek, (start, stop[, step])(düzenli gibi rangeişlevi).

Örneğin

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

Geçersiz bir aralık belirtirseniz, bir IndexError.

Not: Ayrıca dosyaların açık kalmasını önlemek için PdfFileMerger, birleştirilen dosya yazıldığında s close yönteminin çağrılması gerekir. Bu, tüm dosyaların zamanında kapatılmasını (giriş ve çıkış) sağlar. Bu PdfFileMergerbir bağlam yöneticisi olarak uygulanmayan bir utançtır , bu nedenle withanahtar kelimeyi kullanabilir , açık yakın aramalardan kaçınabilir ve kolay bir istisna güvenliği elde edebiliriz.

Ayrıca pdfcatpypdf2'nin bir parçası olarak sağlanan komut dosyasına da bakmak isteyebilirsiniz. Kod yazma ihtiyacını tamamen ortadan kaldırabilirsiniz.

PyPdf2 github ayrıca birleştirmeyi gösteren bazı örnek kodlar içerir .


15

Bir dizinde bulunan tüm pdf dosyalarını birleştirin

Pdf dosyalarını bir dizine koyun. Programı Başlat. Tüm pdf'lerin birleştirildiği bir pdf alırsınız.

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)

8

pdfrwKütüphane Eğer imlerini ve ek açıklamaları korumak gerekmez varsayarak oldukça kolayca yapabilirsiniz ve PDF'leriniz şifreli değildir. cat.pyörnek bir birleştirme komut dosyasıdır ve subset.pyörnek bir sayfa altkümesi komut dosyasıdır.

Birleştirme komut dosyasının ilgili kısmı - inputsgirdi dosya adlarının bir listesi olduğunu ve outfnbir çıktı dosyası adı olduğunu varsayar :

from pdfrw import PdfReader, PdfWriter

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

Buradan da görebileceğiniz gibi, son sayfayı atlamak oldukça kolay olacaktır, örneğin:

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

Sorumluluk reddi: Ben birincil pdfrwyazarım.


1
Bu en kararlı olanıdır.
GoingMyWay

1
Bu kütüphane daha fazla itibarı hak ediyor.
GoingMyWay

6

Python kullanarak ayrı PDF dosyalarını birleştirmek mümkün mü?

Evet.

Aşağıdaki örnek, bir klasördeki tüm dosyaları tek bir yeni PDF dosyasında birleştirir:

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

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


2

burada, http://pieceofpy.com/2009/03/05/concatenating-pdf-with-python/ , bir çözüm sunar.

benzer şekilde:

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

0

Daha fazla esneklik için sözlük kullanan küçük bir varyasyon (ör. Sıralama, tekilleştirme):

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

0

Alt işlemden yararlanarak linux terminalinde pdf unite kullandım (dizinde bir.pdf ve iki.pdf olduğunu varsayar) ve amaç onları üç.pdf ile birleştirmek

 import subprocess
 subprocess.call(['pdfunite one.pdf two.pdf three.pdf'],shell=True)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.