Wie kann ich PDF-Dateien zusammenführen, sodass jede Datei mit einer ungeraden Seitenzahl beginnt?

10

Ich muss ein paar döste PDFs zusammenführen, und ich möchte, dass alle Eingabe-PDFs auf einer ungeraden Seite im Ausgabe-PDF beginnen.

Beispiel: A.pdfhat 3 Seiten, B.pdfhat 4 Seiten. Ich möchte nicht, dass meine Ausgabe 7 Seiten hat. Was ich möchte, ist ein 8-seitiges PDF, in dem die Seiten 1-3 von A.pdf, die Seite 4 leer und die Seiten 5-8 von sind B.pdf. Wie kann ich das machen?

Ich kenne mich mit pdftk aus, habe aber auf der Manpage keine solche Option gefunden.

Jan Warchoł
quelle

Antworten:

6

Die PyPdf-Bibliothek macht diese Art von Dingen einfach, wenn Sie bereit sind, ein bisschen Python zu schreiben. Speichern Sie den folgenden Code in einem Skript mit dem Namen pdf-cat-even(oder wie auch immer Sie möchten), machen Sie ihn ausführbar ( chmod +x pdf-cat-even) und führen Sie ihn als Filter ( ./pdf-cat-even a.pdf b.pdf >concatenated.pdf) aus. Sie benötigen pyPdf ≥1.13 für die addBlankPageMethode.

#!/usr/bin/env python
import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
output = PdfFileWriter()
output_page_number = 0
alignment = 2           # to align on even pages
for filename in sys.argv[1:]:
    # This code is executed for every file in turn
    input = PdfFileReader(open(filename))
    for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
        # This code is executed for every input page in turn
        output.addPage(p)
        output_page_number += 1
    while output_page_number % alignment != 0:
        output.addBlankPage()
        output_page_number += 1
output.write(sys.stdout)
Gilles 'SO - hör auf böse zu sein'
quelle
Danke, das hat bei mir funktioniert! Da ich die Namen der PDFs lieber aus einer Datei lesen möchte, habe ich Ihren Code leicht geändert und als separate Antwort veröffentlicht .
Jan Warchoł
@JanekWarchol Wenn Ihre Dateinamen keine Shell-Sonderzeichen wie Leerzeichen enthalten:./pdf-cat-even $(cat list-of-file-names.txt) >concatenated.pdf
Gilles 'SO- hör auf böse zu sein'
Leider enthalten sie Leerzeichen. Aber trotzdem danke - ich wusste nicht, dass es so geht.
Jan Warchoł
@ JanekWarchol Dann kannst du<list-of-file-names.txt tr '\n' '\0' | xargs -0 ./pdf-cat-even >concatenated.pdf
Gilles '
3

Der erste Schritt besteht darin, eine PDF-Datei mit einer leeren Seite zu erstellen. Sie können dies problemlos mit vielen Programmen tun (LibreOffice / OpenOffice, inkscape, (La) TeX, Scribus usw.).

Fügen Sie dann bei Bedarf einfach diese leere Seite hinzu:

pdftk A.pdf empty_page.pdf B.pdf output result.pdf 

Wenn Sie dies automatisch mit einem Skript tun möchten, können Sie zB pdftk file.pdf dump_data | grep NumberOfPages | egrep -o '[0-9]*'die Seitenzahl extrahieren.

Jofel
quelle
Das fühlt sich wie ein Hack an. Wenn es funktioniert, funktioniert es vermutlich.
Sam Whited
Dieser Ansatz hat bei mir fast funktioniert: Ich habe ein Skript geschrieben, das eine Liste von PDFs mit epmtyPage.pdf erstellt hat, die bei Bedarf hinzugefügt wurde, aber ich konnte pdftk nicht dazu bringen, diese Liste korrekt zu analysieren, wenn die Dateinamen Leerzeichen enthielten. Ich habe versucht, den IFS-Wert mithilfe von Anführungszeichen zu ändern, aber ohne Erfolg - vielleicht ist es pdftks Schuld. Wie auch immer, die Antwort mit pypdf hat bei mir funktioniert.
Jan Warchoł
@ JanekWarchol Welche Version von pdftk haben Sie verwendet? Mindestens pdftk 1.44 und höher scheinen Leerzeichen in Dateinamen zu unterstützen.
Jofel
@jofel pdftk --versiongibt pdftk 1.44 zurück. Ich erinnere mich, dass meine versierteren Freunde mindestens 15 Minuten damit verbracht haben, verschiedene Dinge auszuprobieren, um diese Arbeit zu bekommen, und aufgegeben haben.
Jan Warchoł
1

