web-dev-qa-db-fra.com

Fusionner des PDF avec PDFTK avec des signets?

Utiliser pdftk pour fusionner plusieurs pdf marche bien. Cependant, un moyen simple de créer un signet pour chaque fichier PDF fusionné?

Je ne vois rien dans la documentation de pdftk à ce sujet, donc je ne pense pas que ce soit possible avec pdftk.

Tous nos fichiers fusionnés auront une page, alors vous vous demandez s'il existe un autre utilitaire pouvant ajouter des signets par la suite?

Ou un autre utilitaire pdf basé sur Linux qui permettra de fusionner tout en spécifiant un signet pour chaque pdf individuel.

32
Jason

Vous pouvez également fusionner plusieurs PDF avec Ghostscript. Le gros avantage de cette route est qu’une solution est facilement scriptable et ne nécessite pas de réel effort de programmation:

gswin32c.exe ^
          -dBATCH -dNOPAUSE ^
          -sDEVICE=pdfwrite ^
          -sOutputFile=merged.pdf ^
          [...more Ghostscript options as needed...] ^
          input1.pdf input2.pdf input3.pdf [....]

Avec Ghostscript, vous pourrez passer des instructions pdfmark pouvant ajouter une table des matières, ainsi que des signets pour chaque fichier source supplémentaire inséré dans le fichier PDF résultant. Par exemple:

gswin32c.exe ^
          -dBATCH -dNOPAUSE ^
          -sDEVICE=pdfwrite ^
          -sOutputFile=merged.pdf ^
          [...more Ghostscript options as needed...] ^
          file-with-pdfmarks-to-generate-a-ToC.ps ^
          -f input1.pdf input2.pdf input3.pdf [....]

ou

gswin32c.exe ^
          -dBATCH -dNOPAUSE ^
          -sDEVICE=pdfwrite ^
          -sOutputFile=merged.pdf ^
          [...more Ghostscript options as needed...] ^
          file-with-pdfmarks-to-generate-a-ToC.ps ^
          -f input1.pdf ^
             input2.pdf ^ 
             input3.pdf [....]

Pour une introduction au sujet pdfmark, voir aussi PDFmark Primer de Thomas Merz.


Edit:
Je voulais vous donner un exemple pour file-with-pdfmarks-to-generate-a-ToC.ps, mais je l’ai oubliée. C'est ici:

