Comment puis-je fusionner des fichiers pdf pour que chaque fichier commence sur un numéro de page impair?

11

J'ai besoin de fusionner quelques fichiers PDF somnolents, et je veux que tous les fichiers PDF d'entrée commencent sur une page impaire dans le fichier PDF de sortie.

Exemple: A.pdfa 3 pages, B.pdfa 4 pages. Je ne veux pas que ma sortie contienne 7 pages. Ce que je veux, c'est un pdf de 8 pages dans lequel les pages 1-3 sont de A.pdf, la page 4 est vide et les pages 5-8 sont de B.pdf. Comment puis-je faire ceci?

Je connais pdftk, mais je n'ai pas trouvé une telle option dans la page de manuel.

Jan Warchoł
la source

Réponses:

6

La bibliothèque PyPdf facilite ce genre de choses si vous êtes prêt à écrire un peu de Python. Enregistrez le code ci-dessous dans un script appelé pdf-cat-even(ou ce que vous voulez), rendez-le exécutable ( chmod +x pdf-cat-even) et exécutez-le en tant que filtre ( ./pdf-cat-even a.pdf b.pdf >concatenated.pdf). Vous avez besoin de pyPdf ≥1.13 pour la addBlankPageméthode.

#!/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- arrête d'être méchant'
la source
Merci, cela a fonctionné pour moi! Comme je préfère lire les noms des fichiers PDF à partir d'un fichier, j'ai légèrement modifié votre code et l'ai publié comme réponse distincte .
Jan Warchoł
@JanekWarchol Si les noms de vos fichiers ne contiennent pas de caractères spéciaux shell tels que des espaces:./pdf-cat-even $(cat list-of-file-names.txt) >concatenated.pdf
Gilles 'SO- arrête d'être méchant'
Malheureusement, ils contiennent des espaces blancs. Mais merci quand même - je ne savais pas que cela pouvait se faire de cette façon.
Jan Warchoł
@JanekWarchol Ensuite, vous pouvez utiliser<list-of-file-names.txt tr '\n' '\0' | xargs -0 ./pdf-cat-even >concatenated.pdf
Gilles 'SO- arrêtez d'être méchant'
3

La première étape consiste à produire un fichier pdf avec une page vide. Vous pouvez le faire facilement avec de nombreux programmes (LibreOffice / OpenOffice, inkscape, (La) TeX, scribus, etc.)

Il vous suffit ensuite d'inclure cette page vide si nécessaire:

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

Si vous voulez le faire automatiquement avec un script, vous pouvez par exemple utiliser pdftk file.pdf dump_data | grep NumberOfPages | egrep -o '[0-9]*'pour extraire le nombre de pages.

jofel
la source
Cela ressemble à un peu de piratage. Mais si ça marche, ça marche je suppose.
Sam Whited
Cette approche a presque fonctionné pour moi: j'ai écrit un script qui a produit une liste de fichiers PDF avec epmtyPage.pdf ajouté si nécessaire, mais je n'ai pas pu obtenir pdftk pour analyser correctement cette liste si les noms de fichiers contenaient des espaces. J'ai essayé de changer la valeur IFS, en utilisant des guillemets, mais en vain - c'est peut-être la faute de pdftk. Quoi qu'il en soit, la réponse en utilisant pypdf a fonctionné pour moi.
Jan Warchoł
@JanekWarchol Quelle version de pdftk avez-vous utilisée? Au moins pdftk 1.44 et plus récent semble prendre en charge les espaces blancs dans les noms de fichiers.
jofel
@jofel pdftk --versionrenvoie pdftk 1.44. Je me souviens que mes amis plus avertis ont passé au moins 15 minutes à essayer différentes choses pour obtenir ce travail et ont abandonné.
Jan Warchoł
1

La réponse de Gilles a fonctionné pour moi, mais comme je dois fusionner de nombreux fichiers, c'est plus pratique si je peux lire leurs noms dans un fichier texte. J'ai légèrement modifié le code de Gilles pour faire exactement cela, peut-être que cela aiderait quelqu'un d'autre:

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

Vous pouvez également utiliser LaTeX pour ce faire (bien que je sache que ce n'est probablement pas ce que vous voulez). Quelque chose comme ce qui suit devrait fonctionner:

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

Notez que \cleardoublepageseulement insère une page vierge avec des classes qui sont faites pour l'impression recto verso (par exemple. Livre)

Plus d'options et d'informations sur pdfpagespeuvent être trouvées sur CTAN .

Sam Whited
la source
2
Pour inclure automatiquement toutes les pages, vous pouvez utiliser \includepdf[pages=-]{...}.
jofel
@jofel Merci, correction de la question. Je pense que cela vaut par défaut pour toutes les pages aussi, je l'ai juste mis dedans pour montrer qu'il était possible de sélectionner certaines pages.
Sam Whited
@jofel En outre, n'insère \cleardoublepageune page vierge que si vous utilisez une classe conçue pour l'impression recto verso. J'utilisais un article qui ne fonctionnait pas; Je l'ai corrigé et mis à jour la question pour refléter cela.
Sam Whited
\includepdfinclut uniquement la première page par défaut (pas toutes les pages). \documentclass[twoside]{article}fonctionne aussi.
jofel
D'après ce que je vois, je devrais écrire explicitement tous les fichiers qui doivent être inclus, donc ce n'est pas assez bon pour moi. Mais merci quand même.
Jan Warchoł
0

Voici le code avec PyPDF2 et 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
la source