Gilles 'Antwort hat bei mir funktioniert, aber da ich viele Dateien zusammenführen muss, ist es bequemer, wenn ich ihre Namen aus einer Textdatei lesen kann. Ich habe Gilles 'Code leicht modifiziert, um genau das zu tun. Vielleicht würde es jemand anderem helfen:

#!/usr/bin/env python

# requires PyPdf library, version 1.13 or above -
# its homepage is http://pybrary.net/pyPdf/
# running: ./this-script-name file-with-pdf-list > output.pdf

import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
output = PdfFileWriter()
output_page_number = 0

# every new file should start on (n*alignment + 1)th page
# (with value 2 this means starting always on an odd page)
alignment = 2

listoffiles = open(sys.argv[1]).read().splitlines()
for filename in listoffiles:
    # This code is executed for every file in turn
    input = PdfFileReader(open(filename))
    for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
        # This code is executed for every input page in turn
        output.addPage(p)
        output_page_number += 1
    while output_page_number % alignment != 0:
        output.addBlankPage()
        output_page_number += 1
output.write(sys.stdout)
Jan Warchoł
quelle
1

Sie können dazu auch LaTeX verwenden (obwohl mir bewusst ist, dass es wahrscheinlich nicht das ist, was Sie wollen). So etwas sollte funktionieren:

\documentclass{book}

\usepackage{pdfpages}

\begin{document}

\includepdf[pages=-]{A}
\cleardoublepage % Make sure we clear to an odd page
\includepdf[pages=-]{B} % This inserts all pages. Or you can specify specific pages, a range, or `{}` for a blank page

\end{document}

Beachten Sie, dass \cleardoublepagenur eine leere Seite mit Klassen eingefügt wird, die für zweiseitiges Drucken vorgesehen sind (z. B. Buch).

Weitere Optionen und Informationen zu pdfpagesfinden Sie auf CTAN .

Sam Whited
quelle
2
Um alle Seiten automatisch einzuschließen, können Sie verwenden \includepdf[pages=-]{...}.
Jofel
@jofel Danke, die Frage wurde behoben. Ich denke, es werden standardmäßig auch alle Seiten verwendet. Ich habe es nur dort eingefügt, um zu zeigen, dass es möglich war, bestimmte Seiten auszuwählen.
Sam Whited
@jofel Fügt außerdem \cleardoublepagenur eine leere Seite ein, wenn Sie eine Klasse für zweiseitiges Drucken verwenden. Ich habe einen Artikel verwendet, der nicht funktioniert. Ich habe es behoben und die Frage aktualisiert, um dies widerzuspiegeln.
Sam Whited
\includepdfEnthält standardmäßig nur die erste Seite (nicht alle Seiten). \documentclass[twoside]{article}funktioniert auch.
Jofel
Nach allem, was ich sehe, müsste ich alle Dateien, die enthalten sein müssen, explizit schreiben, also ist das nicht gut genug für mich. Danke trotzdem.
Jan Warchoł
0

Hier ist der Code mit PyPDF2 und Python3

#!/usr/bin/env python


# requires PyPdf2 library, version 1.26 or above -
# its homepage is https://pythonhosted.org/PyPDF2/index.html
# running: ./this-script-name output.pdf file-with-pdf-list

import copy, sys
from PyPDF2 import PdfFileWriter, PdfFileReader
output = PdfFileWriter()
output_page_number = 0

# every new file should start on (n*alignment + 1)th page
# (with value 2 this means starting always on an odd page)
alignment = 2

for filename in sys.argv[2:]:
    # This code is executed for every file in turn
    input = PdfFileReader(open(filename, "rb"))
    output.appendPagesFromReader(input)
    output_page_number += input.getNumPages()

    while output_page_number % alignment != 0:
        output.addBlankPage()
        output_page_number += 1

output.write(open(sys.argv[1], "wb"))
Loren
quelle