[/Page 1 /View [/XYZ null null null] /Title (File 1) /OUT pdfmark
[/Page 2 /View [/XYZ null null null] /Title (File 2) /OUT pdfmark
[/Page 3 /View [/XYZ null null null] /Title (File 3) /OUT pdfmark
[/Page 4 /View [/XYZ null null null] /Title (File 4) /OUT pdfmark 

Cela créerait une liste de contrôle pour les 4 premiers fichiers == les 4 premières pages (puisque vous garantissez que vos fichiers d'ingrédients sont d'une page chacun pour votre fichier PDF de sortie fusionné).

  1. La partie [/XYZ null null null] s'assure que votre fenêtre d'affichage et votre niveau de zoom ne changent pas par rapport à celui en cours lorsque vous suivez le lien. (Vous pouvez dire [/XYZ 222 111 2] pour le faire, si vous voulez un exemple arbitraire.)
  2. La fonction /Title (some string you want) détermine le texte figurant dans la table des matières.

Et, vous pouvez même ajouter ces paramètres à la ligne de commande Ghostscript directement:

gswin32c.exe ^
       -o merged.pdf ^
       [...more Ghostscript options as needed...] ^
       -c "[/Page 1 /View [/XYZ null null null] /Title (File 1) /OUT pdfmark" ^
       -c "[/Page 2 /View [/XYZ null null null] /Title (File 2) /OUT pdfmark" ^
       -c "[/Page 3 /View [/XYZ null null null] /Title (File 3) /OUT pdfmark" ^
       -c "[/Page 4 /View [/XYZ null null null] /Title (File 4) /OUT pdfmark" ^
       -f input1.pdf ^
          input2.pdf ^ 
          input3.pdf ^ 
          input4.pdf [....]



'nother Edit:

Oh, et au fait: Ghostscriptfaitconserve les signets lorsque vous l’utilisez pour fusionner deux PDF en un - pdftk.exe ne le fait pas. Utilisons celui généré par la commande de ma première édition (concaténant efficacement 2 copies du même fichier):

 gswin32c ^
    -sDEVICE=pdfwrite ^
    -o doublemerged.pdf ^
     merged.pdf ^
     merged.pdf

Le fichier doublemerged.pdf aura désormais 2 * 4 = 8 signets.

  • Comme prévu: les signets 1, 2, 3 et 4 renvoient aux pages 1, 2, 3 et 4.
  • Le problème est que les signets 5, 6, 7 et 8 renvoient également aux pages 1, 2, 3 et 4.

La raison en est que les signets préexistants traitaient leurs cibles de liens par des numéros de page absolus. Pour contourner ce problème (et les signets fonctionnent dans les fichiers fusionnés), vous devez générer des signets qui indiquent les liens des cibles par destinations nommées (et assurez-vous qu'ils sont identiques pour tous les documents fusionnés).

(Cette approche fonctionne également sur linux, utilisez simplement gs au lieu de gswin32c.)


Appendice

La ligne de commande ci-dessus utilise [...more Ghostscript options as needed...] comme espace réservé pour plus d'options.

Si vous n'utilisez pas d'autres options, Ghostscript appliquera ses paramètres par défaut intégrés pour divers paramètres. Toutefois, cela peut vous donner des résultats qui pourraient ne pas vous convenir. Étant donné que Ghostscript génère un tout nouveau PDF sur la base des entrées, cela signifie que certains des objets d'origine peuvent être modifiés. Cela est vrai pour les espaces colorimétriques et pour les niveaux de compression d'image.

Vous pouvez voir comment appliquer des paramètres laissant les images incorporées d'origine inchangées à l'adresse suivante: SuperUser: "Utilisez Ghostscript, mais dites-lui de ne pas retraiter les images" .

40
Kurt Pfeifle

Je sais qu'il existe d'autres moyens de le faire, mais avec pdftk, vous pouvez utiliser le fichier PDF fusionné et y ajouter des signets en utilisant la fonction pdftk dump_data pour créer un fichier .info avec les informations existantes dans le fichier PDF. Ensuite, vous pouvez ajouter des informations de signet au fichier .info en ajoutant les quatre lignes suivantes pour chaque signet.

BookmarkBegin
BookmarkTitle: name
BookmarkLevel: level
BookmarkPageNumber: page number

Utilisez ensuite l’appel update_info pour mettre à jour les signets PDF fusionnés avec ceux que vous avez écrits dans le fichier .info. J'ai écrit quelques fonctions simples qui font cela pour moi dans autohotkey si quelqu'un est intéressé. Voir http://www.autohotkey.com/board/topic/98985-scripts-to-merge-pdfs-and-add-bookmarks-with-pdftk/

10
steventaitinger

Voir cette réponse à https://stackoverflow.com/a/17781138/547578 . J'ai utilisé quelque chose appelé Sejda. Ça marche. Il combine les signets parfaitement. Merci @blablatros.

5
Fish Monitor

Pour ajouter ou modifier des signets au format PDF, vous pouvez utiliser JPdfBookmarks . C'est un excellent outil de logiciel libre multi-OS que j'utilise depuis un moment et qui donne d'excellents résultats. Cependant, comme il ne traite que des signets, vous aurez besoin d'un autre outil pour fusionner ou réorganiser les pages. En plus de pdftk, je suggère d'essayer PDF Split and Merge (bonne application, mais interface utilisateur bizarre, gâchis les favoris de mon expérience), PDF-Shuffler (semble pour bien fonctionner, mais se bloque parfois lorsqu’il s’agit de traiter certains fichiers), ou PdfMod (le meilleur potentiellement car il s’agit de réorganiser, de fusionner et de gérer les signets, bien que je n’aie pas pu comprendre comment ajouter des fichiers PDF dans une page spécifique).

Désolé de ne pas avoir fourni de liens, en tant que débutant, le système ne me permet que d’ajouter 2 hyperliens.

4
castaway

La bonne réponse de @pipitas ne résout pas les problèmes de signets mis au point et la question connexe fait l’objet d’une discussion unix https://unix.stackexchange.com/questions/17065/add-and-edit-bookmarks-to- pdf/31070 , où je suggère

Si vous vous en tenez toujours à ces scripts unix, alors

  1. extraire les données de signets vidées de pdftk
  2. écrivez un script supplémentaire pour convertir les données de signets vidées au format pdfmarks, commande gs de ghostscript acceptée.
  3. utilisez le script gs pour les fusionner avec pdfmarks

Le script existe déjà, voir pdf-merge.py depuis Fusionner des PDF avec PDFTK avec des signets?

2
Larry Cai

Peut-être que ce qui suit est utile. Je voulais fusionner tous les fichiers PDF (in_nn.pdf) situés dans un répertoire en un fichier out.pdf portant le nom de l’entrée pdfs (in_nn) sous forme de liste de contrôle. J'ai écrit un script python qui lit les noms, extrait les numéros de page et génère un fichier nommé pdfmarks. La fusion des fichiers se fait facilement avec gs. La commande exacte est sortie par le script et doit être exécutée séparément (peut-être avec quelques modifications dues aux adaptations de la taille de la page ou au système d'exploitation).

C'est ici. Peut-être que quelques modifications sont nécessaires pour Windows? (désolé pour les commentaires pas en anglais). Il suffit d’exécuter le script python dans le répertoire où se trouvent les pdfs à fusionner.

#!/usr/bin/env python

import subprocess

# Dieses Skript dient dazu, eine Reihe von pdfs zu einem einzigen pdf zusammenzufassen und bookmarks fuer diese pdf-Datei zu erzeugen.
# Dafuer wird ein Datei pdfmark benoetigt, die mit diesem Skript erzeugt wird.
# Dazu einfach dieses Skript in dem Verzeichnis aufrufen, das genau alle zusammenzufassenden pdfs (*pdf, s.u.) enthaelt.
# Das zusammenfassende pdf wird dann mit diesem Befehl (in der bash) generiert:
# gs -dBATCH -dNOPAUSE -sPAPERSIZE=A4 -sDEVICE=pdfwrite -sOutputFile="all.pdf" $(ls *pdf ) pdfmarks
# Bereits Inhaltsverzeichnisse bleiben erhalten, die neuen kommen ans Ende des Inhaltsverzeichnisses.
#
# pdfmarks sieht dabei prinzipiell so aus:
#
# [/Title (Nr. 1) /Page 1 /OUT pdfmark
# [/Title (Nr. 2) /Page 5 /OUT pdfmark
# [/Title (Nr. 3) /Page 9 /OUT pdfmark
# usw.

p = subprocess.Popen('ls *pdf', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

pdfdateien = []
kombinationen = []

for line in p.stdout.readlines():
# p enthaelt alle pdf-Dateinamen
  pdfdateien.append(line)


for datei in pdfdateien:
  cmd = "pdfinfo %s" %datei 
  q=subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  kombination = [datei]

for line in p.stdout.readlines():
# p enthaelt alle pdf-Dateinamen
  pdfdateien.append(line)


for datei in pdfdateien:
  cmd = "pdfinfo %s" %datei 
  q=subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  kombination = [datei]


  for subline in q.stdout.readlines():
# q enthaelt die Zeilen von pdfinfo
    if "Pages" in subline:
      kombination.append(subline)

  kombinationen.append(kombination)


# Jetzt kombinationen in benoetigtes Format bringen:

kombinationen_bereinigt =  []
out_string1 = "[/Title ("
out_string2 = ") /Page "
out_string3 = " /OUT pdfmark\n"
seitenzahl = 1

for kombination in kombinationen:
  dateiname = kombination[0][0:len(kombination[0])-5]

#
# Hier noch dateiname evtl. verwursten
# z. B.
#  lesezeichen = dateiname[0:1]+" "+dateiname[6:8]+"/"+dateiname[1:5]
  lesezeichen = dateiname

  anz_seiten = kombination[1][16:len(kombination[1])-1]
  seitenzahl_str = str(seitenzahl)

  kombination_bereinigt = out_string1+lesezeichen+out_string2+seitenzahl_str+out_string3
  kombinationen_bereinigt.append(kombination_bereinigt)

  seitenzahl += int(anz_seiten)


# Ausgabe ins file
outfile = open("pdfmarks", "w")

for i in kombinationen_bereinigt:
  outfile.write(i)

outfile.close()

# Merge-Befehl absetzen

print "\nFor merging all pdfs execute this (or similar) command (in bash Shell):"
print "gs -dBATCH -dNOPAUSE -sPAPERSIZE=A4 -sDEVICE=pdfwrite -sOutputFile=\"all.pdf\" $(ls *pdf ) pdfmarks\n"
2
pdfmerger

Malheureusement, il n'y a pas de moyen facile de le faire. Vous pouvez utiliser la bibliothèque sur laquelle pdftk est directement construite et écrire un programme Java ou .NET utilisant iText ou iTextSharp pour fusionner vos pages uniques et créer les signets. Si vous souhaitez emprunter la voie iText, de nombreux exemples sont disponibles en ligne ou dans le livre iText (écrit par l'auteur iText).

... ou laissez-moi savoir ce qui ne fonctionne pas et je peux vous aider.

1
khkremer

Ce qui suit est destiné à être un commentaire à la réponse de pdfmerger ( https://stackoverflow.com/a/30524828/3915004 ).

Merci pour votre script pdfmerger! Je sais que la question porte la mention linux, mais pour généraliser votre script sous Mac OS X, il vous faut 2 choses:

  • ghostscript gs et
  • la commande pdfinfo (incluse par exemple dans poppler)

Installez-les en obtenant d'abord brew (google, il est installé via une commande curl/Ruby-magic ^^), puis simplement:

brew install ghostscript
brew install poppler

ADD-ON: LIRE LE FICHIER TEXTE AVEC LES TITRES DE CHAPITRE:

Pour développer votre script. J'utilise ce flux de travail principalement pour les livres disponibles en téléchargement de chapitre sur le site Web de l'éditeur. Un fichier texte contenant les noms de chapitre peut facilement être généré. L'add-on suivant à votre code lit en outre un fichier texte 'chapitres.txt' contenant une ligne par fichier PDF à fusionner. (Remarque, je n'ai mis en œuvre aucun contrôle sur le nombre de lignes correspondant au nombre de fichiers PDF.)

Développez simplement votre script en remplaçant les lignes suivantes:

p = subprocess.Popen('ls *pdf', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
c = subprocess.Popen('less chapters.txt', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

pdfdateien = []
kombinationen = []
chapternames = []

for line in c.stdout.readlines():
# c contains all chapter-titles
  chapternames.append(line)

for line in p.stdout.readlines():

et

for index, kombination in enumerate(kombinationen):
#  dateiname = kombination[0][0:len(kombination[0])-5]
#
# Hier noch dateiname evtl. verwursten
# z. B.
#  lesezeichen = dateiname[0:1]+" "+dateiname[6:8]+"/"+dateiname[1:5]
#  lesezeichen = dateiname
  lesezeichen=chapternames[index][:-1]

  anz_seiten = kombination[1][16:len(kombination[1])-1]
0
fber

Sejda PDF (suggéré dans une des réponses ) est également disponible sous forme de service en ligne: https://www.sejda.com/merge- pdf .

Cela peut s'avérer utile si vous ne souhaitez installer aucun logiciel supplémentaire et préférez travailler en ligne à partir d'un navigateur.

Étapes à suivre pour fusionner:

  1. Faites glisser et déposez tous les fichiers PDF sur la page Web.
  2. Par défaut tous les signets existants sont conservés et fonctionnent également dans le document fusionné .

  3. L'outil de fusion peut éventuellement créer une table des matières basée sur les documents PDF combinés.

 Option selected to generated Table of contents for merged PDF documents based on filenames

 Merged PDF table of contents

Le service en ligne permettant de fusionner PDF fichiers est libre d'utilisation jusqu'à 30 fichiers par heure et jusqu'à 50 Mo/200 pages.

Disclaimer: Je suis un développeur open source travaillant sur Sejda.

0
Edi

Il y a PdfMod . Il possède une interface graphique et vous permet d’ajouter des signets manuellement. De même, si vous modifiez un PDF déjà accompagné de signets, il sera automatiquement mis à jour pour qu'il pointe vers les pages appropriées.

0
Caio S.

La version récente de pdftk (au moins v2.02) gère correctement les signets et les liens:

pdftk file1.pdf file2.pdf cat output merged.pdf
0
rriemann