Объединить PDF-файлы - PullRequest
       38

Объединить PDF-файлы

84 голосов
/ 10 августа 2010

Можно ли с помощью Python объединять отдельные файлы PDF?

При условии, что мне нужно расширить это немного дальше. Я надеюсь перебрать папки в каталоге и повторить эту процедуру.

И я могу испытывать удачу, но возможно ли исключить страницу, содержащуюся в PDF-файлах (при создании моего отчета всегда создается дополнительная пустая страница).

Ответы [ 8 ]

122 голосов
/ 21 июня 2016

Вы можете использовать PyPdf2 s PdfMerger класс.

Объединение файлов

Вы можете просто объединить файлы, используя метод 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.

Диапазоны страниц

Если вы хотите контролировать, какие страницы добавляются из определенного файла, вы можете использовать pages ключевое слово аргумента append и merge, передавая кортеж в виде (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.

Примечание: также, что во избежание открытия файлов следует вызывать метод close PdfFileMerger, когда записанный объединенный файл был записан.Это гарантирует, что все файлы будут закрыты (вход и выход) своевременно.Жаль, что PdfFileMerger не реализован как менеджер контекста, поэтому мы можем использовать ключевое слово with, избегать явного вызова close и получить некоторую простую исключительную безопасность.

Возможно, вы захотите посмотретьв сценарии pdfcat, предоставленном как часть pypdf2.Вы потенциально можете избежать необходимости писать код целиком.

Python PDF github также включает некоторые примеры кода, демонстрирующие слияние.

96 голосов
/ 10 августа 2010

Используйте Pypdf или его преемника PyPDF2 :

Библиотека Pure-Python, созданная в виде инструментария PDF.Он способен:
* разбивать документы по страницам,
* объединять документы по страницам,

(и многое другое)

Вот пример программы, котораяработает с обеими версиями.

#!/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 __name__ == '__main__':
    if sys.platform == "win32":
        import os, msvcrt
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    pdf_cat(sys.argv[1:], sys.stdout)
6 голосов
/ 31 марта 2014

Возможно ли с помощью Python объединить отдельные файлы PDF?

Да.

В следующем примере все файлы в одной папке объединяются в один новый 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)
5 голосов
/ 02 апреля 2017

Библиотека pdfrw может сделать это довольно легко, при условии, что вам не нужно сохранять закладки и аннотации, а ваши PDF-файлы не зашифрованы. cat.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 автор.

4 голосов
/ 17 ноября 2017

Объединить все PDF-файлы, которые присутствуют в каталоге

Поместите PDF-файлы в каталог. Запустить программу. Вы получаете один PDF со всеми объединенными 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)
2 голосов
/ 18 июля 2014

здесь, 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"))
1 голос
/ 27 июля 2018
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

0 голосов
/ 20 февраля 2019

Небольшое изменение с использованием словаря для большей гибкости (например, сортировка, дедупликация):

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...