¿Cómo puedo combinar archivos PDF para que cada archivo comience en un número de página impar?

11

Necesito fusionar algunos archivos PDF dormitados, y quiero que todos los archivos PDF de entrada comiencen en una página extraña en el archivo PDF de salida.

Ejemplo: A.pdftiene 3 páginas, B.pdftiene 4 páginas. No quiero que mi salida tenga 7 páginas. Lo que quiero es un pdf de 8 páginas en el que las páginas 1-3 son de A.pdf, la página 4 está vacía y las páginas 5-8 son de B.pdf. ¿Cómo puedo hacer esto?

Sé sobre pdftk, pero no encontré esa opción en la página del manual.

Jan Warchoł
fuente

Respuestas:

6

La biblioteca PyPdf facilita este tipo de cosas si está dispuesto a escribir un poco de Python. Guarde el código a continuación en un script llamado pdf-cat-even(o lo que quiera), hágalo ejecutable ( chmod +x pdf-cat-even) y ejecútelo como filtro ( ./pdf-cat-even a.pdf b.pdf >concatenated.pdf). Necesita pyPdf ≥1.13 para el addBlankPagemétodo.

#!/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- deja de ser malvado'
fuente
¡Gracias, esto funcionó para mí! Como prefiero leer los nombres de los archivos PDF de un archivo, modifiqué un poco su código y lo publiqué como una respuesta por separado .
Jan Warchoł
@JanekWarchol Si los nombres de tus archivos no contienen caracteres especiales de shell como espacios en blanco:./pdf-cat-even $(cat list-of-file-names.txt) >concatenated.pdf
Gilles 'SO- deja de ser malvado'
Lamentablemente contienen espacios en blanco. Pero gracias, sin embargo, no me di cuenta de que podría hacerse de esta manera.
Jan Warchoł
@JanekWarchol Entonces puedes usar<list-of-file-names.txt tr '\n' '\0' | xargs -0 ./pdf-cat-even >concatenated.pdf
Gilles 'SO- deja de ser malvado'
3

El primer paso es producir un archivo pdf con una página vacía. Puede hacerlo fácilmente con muchos programas (LibreOffice / OpenOffice, inkscape, (La) TeX, scribus, etc.)

Luego solo incluya esta página vacía donde sea necesario:

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

Si desea hacer esto automáticamente con un script, puede usar, por ejemplo, pdftk file.pdf dump_data | grep NumberOfPages | egrep -o '[0-9]*'para extraer el recuento de páginas.

jofel
fuente
Esto se siente como un truco. Aunque si funciona, funciona, supongo.
Sam Whited
Este enfoque casi funcionó para mí: escribí un script que produjo una lista de archivos PDF con epmtyPage.pdf agregado cuando fue necesario, pero no pude hacer que pdftk analizara correctamente esta lista si los nombres de los archivos contenían espacios. Intenté cambiar el valor de IFS, utilizando comillas, pero fue en vano, tal vez es culpa de pdftk. De todos modos, la respuesta usando pypdf funcionó para mí.
Jan Warchoł
@JanekWarchol ¿Qué versión de pdftk usaste? Al menos pdftk 1.44 y posteriores parecen admitir espacios en blanco en los nombres de archivo.
jofel
@jofel pdftk --versiondevuelve pdftk 1.44. Recuerdo que mis amigos más conocedores pasaron al menos 15 minutos intentando diferentes cosas para conseguir este trabajo y se dieron por vencidos.
Jan Warchoł
1

La respuesta de Gilles funcionó para mí, pero como tengo que fusionar muchos archivos, es más conveniente si puedo leer sus nombres desde un archivo de texto. He modificado ligeramente el código de Gilles para hacer exactamente eso, tal vez ayudaría a alguien más:

#!/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ł
fuente
1

También podría usar LaTeX para hacer esto (aunque sé que probablemente no sea lo que desea). Algo como lo siguiente debería funcionar:

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

Tenga en cuenta que \cleardoublepagesolo inserta una página en blanco con clases hechas para impresión a doble cara (por ejemplo, libro)

Se pdfpagespueden encontrar más opciones e información sobre CTAN .

Sam Whited
fuente
2
Para incluir todas las páginas automáticamente, puede usar \includepdf[pages=-]{...}.
jofel
@jofel Gracias, solucionó la pregunta. Creo que también está predeterminado en todas las páginas, solo lo puse allí para mostrar que era posible seleccionar ciertas páginas.
Sam Whited
@jofel Además, \cleardoublepagesolo inserta una página en blanco si está utilizando una clase hecha para impresión a doble cara. Estaba usando un artículo que no funciona; Lo arreglé y actualicé la pregunta para reflejar eso.
Sam Whited
\includepdfincluye solo la primera página por defecto (no todas las páginas). \documentclass[twoside]{article}Funciona también.
jofel
Por lo que veo, tendría que escribir explícitamente todos los archivos que deben incluirse, así que eso no es lo suficientemente bueno para mí. Pero gracias de cualquier manera.
Jan Warchoł
0

Aquí está el código con PyPDF2 y 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
fuente