【问题标题】:Combine two lists of PDFs one to one using Python使用 Python 一对一组合两个 PDF 列表
【发布时间】:2012-06-05 23:15:02
【问题描述】:

我在 ESRI ArcMap 10 中使用数据驱动页面创建了一系列 PDF 文档(地图)。每个地图都有一个页面 1 和页面 2,每个地图都是从单独的 *.mxd 生成的。因此,我有一份包含每张地图第 1 页的 PDF 文档列表和一份包含每张地图第 2 页的 PDF 文档列表。例如:Map1_001.pdf、map1_002.pdf、map1_003.pdf...map2_001.pdf、map2_002.pdf、map2_003.pdf...等等。

我想将这些地图(第 1 页和第 2 页)附加在一起,以便将第 1 页和第 2 页放在每个地图的一个 PDF 中。例如:mapboth_001.pdf、mapboth_002.pdf、mapboth_003.pdf...(它们不必进入新的pdf文件(mapboth),可以将它们附加到map1)

对于每个地图1_ *.pdf 遍历目录并在文件名中的数字(* 所在的位置)匹配的地方附加 map2_ *.pdf

必须有一种方法可以使用 python 来做到这一点。也许结合使用 arcpy、os.walk 或 os.listdir,以及 pyPdf 和 for 循环?

对于 os.walk(datadirectory) 中的 pdf:

      ??

有什么想法吗?感谢您的帮助。

【问题讨论】:

    标签: python pdf append pypdf


    【解决方案1】:

    PDF 文件的结构与纯文本文件不同。简单地将两个 PDF 文件放在一起是行不通的,因为文件的结构和内容可能会被覆盖或损坏。您当然可以自己创作,但这需要相当长的时间,并且需要深入了解 PDF 的内部结构。

    也就是说,我建议您查看pyPDF。它支持您正在寻找的合并功能。

    【讨论】:

    • ...在Python中处理二进制数据是完全可能的。
    • 是的,我很清楚这一点。然而,处理二进制数据和处理它很好是两件不同的事情。
    • 如果你的答案说“.pdf 是一种复杂的格式;简单地连接文件会失败,编写自己的代码来操作它会非常复杂。”
    • 我想我会同意的。
    【解决方案2】:

    这应该正确地找到并整理所有要合并的文件;它仍然需要实际的 .pdf 合并代码。

    编辑:我添加了基于the pyPdf example code 的pdf 编写代码。它没有经过测试,但应该(据我所知)可以正常工作。

    Edit2:意识到我有地图编号的十字路口;重新调整它以合并正确的地图集。

    import collections
    import glob
    import re
    
    # probably need to install this module -
    #   pip install pyPdf
    from pyPdf import PdfFileWriter, PdfFileReader
    
    def group_matched_files(filespec, reg, keyFn, dataFn):
        res = collections.defaultdict(list)
        reg = re.compile(reg)
        for fname in glob.glob(filespec):
            data = reg.match(fname)
            if data is not None:
                res[keyFn(data)].append(dataFn(data))
        return res
    
    def merge_pdfs(fnames, newname):
        print("Merging {} to {}".format(",".join(fnames), newname))
    
        # create new output pdf
        newpdf = PdfFileWriter()
    
        # for each file to merge
        for fname in fnames:
            with open(fname, "rb") as inf:
                oldpdf = PdfFileReader(inf)
                # for each page in the file
                for pg in range(oldpdf.getNumPages()):
                    # copy it to the output file
                    newpdf.addPage(oldpdf.getPage(pg))
    
        # write finished output
        with open(newname, "wb") as outf:
            newpdf.write(outf)
    
    def main():
        matches = group_matched_files(
            "map*.pdf",
            "map(\d+)_(\d+).pdf$",
            lambda d: "{}".format(d.group(2)),
            lambda d: "map{}_".format(d.group(1))
        )
        for map,pages in matches.iteritems():
            merge_pdfs((page+map+'.pdf' for page in sorted(pages)), "merged{}.pdf".format(map))
    
    if __name__=="__main__":
        main()
    

    【讨论】:

      【解决方案3】:

      我没有任何可以尝试组合的测试 pdf,但我使用 cat 命令对文本文件进行了测试。 你可以试试这个(我假设是基于 unix 的系统):merge.py

      import os, re
      files = os.listdir("/home/user/directory_with_maps/")
      files = [x for x in files if re.search("map1_", x)]
      while len(files) > 0:
          current = files[0]
          search = re.search("_(\d+).pdf", current)
          if search:
              name = search.group(1)
              cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=FULLMAP_%s.pdf %s map2_%s.pdf" % (name, current, name)
              os.system(cmd)
          files.remove(current)
      

      基本上它会遍历并获取 maps1 列表,然后遍历并假定正确的文件并仅遍历数字。 (我可以看到使用计数器来执行此操作并用 0 填充以获得类似的效果)。

      首先测试 gs 命令,我只是从http://hints.macworld.com/article.php?story=2003083122212228 获取的。

      【讨论】:

        【解决方案4】:

        在 googlecode 的 pdfrw 项目页面上有如何执行此操作的示例:

        http://code.google.com/p/pdfrw/wiki/ExampleTools

        【讨论】:

          猜你喜欢
          • 2017-04-12
          • 2022-12-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-14
          • 1970-01-01
          • 2015-10-30
          • 1970-01-01
          相关资源
          最近更新 更多