将PDF与PDFTK合并为书签?

使用pdftk合并多个pdf的工作正常。 但是,任何简单的方法来使每个PDF合并书签?

我没有看到关于这个pdftk文档的任何东西,所以我不认为这是可能的pdftk。

我们合并的所有文件将是1页,所以想知道是否有任何其他工具可以添加书签之后?

或另一个基于Linux的PDF实用程序,将允许合并,同时指定每个PDF的书签。

Solutions Collecting From Web of "将PDF与PDFTK合并为书签?"

您也可以将多个PDF与Ghostscript合并。 这条路线的一大优点是解决方案很容易编写脚本,而且不需要真正的编程工作:

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

使用Ghostscript,您将能够传递pdfmark语句,这些语句可以为每个附加源文件添加一个内容列表以及进入生成PDF的书签。 例如:

 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 [....] 

要么

 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 [....] 

有关pdfmark主题的一些介绍,另请参阅Thomas Merz的“ PDFmark入门”


编辑:
我本来想给你一个file-with-pdfmarks-to-generate-a-ToC.ps的例子,但不知何故忘了它。 这里是:

 [/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 

这将为前4个文件创建一个ToC ==前4个页面(因为你保证你的成分文件是1页,你的合并输出PDF)。

  1. [/XYZ null null null]部分确保您的页面视口和缩放级别不会从当前链接改变。 (如果你想要一个任意的例子,你可以说[/XYZ 222 111 2]来做到这一点)。
  2. /Title (some string you want) thingie决定了ToC中的文本。

而且,您甚至可以直接将这些参数添加到Ghostscript命令行中:

 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编辑:

哦,顺便说一句:Ghostscript保存书签,当你用它来合并两个PDF文件到一个 – pdftk.exe不。 让我们使用我的第一个编辑命令生成的(有效连接同一个文件的两个副本):

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

文件doublemerged.pdf现在将有2 * 4 = 8个书签。

  • 如预期的那样:书签1,2,3和4链接到页面1,2,3和4。
  • 问题是,书签5,6,7和8也链接在页面1,2,3和4。

原因是,现有书签确实通过绝对页码来解决链接目标。 要解决这个问题(和书签在合并文件中工作),必须生成指向指定目标链接目标的书签(并确保这些目录在合并的文档中是uniq)。

(这种方法也适用于linux,只需使用gs而不是gswin32c。)


附录

上面的命令行使用[...more Ghostscript options as needed...]作为一个占位符更多的选择。

如果您不使用其他选项,Ghostscript将为各种参数应用其内置的默认值。 但是,这可能会给你可能不符合你喜欢的结果。 由于Ghostscript基于输入生成一个全新的PDF,这意味着一些原始对象可能会被改变。 这对于色彩空间和图像压缩级别是正确的。

超级用户可以看到如何应用保留原始嵌入图像的参数: “使用Ghostscript,但是告诉它不要重新处理图像”

我知道还有其他的方法可以做到这一点,但是通过pdftk,你可以使用合并的PDF文件,并使用pdftk函数dump_data在pdf中创建现有信息的.info文件。 然后,您可以通过为每个书签添加以下四行来将书签信息添加到.info文件

 BookmarkBegin BookmarkTitle: name BookmarkLevel: level BookmarkPageNumber: page number 

然后使用update_info调用来更新合并的pdf书签和你写入.info文件的PDF书签。 我写了一些简单的函数,如果有人感兴趣,可以在autohotkey中为我做这个。 请参阅http://www.autohotkey.com/board/topic/98985-scripts-to-merge-pdfs-and-add-bookmarks-with-pdftk/

太添加或编辑PDF书签,你可以使用JPdfBookmarks 。 这是一个优秀的多操作系统免费软件工具,我已经使用了一段时间,现在已经很好的结果。 它只处理书签,所以你需要另一个工具来合并或重新排序页面。 除了pdftk,我建议尝试PDF拆分和合并 (好的应用程序,但怪异的用户界面,从我的经验弄乱书签), PDF-Shuffler (似乎工作正常,但有时冻结,而处理一些文件),或PdfMod因为它处理重新排列,合并和处理书签,尽管我还没有弄清楚如何将pdf添加到特定的页面)。

对不起,不提供一些链接,作为一个新手系统只允许我添加2个超链接。

请参阅https://stackoverflow.com/a/17781138/547578上的答案。 我用了一个叫Sejda的东西。 有用。 它完美地结合了书签。 谢谢@blablatros。

@pipitas的好回答并没有解决完善的书签问题,并且在unix讨论中有相关的问题https://unix.stackexchange.com/questions/17065/add-and-edit-bookmarks-to-pdf/ 31070 ,我建议

如果你仍然坚持使用这些unix脚本,那么

  1. 提取从pdftk转储的书签数据
  2. 写一个额外的脚本来转储转储的书签数据为pdfmarks格式,该ghostscript命令gs被接受。
  3. 使用gs脚本将它们与pdfmarks合并在一起

该脚本已经存在,请参阅合并PDF与PDFTK与书签的pdf-merge.py?

也许以下是有帮助的。 我想将位于一个目录中的所有pdf(in_nn.pdf)合并为一个out.pdf,其名称为输入pdf(in_nn)作为ToC。 我写了一个python脚本,它读取名称并提取页码,并生成一个名为pdfmarks的文件。 合并文件,然后轻松地与gs完成。 确切的命令由脚本输出,并且必须单独执行(可能由于页面大小适配或由于操作系统而进行了一些修改)。

这里是。 也许一些修改是必要的Windows? (对不起,评论不是英文)。 只需要在要合并的pdf目录中执行python脚本。

 #!/usr/bin/env python import subprocess # Dieses Skript dient dazu, eine Reihe von pdfs zu einem einzigen pdf zusammenzufassen und bookmarks fuer diese pdf-file zu erzeugen. # Dafuer wird ein file pdfmark benoetigt, die mit diesem Skript erzeugt wird. # Dazu einfach dieses Skript in dem Verzeichnis aufrufen, das genau alle zusammenzufassenden pdfs (*pdf, su) 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-filenamen 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-filenamen 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" 

不幸的是,有没有简单的方法来做到这一点。 您可以使用pdftk直接构建的库,或者编写一个使用iText或iTextSharp的Java或.NET程序来合并您的单页并创建书签。 如果你想去iText路线,有很多例子可以在线或在iText书(由iText作者编写)中。

…或者,让我知道什么是不工作,我可以帮助。

以下内容旨在通过pdfmerger( https://stackoverflow.com/a/30524828/3915004 )对答案进行评论。

感谢您的脚本pdfmerger! 我知道这个问题是标记为Linux,但是为了推广Mac OS X的脚本,需要两件事情:

  • ghostscript gs
  • 命令pdfinfo (包含在poppler

通过获得第一个brew (谷歌,它通过一些curl / ruby​​-magic命令^^)来安装它们,然后简单地:

 brew install ghostscript brew install poppler 

附加:阅读与章标题的文本文件:

展开你的脚本。 我主要使用这个工作流程作为章节 – 编辑网站的下载。 包含章节名称的文本文件可以很容易地生成。 下面的附加代码读取另外一个文本文件“chapters.txt”,每个pdf包含一行,以合并。 (注意,我没有执行任何检查与pdf数量相对应的行数。)

简单地通过替换以下几行来扩展您的脚本:

 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(): 

 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] 

有PdfMod 。 它有一个图形界面,它可以让你手动添加书签。 另外,如果您编辑已经附带书签的PDF,它将自动更新它们以指向正确的页面。