web-dev-qa-db-fra.com

Fusionner PDF

Est-il possible, en utilisant Python, de fusionner des fichiers séparés PDF?

En supposant que tel soit le cas, j’ai besoin de l’étendre un peu plus loin. J'espère pouvoir parcourir les dossiers d'un répertoire et répéter cette procédure.

Et je vais peut-être tenter ma chance, mais est-il possible d'exclure une page contenue dans les fichiers PDF (ma génération de rapport crée toujours une page vierge supplémentaire).

87
Btibert3

Utilisez Pypdf ou son successeur PyPDF2 :

Une bibliothèque Pure-Python construite comme un toolkit PDF. Elle est capable de:
* division de documents page par page,
* fusion de documents page par page,

(et beaucoup plus)

Voici un exemple de programme qui fonctionne avec les deux versions.

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

if __== '__main__':
    if sys.platform == "win32":
        import os, msvcrt
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    pdf_cat(sys.argv[1:], sys.stdout)
96
Gilles

Vous pouvez utiliser PyPdf2 s PdfMerger classe.

Concaténation de fichiers

Vous pouvez simplement concaténer fichiers en utilisant la méthode 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()

Vous pouvez transmettre des descripteurs de fichiers à la place des chemins de fichiers si vous le souhaitez.

Fusion de fichiers

Si vous voulez un contrôle plus fin de la fusion, il existe une méthode merge du PdfMerger, qui vous permet de spécifier un point d'insertion dans le fichier de sortie, ce qui signifie pouvez insérer les pages à n’importe quel endroit du fichier. La méthode append peut être considérée comme un merge où le point d'insertion est la fin du fichier.

par exemple.

merger.merge(2, pdf)

Ici, nous insérons le pdf entier dans la sortie mais à la page 2.

Intervalles de pages

Si vous souhaitez contrôler les pages ajoutées d'un fichier particulier, vous pouvez utiliser l'argument de mot clé pages de append et merge, en passant un tuple sous la forme (start, stop[, step]) (comme la fonction normale range).

par exemple.

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

Si vous spécifiez une plage non valide, vous obtiendrez un IndexError.

Remarque: De plus, pour éviter que les fichiers ne soient laissés ouverts, la méthode de fermeture PdfFileMergers devrait être appelée lorsque le fichier fusionné a été écrit. Cela garantit que tous les fichiers sont fermés (entrée et sortie) en temps voulu. Il est dommage que PdfFileMerger ne soit pas implémenté en tant que gestionnaire de contexte. Nous pouvons donc utiliser le mot clé with, éviter l'appel de fermeture explicite et obtenir une sécurité simple en ce qui concerne les exceptions.

Vous pouvez également consulter le script pdfcat fourni dans le cadre de pypdf2. Vous pouvez potentiellement éviter le besoin d'écrire du code complètement.

Le github PyPdf2 contient également inclut quelques exemples de code illustrant la fusion.

130
Paul Rooney

Est-il possible, en utilisant Python, de fusionner des fichiers séparés PDF?

Oui.

L'exemple suivant fusionne tous les fichiers d'un dossier en un nouveau fichier 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 __== "__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)
6
Martin Thoma

Fusionner tous les fichiers pdf présents dans un répertoire

Mettez les fichiers pdf dans un répertoire. Lancer le programme. Vous obtenez un pdf avec tous les pdfs fusionnés.

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)
6
Giovanni Python

La pdfrw library peut le faire très facilement, en supposant que vous n’ayez pas besoin de conserver les signets et les annotations et que vos PDF ne soient pas chiffrés. cat.py est un exemple de script de concaténation, et subset.py est un exemple de script de sous-paramétrage de page.

La partie pertinente du script de concaténation - suppose que inputs est une liste de noms de fichiers en entrée et que outfn est un nom de fichier de sortie:

from pdfrw import PdfReader, PdfWriter

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

Comme vous pouvez le constater, il serait assez facile de laisser de côté la dernière page, par exemple. quelque chose comme:

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

Déni de responsabilité: je suis l'auteur principal pdfrw.

5
Patrick Maupin

ici, http://pieceofpy.com/2009/03/05/concatenating-pdf-with-python/ , donne une solution.

de même:

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"))
2
Mark K
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')

Repo Git: https://github.com/mahaguru24/Python_Merge_PDF.git

2
guruprasad mulay

Une légère variation utilisant un dictionnaire pour une plus grande flexibilité (par exemple, trier, dédoubler):

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
Ogaga Uzoh