Teilen Sie PDF in Dokumente mit jeweils mehreren Seiten auf

7

Es gibt verschiedene Ressourcen im Web, die erklären, wie man ein PDF in mehrere Dateien mit einer Seite pro Datei aufteilen kann.

Aber wie können Sie sie in Stücke von beispielsweise fünf Seiten aufteilen? Ich habe mir die Standardwerkzeuge angeschaut, z. B. pdftkaber keine Option gefunden, um das zu tun, was ich will.

Raphael
quelle

Antworten:

12

pdftkist in der Lage, einen festen Satz von Seiten effizient auszuschneiden. Mit etwas Skriptkleber macht das, was ich will:

number=$(pdfinfo -- "$file" 2> /dev/null | awk '$1 == "Pages:" {print $2}')
count=$((number / pagesper))
filename=${file%.pdf}

counter=0
while [ "$count" -gt "$counter" ]; do 
  start=$((counter*pagesper + 1));
  end=$((start + pagesper - 1));

  counterstring=$(printf %04d "$counter")
  pdftk "$file" cat "${start}-${end}" output "${filename}_${counterstring}.pdf"

  counter=$((counter + 1))
done

Dies setzt voraus, dass Sie die Anzahl der Seiten pro Block $pagesperund den Dateinamen der Quell-PDF-Datei haben $file.

Wenn Sie acroreadinstalliert haben, können Sie auch verwenden

acroread -size a4 -start "$start" -end "$end" -pairs "$file" "${filename}_${counterstring}.ps"

acroreadbietet die Option, -toPostScriptdie nützlich sein kann.

Raphael
quelle
Sehen Sie hier für eine vollständige Umsetzung.
Raphael
9

Siehe auch pdfseparateund pdfunitevon poppler-utils. pdfseparateteilt die Datei in eine Datei pro Seite auf, was es relativ einfach macht, sie später nach Belieben pdfunitemanuell oder (halb-) automatisch wieder zusammenzusetzen.

Wie bei zsh:

autoload zargs

reunite() pdfunite "$@" file-$1-$argv[-1].pdf

pdfseparate file.pdf p%d
zargs -n 5 p<->(n) -- reunite
rm -f p<->

spalten würde file.pdfin file-p1-p5.pdf, file-p6-p10.pdf...

Stéphane Chazelas
quelle
Nett. Es werden jedoch viele temporäre Dateien erstellt.
Raphael
1
Dieses Skript funktionierte perfekt mit mir, nachdem mir klar wurde, dass ich es #!/bin/zshals erste Zeile hinzufügen sollte . Und natürlich die Installation von Z Shell ... Diese Details sind für Anfänger möglicherweise nicht offensichtlich.
Leonardo Castro
3

Ich finde Python mit der PyPdf-Bibliothek praktisch für Jobs, die pdftk nicht bequem (oder überhaupt nicht) erledigt.

#!/usr/bin/env python
import sys
from pyPdf import PdfFileWriter, PdfFileReader

# Command line parsing
if len(sys.argv) < 2 or sys.argv[1][-4:] != '.pdf':
    sys.stderr.writeln('Usage: ' + sys.argv[0] + ''' FILE.pdf N
Split FILE.pdf into chunks of N pages each.''')
    exit(3)
pages_per_file = int(sys.argv[2])

base_name = sys.argv[1][:-4] + '-'
input_pdf = PdfFileReader(open(sys.argv[1]))
output_pdf = PdfFileWriter()
num_pages = input_pdf.getNumPages()
for i in xrange(num_pages):
    output_pdf.addPage(input_pdf.getPage(i))
    if (i + 1) % pages_per_file == 0 or i + 1 == num_pages:
        output_file = open(base_name + str(i / pages_per_file + 1) + '.pdf', "wb")
        output_pdf.write(output_file)
        output_file.close()
        output_pdf = PdfFileWriter()
Gilles 'SO - hör auf böse zu sein'
quelle
Ich erhalte diesen Fehler: Traceback (most recent call last): File "./dividePDF.py", line 23, in <module> if (i + 1) % pages_per_file == 0: flush() File "./dividePDF.py", line 18, in flush output_pdf.write(output_file) UnboundLocalError: local variable 'output_pdf' referenced before assignment
Leonardo Castro
Vorher bekam ich diesen Fehler: Traceback (most recent call last): File "./dividePDF.py", line 20, in <module> for i in xrange(input_pdf.getNumPages(input_pdf)): TypeError: getNumPages() takes exactly 1 argument (2 given) Also wechselte ich input_pdf.getNumPages(input_pdf)zu input_pdf.getNumPages()und bekam den anderen Fehler.
Leonardo Castro
1
@LeonardoCastro Danke für den Fehlerbericht, ich habe das Skript behoben.
Gilles 'SO - hör auf böse zu sein'
Ich habe dieses Skript nur mit N = 4 verwendet, aber der erste "Block" hatte immer 3 statt 4 Seiten. Die folgenden Blöcke waren in Ordnung. Ich habe die Reihenfolge der Zeilen "if (i + 1)% pages_per_file == 0: flush ()" und "output_pdf.addPage (input_pdf.getPage (i))" geändert und es hat richtig funktioniert.
Leonardo Castro
1
@LeonardoCastro Nochmals vielen Dank, ich habe das auf eine etwas andere Weise behoben und einen Fehler behoben, wenn die letzte Datei kürzer ist, weil die Anzahl der Seiten nicht ein Vielfaches der Blockgröße ist.
Gilles 'SO - hör auf böse zu sein'
2

Die von Raphael veröffentlichte Lösung ist fehlerhaft: Wenn Sie eine ungerade Anzahl von Seiten haben, werden die letzten einfach ignoriert. Dort ist es eine verbesserte Lösung, die auch mit einer ungeraden Anzahl von Seiten funktioniert. Auch hier wird davon ausgegangen, dass Sie die Anzahl der Seiten pro Block $pagesperund den Dateinamen der Quell-PDF-Datei haben $file.

number=$(pdfinfo -- "$file" 2> /dev/null | awk '$1 == "Pages:" {print $2}')

count=$((($number+$pagesper-1)/$pagesper))
filename=${file%.pdf}

counter=0
while [ "$count" -gt "$counter" ]; do
  start=$((counter*pagesper + 1));
  end=$((start + pagesper - 1));
  if [ $end -gt $number ]; then
    end=$number
  fi

  counterstring=$(printf %04d "$counter")
  pdftk "$file" cat "${start}-${end}" output "${filename}_${counterstring}.pdf"
  counter=$((counter + 1))
done
Verknüpfung aufheben
quelle
Guter Fang, danke! Sie hätten das aber auch in meiner Antwort bearbeiten können.
Raphael
Oh, tut mir leid, ich dachte, ich könnte die Antwort eines anderen mit geringem Ruf nicht bearbeiten.
Verknüpfung
Sie können, irgendwie; Die Bearbeitung wird von hochrangigen Mitarbeitern überprüft. Angesichts der Tatsache, dass Sie einen tatsächlichen Fehler behoben haben, gehe ich davon aus, dass sie ihn akzeptiert hätten! (Sie erhalten auch +2 Wiederholungen für akzeptierte Änderungen.)
Raphael