【问题标题】:Merge / convert multiple PDF files into one PDF [closed]将多个 PDF 文件合并/转换为一个 PDF [关闭]
【发布时间】:2011-01-31 06:06:54
【问题描述】:

如何将多个 PDF 文件合并/转换为一个大的 PDF 文件?

我尝试了以下,但目标文件的内容与预期不符:

convert file1.pdf file2.pdf merged.pdf

我需要一个非常简单/基本的命令行 (CLI) 解决方案。如果我可以将合并/转换的输出直接通过管道传输到pdf2ps(正如我之前在这里提出的问题中最初尝试的那样:Linux piping ( convert -> pdf2ps -> lp)),那最好。

【问题讨论】:

  • ymmv,但这似乎在输出文件中的分辨率不如 pdfunite,而且它还会导致文件大小大于 pdfunite 的输出
  • 无论何时讨论这些解决方案是否保留链接in this post。如果要保留链接(可能与其他注释一起),如果需要命令行界面,请使用 pdftk,如果需要图形用户界面,请使用 pdfsam,如果需要 Web 界面,请使用 sejda。
  • convert 命令行来自 ImageMagick,它会在执行任何其他操作之前将 PDF 转换为图像。

标签: linux pdf merge command-line-interface


【解决方案1】:

考虑到pdfunitepoppler的一部分,它被安装的几率更高,使用也比pdftk简单:

pdfunite in-1.pdf in-2.pdf in-n.pdf out.pdf

请确保您记得提供out.pdf,否则它将覆盖您命令中的最后一个文件

【讨论】:

  • 速度很快,但似乎破坏了超链接。见blog.dbrgn.ch/2013/8/14/merge-multiple-pdfs
  • 只要确保你记得提供 out.pdf,否则它会覆盖你命令中的最后一个文件,叹气。
  • pdfunite 的软件包在 debian 中是 poppler-utils,但在旧的 debian 版本中可能不存在。
  • 不能推荐这个。生成的 PDF 的大小太大了。例如:Pdfunite 给了我一个 75MB 的文件,而 Ghostscript 将所有内容打包成 1MB。
  • 您可以使用:pdfunite *.pdf out.pdf 假设该目录中不存在其他 pdf 并且它们的顺序由“*”保留。如果未保留,请使用范围:filename_{0..9}.pdf 解决它。
【解决方案2】:

试试好ghostscript:

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=merged.pdf mine1.pdf mine2.pdf

或者甚至这种方式用于低分辨率 PDF 的改进版本(感谢 Adriano 指出这一点):

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=merged.pdf mine1.pdf mine2.pdf

在这两种情况下,输出分辨率都比使用转换的这种方式高得多且更好:

convert -density 300x300 -quality 100 mine1.pdf mine2.pdf merged.pdf

通过这种方式,您不需要安装任何其他东西,只需使用您系统中已经安装的东西(至少两者都默认在我的盒子里)。

更新:首先感谢所有漂亮的 cmets!只是一个可能对你们有用的提示,在谷歌搜索之后,我发现了一个缩小 PDF 大小的绝妙技巧,我用它把一个 300 MB 的 PDF 缩小到只有 15 MB,分辨率可以接受!所有这一切都与好的 ghostscript,这里是:

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
  • 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。来自Documentation:“作为一种方便的速记,您可以使用-o 选项,后跟上面讨论的输出文件规范。-o 选项还设置-dBATCH-dNOPAUSE 选项。这是为了一种调用ghostscript 来转换一个或多个输入文件的快捷方式。"
  • @Winny 我需要添加dPrinted=false 以保留超链接。否则它会破坏除第一个 pdf 之外的所有链接。见tex.stackexchange.com/questions/245801/…
【解决方案3】:

对不起,我自己用谷歌和一点运气找到了答案:)

对于那些感兴趣的人;

我在我们的 debian 服务器上安装了 pdftk(pdf 工具包),并使用以下命令获得了所需的输出:

