Come posso unire i file pdf in modo che ciascun file inizi su un numero di pagina dispari?


11

Ho bisogno di unire alcuni pdf appannati e voglio che tutti i pdf di input inizino su una pagina dispari nel pdf di output.

Esempio: A.pdfha 3 pagine, B.pdfha 4 pagine. Io non voglio la mia uscita di avere 7 pagine. Quello che voglio è un pdf di 8 pagine in cui le pagine 1-3 provengono A.pdf, la pagina 4 è vuota e le pagine 5-8 provengono da B.pdf. Come posso fare questo?

Conosco pdftk, ma non ho trovato questa opzione nella pagina man.

Risposte:


6

La libreria PyPdf semplifica questo genere di cose se sei disposto a scrivere un po 'di Python. Salva il codice qui sotto in uno script chiamato pdf-cat-even(o come preferisci), rendilo eseguibile ( chmod +x pdf-cat-even) ed eseguilo come filtro ( ./pdf-cat-even a.pdf b.pdf >concatenated.pdf). È necessario pyPdf ≥1.13 per il addBlankPagemetodo.

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

Grazie, ha funzionato per me! Poiché preferisco leggere i nomi dei file PDF da un file, ho modificato leggermente il codice e l'ho pubblicato come risposta separata .
Jan Warchoł

@JanekWarchol Se i nomi dei tuoi file non contengono caratteri speciali della shell come gli spazi bianchi:./pdf-cat-even $(cat list-of-file-names.txt) >concatenated.pdf
Gilles 'SO- smetti di essere malvagio'

Sfortunatamente contengono spazi bianchi. Ma grazie comunque - non mi ero reso conto che potesse essere fatto in questo modo.
Jan Warchoł

@JanekWarchol Quindi puoi usare<list-of-file-names.txt tr '\n' '\0' | xargs -0 ./pdf-cat-even >concatenated.pdf
Gilles 'SO- smetti di essere malvagio'

3

Il primo passo è produrre un file pdf con una pagina vuota. Puoi farlo facilmente con molti programmi (LibreOffice / OpenOffice, inkscape, (La) TeX, scribus, ecc.)

Quindi includi questa pagina vuota dove necessario:

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

Se vuoi farlo automaticamente con uno script, puoi usare, ad esempio, pdftk file.pdf dump_data | grep NumberOfPages | egrep -o '[0-9]*'per estrarre il conteggio delle pagine.


Sembra un po 'un trucco. Anche se funziona, suppongo che funzioni.
Sam Whited,

Questo approccio ha funzionato quasi per me: ho scritto una sceneggiatura che ha prodotto un elenco di pdf con epmtyPage.pdf aggiunto dove necessario, ma non sono riuscito a far sì che pdftk analizzasse correttamente questo elenco se i nomi dei file contenessero spazi. Ho provato a cambiare il valore IFS, usando le virgolette ma senza risultati - forse è colpa di pdftk. Ad ogni modo, la risposta usando pypdf ha funzionato per me.
Jan Warchoł

@JanekWarchol Quale versione di pdftk hai usato? Almeno pdftk 1.44 e successivi sembrano supportare gli spazi bianchi nei nomi dei file.
Jofel

@jofel pdftk --versionrestituisce pdftk 1.44. Ricordo che i miei amici più esperti di bash hanno trascorso almeno 15 minuti a provare cose diverse per ottenere questo lavoro e hanno rinunciato.
Jan Warchoł

1

La risposta di Gilles ha funzionato per me, ma dal momento che devo unire molti file è più conveniente se riesco a leggere i loro nomi da un file di testo. Ho leggermente modificato il codice di Gilles per farlo, forse aiuterebbe qualcun altro:

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

1

Puoi anche usare LaTeX per farlo (anche se sono consapevole che probabilmente non è quello che vuoi). Qualcosa di simile al seguente dovrebbe funzionare:

\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}

Si noti che \cleardoublepageinserisce solo una pagina vuota con le classi create per la stampa fronte / retro (ad es. Libro)

Ulteriori opzioni e informazioni pdfpagessono disponibili su CTAN .


2
Per includere automaticamente tutte le pagine, è possibile utilizzare \includepdf[pages=-]{...}.
jofel,

@jofel Grazie, risolto il problema. Penso che sia predefinito anche su tutte le pagine, l'ho appena inserito per mostrare che era possibile selezionare determinate pagine.
Sam Whited,

@jofel Inoltre, \cleardoublepageinserisce una pagina vuota solo se si utilizza una classe creata per la stampa fronte / retro. Stavo usando un articolo che non funziona; L'ho risolto e ho aggiornato la domanda per riflettere ciò.
Sam Whited,

\includepdfinclude solo la prima pagina per impostazione predefinita (non tutte le pagine). \documentclass[twoside]{article}funziona anche.
jofel

Da quello che vedo dovrei scrivere esplicitamente tutti i file che devono essere inclusi, quindi non è abbastanza buono per me. Ma grazie comunque.
Jan Warchoł

0

Ecco il codice con PyPDF2 e 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"))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.