如何将多个PDF文件合并/转换为一个大的PDF文件?
我尝试了以下操作,但目标文件的内容与预期不符:
1
| convert file1.pdf file2.pdf merged.pdf |
我需要一个非常简单/基本的命令行(cli)解决方案。最好是我可以将合并/转换的输出直接通过管道传输到pdf2ps(正如我之前在这里问的问题:linux管道(convert->pdf2ps->lp))中最初尝试的那样)。
- 但是输出文件中的分辨率似乎不如pdfunite好,而且文件大小也比pdfunite的输出大
- 相关:Linux命令用数字排序合并PDF文件
考虑到pdfunite是poppler的一部分,安装的机会更大,使用也比pdftk简单:
1
| pdfunite in-1.pdf in-2.pdf in-n.pdf out.pdf |
- 波普勒也很快,从我的测试来看
- 它很快,但似乎断开了超链接。参见blog.dbrgn.ch/2013/8/14/merge-multiple-pdfs
- 只需确保您记得提供out.pdf,否则它将覆盖您命令中的最后一个文件,sigh。
- pdfunite的包是debian中的poppler utils,但在旧的debian版本中可能不存在。
- 不能推荐这个。结果PDF的大小太大了。例如:pdfunite为我提供了一个75MB文件,而ghostscript将所有内容打包为1MB。
- 六羟甲基三聚氰胺六甲醚。。。@Torben我刚刚使用这个工具将300多个PDF(总共13MB)打包成一个PDF文件,最后得到了一个12MB的文件。也许是你用的那个版本?我在OpenSUSE12.2上,使用pdfunite版本0.20.0。
- @我的评论有点误导人。我的意思是pdfunite不会优化文件大小。例如:当我使用pdfunite时,10个1MB的类似pdf(演示幻灯片)会生成一个~10MB的pdf。使用ghostscript,生成的pdf小于1MB。
- 在我的例子中,pdfunite没有生成可用的pdf文件。当我加载了evince时,我得到了很多错误。gs解决方案起作用。
- 您可以使用:pdfunite *.pdf out.pdf,假设该目录中不存在其他PDF,并且它们的顺序由"*"保留。如果不保留,则使用范围:文件名0..9.pdf解决此问题。
- PDfunite在我的用例中比PDFTK工作得更糟。我试图将一个特定表单的副本合并到同一个PDF中。在pdfunite中,它们是链接的,在pdftk中,它们是分离的,可以单独填写。
- @Torben使用GS时文件较小,因为使用默认设置时,图像会降低质量(仅屏幕视图质量,72 dpi图像)。使用-dPDFSETTINGS=/printer文件大小几乎相同(高质量,300 dpi图像)。
- @即使你对某些特殊情况可能是正确的,但你的一般假设是错误的。我刚刚合并了133MB的pdf(从inkscape导出的84个文件),其中包含位图、矢量图和文本,成了一个1.6MB大小的pdf。我用了/prepress做这个,/printer甚至把大小降到了1.3MB。即使我放大并打印了一个部件,我也找不到单个PDF和合并版本之间的任何明显区别。我很确定ghostscript会比较合并后的pdf并只存储一次共享内容。
- @danilobargen pdfunite不会破坏外部超链接。我已将文档与链接合并。链接保持功能。但是pdfunite可能会破坏内部超链接,如您提到的博客中所示。
- 普夫尼特对我很好。保留原始PDF的分辨率。PDF大小简单添加原始PDF。convert-compress的无损与convert、resolution lost和file size都有很大的不同。pdfunite版本0.22.1与ImageMagick 6.7.8-9。69K+130K PDF=>198K(含pdfunite),=>771K(含convert)。文本+gfx(原odt)+gfx(pdf打印为pdf)pdf。
- 不适用于我给Unimplemented Feature: Could not merge encrypted files ('MR1418_introduction.pdf')的pdf。但是pdftk能够处理它,尽管他警告我没有你不需要的密码。
- 比convert快得多,分辨率也不会变差。顶部
- 仍然工作到完美。我也没有看到任何大小变化;9.2 MB的文件生成了一个9.2 MB的文件。没有任何超链接,因此无法对此发表评论。
- 只需在bash脚本中输入以下内容:pdfunite $@ out.pdf
- @Aarnor很高兴报告OpenSuseLeap 42.3的工作进展良好。它的速度相当快,在不到一秒钟的时间内合并了100多页。
- 对不起,但是pdfunite弄乱了我的一些字体。
- 断开超链接。
尝试好的鬼脚本:
1
| gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=merged.pdf mine1.pdf mine2.pdf |
或者,即使对于低分辨率PDF的改进版本也可以这样(感谢Adriano指出这一点):
1
| gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=merged.pdf mine1.pdf mine2.pdf |
在这两种情况下,使用convert时输出分辨率都比使用convert时高得多,而且更好:
1
| convert -density 300x300 -quality 100 mine1.pdf mine2.pdf merged.pdf |
这样,您就不需要安装任何其他东西,只需使用您已经安装在系统中的东西(至少在我的RHEL中都是默认的)。
希望这有帮助,
最新消息:首先,谢谢你所有的好评!!只是一个可能对你们有用的提示,在谷歌搜索后,我发现了一个缩小PDF大小的绝妙方法,我用它将一个300 MB的PDF缩小到15 MB,分辨率可以接受!所有这些都有一个好的鬼脚本,这里是:
1
| gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=output.pdf input.pdf |
干杯!!
- 很好的提示,gs运行得很快,而且压缩很多。不过,我用了这个参数后质量提高了很多:-dPDFSETTINGS=/prepress。
- 我发现-dPDFSETTINGS=/prepress具有非常好的效果,可以旋转太宽的页面,并强制使用恼人的水平滚动条。
- 在您的.bash_profile中添加以下行,您就有了一个很好的快捷方式:pdfmerge() { gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=$@ ; },如果您需要经常使用命令,这可以节省一些输入。用法如下:pdfmerge merged.pdf mine1.pdf mine2.pdf。
- 我试图找到-dbatch标志的描述,但找不到。即使是man-gs也什么都没说。但是很好,没有任何附加程序!
- 因为imagemagick是基于ghostscript的,如果您已经有了它,也可以使用它;convert file1.pdf file2.pdf outputfile.pdf。
- @有意思的是,当我尝试第一个命令时,它旋转了一些页面(看起来与其他页面的比例相同),而/prepress版本没有旋转。
- 我喜欢这个解决方案,因为它保留了部分标题,我可以用我的PDF软件随意切换。
- 漂亮的回答。自从我听说Mac的预览应用程序有帮助以来,我一直很沮丧,但第一次我几乎没能让它工作,第二次我也不需要它。最大的问题是它不能决定它的行动。我以前可以拖动整个PDF文件,但尝试了邀请的缩略图,也有保存问题之间的新副本和所有!所以这个解决方案是一个很好的突破。由于ghostscript无法处理这个问题,我唯一的额外任务是在最后使用preview添加一个gif图像。也从自制安装!
- 这将保留超链接。好极了!
- 我只是运行这个命令,这样它就可以保存到我的鱼历史中了!我以后肯定会用到的。
- @温妮,对我来说,它没有保留超链接。你知道为什么吗?
- @我用了gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=output.pdf a.pdf b.pdf c.pdf这个对我有用。
- 我也用过。但在我的情况下,它不起作用。然后我使用了在线服务。谢谢你的回复。
- gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=merged.pdf mine1.pdf mine2.pdf可以缩短为gs -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -o merged.pdf mine1.pdf mine2.pdf。来自文档:"作为一个方便的速记,您可以使用-o选项,然后按照上面讨论的输出文件规范进行操作。-o选项还设置了-dBATCH和-dNOPAUSE选项。这是一种快速调用ghostscript来转换一个或多个输入文件的方法。"
很抱歉,我自己用谷歌找到了答案,而且有点运气:)
对于感兴趣的人;
我在Debian服务器上安装了PDFTK(PDF工具包),并使用以下命令实现了所需的输出:
1
| pdftk file1.pdf file2.pdf cat output output.pdf |
或
1
| gs -q -sPAPERSIZE=letter -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=output.pdf file1.pdf file2.pdf file3.pdf ... |
这反过来可以直接通过管道输送到PDF2PS。
- 使用ghostscript也可能有效:gs -q -sPAPERSIZE=letter -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=out.pdf in1.pdf in2.pdf in3.pdf ...
- 我需要更深入地研究可能的选项/标志(因为我不希望在文件中输出),但可能是的。谢谢你的建议。
- 值得一提的是,pdftk可以合并加密的pdf,而pdfnite不能
- 与默认选项中的转换相比,PDFTK提供更好的分辨率。
- pdftk file1.pdf file2.pdf cat output out.pdf将合并文件输出为out.pdf。
- 由于缺少依赖项libgcj,因此pdftk不适用于EL7系统。
- @"不幸的是,冰火对我来说不起作用,"埃多克斯1〔5〕说。像你一样,我喜欢这种方法,因为我已经安装了它。尽管如此,江户十一〔三〕还是很有魅力。
- 如果您不想键入每个文件名:pdftk ``ls *.pdf`` cat output out.pdf(只有一个backticks而不是两个backticks,但我没有用stackoverflow markdown解析器呈现它)
- @如果你想在室内使用倒勾,可以使用两个倒勾作为周围的倒勾。或者三个,如果你想使用双回线。不确定它是否会更高。但是在bash中不再推荐使用backticks,所以最好使用$(ls *.pdf)。
- @酒精这个命令中的cat是做什么的(一般不做)?我可以合并两个PDF文件而不需要那样做,并且看不到生成的PDF有任何问题。
- @Zelphir cat是这里的操作(PDFTK执行),而不是shell命令。
- pdftk很整洁,因为您可以轻松地选择要合并的页面范围:pdftk A=file1.pdf B=file2.pdf cat A1-3 B1 output out.pdf。
- 在我的使用中,pdftk不知何故卡住了,什么都没有产生,而gs给出了完美的结果。convert的分辨率下载为真(默认设置)。
- 由于GCJ是不推荐使用的链接,pdftk也是(大多数发行版已经将其淘汰)。另一个不错的选择是pdfunite和其他poppler实用程序。
- 用于加入明显在Windows下创建的文档的gs给了我这个错误Missing glyph CID=48, glyph=0030 in the font EAAAAB+Tahoma,Bold . The output PDF may fail with some viewers.,实际上,在默认的Ubuntu查看器上,我无法浏览它。
- 官方网站的版本不起作用。该答案截至2019年1月(仍然是官方的)。
- 关于PDF表单的注释。Thusfar,pdftk是我尝试过的唯一一个工具,它可以保持我的PDF格式和以前一样(在任何PDF阅读器和Acrobat阅读器中都可以使用)。
另外,pdfjoin a.pdf b.pdf将创建一个新的b-joined.pdf,内容包括a.pdf和b.pdf。
- 这很好,也很简洁,但是会破坏超链接。
- pdfjoin(pdflatex)失败,文件有很多页。未能合并到1K页文件。
- pdfjoin中断注释或其他非图形项
- "url palladio l"字体在pdfjoin'页面后变为不可见。
- pdfunite通常工作得很好,但是如果它说"未实现的特性:无法合并加密文件",pdfjoin是一个不错的选择。无论出于什么原因,pdfjoin都不会抱怨加密。
- 本机为我工作(可能),无需在MacOS Sierra(OSX)上安装任何设备。
- pdfjoin的v2.08对我来说不合适。其中一个输入PDF文件包含已填充的表单。但是结果PDF文件中没有显示任何输入。
您可以直接使用convert命令,
例如
1
| convert sub1.pdf sub2.pdf sub3.pdf merged.pdf |
- 这不是无损的。
- 您可以使用convert -compress lossless sub1.pdf sub2.pdf sub3.pdf merged.pdf,但产生的文件大小可能太大。我建议用convert -compress jpeg -quality 90 sub1.pdf sub2.pdf sub3.pdf merged.pdf代替。
- 这涉及到将所有内容转换为光栅图像,这显然不是最好的,尤其是在处理基于文本的PDF时。
- 几乎是一份OP所描述的不起作用的副本
- 不要将convert用于PostScript或PDF文件,除非您从矢量转到光栅,并且永不返回。很难夸大这是个多么糟糕的主意。
如果您有多个文件,不想逐个键入名称,这是最简单的解决方案:
qpdf --empty --pages *.pdf -- out.pdf
pdfunite可以合并整个pdf。例如,如果您想要文件1.pdf中的第2-7页和文件2.pdf中的第1、3、4页,则必须使用pdfseparate将文件拆分为单独的PDF,以便为每个页面提供给pdfunite。
此时,您可能需要一个具有更多选项的程序。qpdf是我发现的操纵pdf的最佳工具。pdftk越来越大,越来越慢,而且红帽/软呢帽由于依赖于GCJ而不打包。其他PDF实用程序具有mono或python依赖性。我发现qpdf生成的输出文件比使用pdfseparate和pdfunite将页面组装成30页的输出PDF要小得多,分别为970kb和16450kb。因为它提供了更多的选项,所以qpdf的命令行就不那么简单了;合并file1和file2的原始请求可以用
1
| qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf |
- 这么多。例如抛物线不再包住pdftk,或者是因为它依赖于gcj,我相信对于它的支持已经下降了。尽管通过pacman -Ss pdf搜索PDF操作工具,但我还是错过了。谢谢你的回答!我应该得到更多的赞成票,所以它就出现在对pdfunite或pdftk的建议旁边。
Apache PDFoxhttp://pdfbox.apache.org网站/
PDF合并此应用程序将获取PDF文档的列表并将其合并,将结果保存到新文档中。
usage: java -jar pdfbox-app-x.y.z.jar PDFMerger"Source PDF files (2 ..n)""Target PDF file"
使用来自python的pdf工具https://pypi.python.org/pypi/pdf tools/1.0.6
下载tar.gz文件并解压缩,然后运行如下命令
1
| python pdftools-1.1.0/pdfmerge.py -o output.pdf -d file1.pdf file2.pdf file3 |
在运行上述命令之前,应该安装pyhton3
此工具支持以下内容
您可以在下面的链接中找到更多详细信息,它是开源的
https://github.com/mrleeh/pdftools
- 这是完美的。使用gs(上面列出的所有变体),两个pdf(2MB和500KB)的简单合并需要几分钟时间才能完成,并生成一个40MB文件!pdftools以相同的文件大小即时完成。
您可以使用Sejda控制台,免费和开源。拉开拉链,运行sejda-console merge -f file1.pdf file2.pdf -o merged.pdf。
它保留书签、链接注释、acroforms等。它实际上有很多可以选择的选项,只需运行sejda-console merge -h就可以看到它们。
如果要将所有下载的图像转换为一个PDF,请执行
convert img{0..19}.jpg slides.pdf
- 不要将convert用于PostScript或PDF文件,除非您从矢量转到光栅,并且永不返回。很难夸大这是个多么糟糕的主意。
我赞成pdfunite的建议。然而,当我试图合并>2K的PDF文件时,我得到了Argument list too long错误。
我转向了python和两个外部包:pypdf2(处理所有与pdf相关的事情)和natsort(对目录的文件名进行"自然"排序)。如果这可以帮助某人:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| from PyPDF2 import PdfFileMerger
import natsort
import os
DIR ="dir-with-pdfs/"
OUTPUT ="output.pdf"
file_list = filter(lambda f: f.endswith('.pdf'), os.listdir(DIR))
file_list = natsort.natsorted(file_list)
# 'strict' used because of
# https://github.com/mstamy2/PyPDF2/issues/244#issuecomment-206952235
merger = PdfFileMerger(strict=False)
for f_name in file_list:
f = open(os.path.join(DIR, f_name),"rb")
merger.append(f)
output = open(OUTPUT,"wb")
merger.write(output) |
- "参数列表太长"表示您正在检查shell为环境分配的缓冲区大小——这实际上不是工具的限制。在这种情况下,切换到python可能有点杀伤力,因为您可以批处理:find input-name*.pdf xargs-p1-n500 sh-c'pdfunite"$@"output-date +%s.pdf'&;&;pdfunite output-*.pdf output.pdf(这将创建一批连续处理的500个文件,使生成的临时文件按正确的顺序排序,并生成一个ap适当的输出文件;之后需要清理临时文件)
这是我使用的一个方法,它很好用,而且很容易实现。这将需要fpdf和fpdi库,可以在这里下载:
- fpdf:http://www.fpdf.org/en/download.php
- fpdi:https://www.setasign.com/products/fpdi/downloads
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| require('fpdf.php');
require('fpdi.php');
$files = ['doc1.pdf', 'doc2.pdf', 'doc3.pdf'];
$pdf = new FPDI();
foreach ($files as $file) {
$pdf->setSourceFile($file);
$tpl = $pdf->importPage(1, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tpl);
}
$pdf->Output('F','merged.pdf'); |
我倾向于成为pymupdf(mupdf的python绑定)的开发人员之一。
你可以很容易地用它做你想做的(以及更多)。框架代码的工作方式如下:
1 2 3 4 5 6 7 8 9 10 11 12
| #-------------------------------------------------
import fitz # the binding PyMuPDF
fout = fitz.open() # new PDF for joined output
flist = ["1.pdf","2.pdf", ...] # list of filenames to be joined
for f in flist:
fin = fitz.open(f) # open an input file
fout.insertPDF(fin) # append f
fin.close()
fout.save("joined.pdf")
#------------------------------------------------- |
就是这样。有几个选项可用于仅选择页面范围、维护联合目录、反转页面顺序或更改页面旋转等。
我们是PyPI。
我喜欢查莫的想法,但我还是先考虑利用像这样的优势
1
| convert $(ls *.pdf) ../merged.pdf |
将多个源文件提供给convert会导致将它们合并为一个通用的pdf。此命令将实际目录中所有扩展名为.pdf的文件合并到父目录中的merged.pdf中。
- 考虑到这与最初的问题有多么相似,这似乎应该是一个评论,而不是一个答案。再多做一点,你就可以发表评论了。在此之前,请不要将答案用作解决方法。
- @太傻了,不,它回答了问题!虽然答案应该更详细。
- 不要将convert用于PostScript或PDF文件,除非您从矢量转到光栅,并且永不返回。很难夸大这是个多么糟糕的主意。
- 使用$(ls *.pdf)代替简单通配符*.pdf有什么意义?
- 此外,对于@firegurafiku answer,使用ls *.pdf通配符,您将失去对合并文件顺序的控制。在一个例子中,下面的列表:1.pdf,2.pdf,3.pdf,…,10.pdf,…,100.pdf实际上会像1.pdf,10.pdf,100.pdf,2.pdf,3.pdf那样合并(由于默认的Linux文件订购方式-这里您有关于这个问题的更多详细信息-stackoverflow.com/q/22948042/1977012)。
其他的答案是好的,但是如果您不能在本地合并PDF,无论您是在共享的托管环境中,还是出于其他原因,它们都不会帮助您。
如果您正在寻找一个API来远程合并PDF,您可以尝试使用API2PDF,它有一个端点用于将PDF合并在一起。文件在这里。
- 如果我想合并pdfs-remote,我会把ssh合并到远程机器中,不是吗?
- 正如我的文章所说,网站通常在共享的托管环境中,或者在您不能使用ssh的情况下。