pdftk file1.pdf file2.pdf cat output output.pdf

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,而pdfunite不能
  • 与 pdftk 相比,在默认选项中转换提供更好的分辨率。
  • pdftk file1.pdf file2.pdf cat output out.pdf 会将合并后的文件输出为out.pdf
  • pdftk 不适用于 EL7 系统,因为缺少依赖关系 libgcj
【解决方案4】:

如果您有多个文件并且不想一个一个地输入名称,这是最简单的解决方案:

qpdf --empty --pages *.pdf -- out.pdf

【讨论】:

  • qpdf 似乎破坏了文档中的超链接
  • 虽然开始时很难理解复杂的选项,但 qpdf 是一个非常方便且功能强大的工具。在线文档可用here
  • 来到这里寻找qpdf 解决方案,但不想再次浏览文档来弄清楚,谢谢。
  • 只要订单适合您,使用 shell 通配符就很好!先用echo *.pdf | tr ' ' $'\n'左右查看订单!
  • 不错的脚本。您可以通过在每个页面上加上“A_”、“B_”等前缀来排列顺序,或者如果一个文档位于第 1 页并且您希望它位于最后一页,则只需添加 'z',假设您的文件以字母和数字命名,而不是以“z”开头。
【解决方案5】:

pdfjoin a.pdf b.pdf 也将创建一个新的b-joined.pdf,其中包含 a.pdf 和 b.pdf 的内容

【讨论】:

  • 这很好而且简洁,但是会破坏超链接。
  • pdfjoin (pdflatex) 因包含大量页面的文件而失败。无法合并到 1k 页文件。
  • pdfjoin 中断注释或其他非图形项
  • pdfunite 通常运行良好,但如果它显示“未实现的功能:无法合并加密文件”,pdfjoin 是一个不错的选择。无论出于何种原因,pdfjoin 都不会抱怨加密。
  • pdfjam 包不再包含 pdfjoin 脚本。你可以找到脚本here
【解决方案6】:

pdfunite 可以合并整个 PDF。例如,如果您想要 file1.pdf 中的第 2-7 页和 file2.pdf 中的第 1、3、4 页,则必须使用 pdfseparate 将文件拆分为每个页面的单独 PDF 以提供给 pdfunite .

那时您可能想要一个具有更多选项的程序。 qpdf 是我发现的用于处理 PDF 的最佳实用程序。 pdftk 更大更慢,Red Hat/Fedora 不打包它,因为它依赖于 gcj。其他 PDF 实用程序具有 Mono 或 Python 依赖项。我发现qpdf 生成的输出文件比使用pdfseparatepdfunite 将页面组装成30 页的输出PDF(970kB 与1,6450 kB)要小得多。因为它提供了更多的选项,qpdf 的命令行并不那么简单;合并file1和file2的原始请求可以使用

qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf

【讨论】:

  • 这么多。例如,抛物线不再打包pdftk,因为它依赖于gcj,我相信已经放弃了对它的支持。尽管通过pacman -Ss pdf 搜索 pdf 操作工具,我还是错过了这个。感谢您的回答!我应该得到更多的支持,所以它会显示在pdfunitepdftk 的建议旁边。
  • 在我全新安装的 Linux Mint 中,它在终端窗口中运行,无需任何安装或路径调整。不错!
  • 这工作完美,并且还提供了一个更清晰的合并文档,我尝试过的其他命令。感谢您的帖子。
  • 如果 even.pdf 文件中的页面颠倒(在非双面扫描仪上扫描时很常见),您将需要使用它:qpdf --collate --empty --pages odd.pdf even.pdf z-1 -- merged.pdf
【解决方案7】:

你可以直接使用转换命令,

例如

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 所描述的不起作用的副本
  • 不要对 postscript 或 PDF 文件使用转换,除非您从矢量转到光栅并且永不返回。这是一个多么糟糕的主意。
【解决方案8】:

使用来自 python https://pypi.python.org/pypi/pdftools/1.0.6 的 PDF 工具

下载 tar.gz 文件并解压并运行如下命令

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 立即以相同的文件大小完成。
  • 或者你也可以安装它。依赖项的总大小为
【解决方案9】:

Apache PDFBox http://pdfbox.apache.org/

PDFMerger 此应用程序将获取 pdf 文档列表并将它们合并,将结果保存在新文档中。

用法:java -jar pdfbox-app-x.y.z.jar PDFMerger "源 PDF 文件 (2 ..n)" "目标 PDF 文件"

【讨论】:

    【解决方案10】:

    您可以使用sejda-console,免费且开源。 解压并运行sejda-console merge -f file1.pdf file2.pdf -o merged.pdf

    它保留了书签、链接注释、acroforms 等。它实际上有很多可供您使用的选项,只需运行sejda-console merge -h 即可查看所有内容。

    【讨论】:

    • OMHO 是执行此类任务的最佳工具
    • 这不再是开源的
    【解决方案11】:

    我倾向于成为 PyMuPDF(MuPDF 的 Python 绑定)的开发人员之一。

    您可以使用它轻松地做您想做的事(以及更多)。骨架代码是这样工作的:

    #-------------------------------------------------
    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 上。

    【讨论】:

      【解决方案12】:

      如果你想将所有下载的图片转换成一个pdf然后执行

      convert img{0..19}.jpg slides.pdf

      【讨论】:

      • 不要对 postscript 或 PDF 文件使用转换,除非您从矢量转到光栅并且永不返回。这是一个多么糟糕的主意。
      【解决方案13】:

      虽然不是命令行解决方案,但可能对macos用户有所帮助:

      1. 选择您的 PDF 文件
      2. 右键单击突出显示的文件
      3. 选择快速操作 > 创建 PDF

      【讨论】:

        【解决方案14】:

        我赞同pdfunite 的建议。然而,当我尝试合并 > 2k PDF 文件时,我遇到了 Argument list too long 错误。

        为此,我使用 Python 和两个外部包:PyPDF2(处理与 PDF 相关的所有内容)和natsort(对目录的文件名进行“自然”排序)。如果这可以帮助某人:

        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)
        

        【讨论】:

        • "Argument list too long" 表示您正在检查 shell 为环境分配的缓冲区大小——这实际上不是工具的限制。在这种情况下,切换到 Python 可能是多余的,因为您可以批量处理:find input -name *.pdf | xargs -P1 -n500 sh -c 'pdfunite "$@" output-date +%s.pdf' && pdfunite output-*.pdf output.pdf (这将创建批量处理的 500 个文件,使生成的临时文件排序正确的顺序,并生成适当的输出文件;之后您需要清理临时文件)
        • pdftools 是 PyPDF2 的包装器。请参阅this 答案。
        【解决方案15】:

        你可以看到使用免费和开源的pdftools(免责声明:我是它的作者)。

        它基本上是 Latex pdfpages 包的 Python 接口。

        要一个一个地合并pdf文件,你可以运行:

        pdftools --input-file file1.pdf --input-file file2.pdf --output output.pdf
        

        要将目录中的所有 pdf 文件合并在一起,您可以运行:

        pdftools --input-dir ./dir_with_pdfs --output output.pdf
        

        【讨论】:

          【解决方案16】:

          这是我使用的一种有效且易于实施的方法。这将需要 fpdffpdi 库,可在此处下载:

          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');
          

          【讨论】:

            【解决方案17】:

            我喜欢 Chasmo 的想法,但我更喜欢利用诸如此类的东西的优点

            convert $(ls *.pdf) ../merged.pdf
            

            将多个源文件提供给 convert 会导致将它们合并为一个通用 pdf。该命令将实际目录中所有带有.pdfextension的文件合并到父目录中的merged.pdf中。

            【讨论】:

            • 鉴于这看起来与原始问题有多么相似,这似乎应该是一个评论,而不是一个答案。多一点代表,you will be able to post comments。在此之前,请不要使用答案作为解决方法。
            • @Silfheed 不,它回答了问题!虽然答案可能应该更详细。
            • 不要对 postscript 或 PDF 文件使用转换,除非您从矢量转到光栅并且永不返回。这是一个多么糟糕的主意。
            • 使用$(ls *.pdf) 代替简单的通配符*.pdf 有什么意义?
            • 另外参考@firegurafiku 答案,使用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)。
            【解决方案18】:

            PdfCpu 效果很好:

            pdfcpu merge c.pdf a.pdf b.pdf
            

            https://pdfcpu.io/core/merge

            【讨论】:

            • 可以用自制软件安装+1还没试过
            【解决方案19】:

            我从终端使用 qpdf 并在 Windows (Mobaxterm) 和 Linux 上为我工作,例如在新文件 C.pdf 中加入 A.pdf 和 B.pdf 的命令是:

            qpdf --empty --pages oficios/A.pdf informes/B.pdf -- salida/C.PDF

            如果需要更多文档 [https://net2.com/how-to-merge-or-split-pdf-files-on-linux/][1]

            【讨论】:

            • 这是一个被低估的答案。 qpdf 工具很棒
            • 是的,qpdf 是多平台的,可移植的并且可以在脚本中使用
            • 用于提取 qpdf "in.pdf" --pages 。 1 -- "out.pdf"
            【解决方案20】:

            如果你想用 Ghostscript 连接一个目录中的所有 PDF 文件,你可以使用 find 来完成。这是一个例子

            find . -name '*.pdf' -exec gs -o -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=../out.pdf {} +
            

            会在当前目录中查找所有pdf,并在父目录中创建out.pdf。 如果他们正在寻找一种使用 ghostscript 快速创建整个目录的方法,这可能会很有用。

            【讨论】:

              【解决方案21】:
              pdfconcat -o out.pdf 1.pdf 2.pdf
              

              ``pdfconcat 是一个用 ANSI C 编写的小而快的命令行实用程序,可以将多个 PDF 文件连接(合并)成一个长 PDF 文档。''

              【讨论】:

                【解决方案22】:

                这是一个检查合并错误的 Bash 脚本。

                我遇到了一些 PDF 合并产生一些错误消息的问题。 由于查找损坏的 PDF 需要反复试验,因此我为它编写了一个脚本。

                以下 Bash 脚本将一个文件夹中的所有可用 PDF 逐一合并,并在每次合并后显示成功状态。只需将其复制到包含 PDF 的文件夹中并从那里执行即可。

                #!/bin/bash
                
                PDFOUT=_all_merged.pdf
                rm -f "${PDFOUT}"
                
                for f in *.pdf
                do
                  printf "processing %-50s" "$f  ..." >&2
                  if [ -f "$PDFOUT" ]; then
                    # https://stackoverflow.com/questions/8158584/ghostscript-to-merge-pdfs-compresses-the-result
                    #  -dPDFSETTINGS=/prepress
                    status=$(gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="${PDFOUT}.new" "${PDFOUT}" "$f" 2> /dev/null)
                    if [ "$status" ]
                    then
                      echo "gs ERROR: $status" >&2
                    else
                      echo "successful" >&2
                    fi
                    mv "${PDFOUT}.new" "${PDFOUT}"
                  else
                    cp "$f" "${PDFOUT}"
                    echo "successful" >&2
                  fi
                done
                

                示例输出:

                processing inp1.pdf  ...                                     successful
                processing inp2.pdf  ...                                     successful
                

                【讨论】:

                  【解决方案23】:

                  另一个选项,有用的是您还想选择要合并的文档中的页面:

                  pdfjoin image.jpg '-' doc_only_first_pages.pdf '1,2' doc_with_all_pages.pdf '-'
                  

                  它带有包 texlive-extra-utils

                  【讨论】:

                  • 包名可能指的是一个Debian包。
                  猜你喜欢
                  • 2020-10-10
                  • 2013-06-10
                  • 2013-11-20
                  • 1970-01-01
                  • 2013-03-03
                  • 1970-01-01
                  • 2014-12-02
                  • 1970-01-01
                  相关资源
                  最近更新 更多