【问题标题】:How to attach mulitple files in PDF?如何在 PDF 中附加多个文件?
【发布时间】:2019-11-28 09:17:22
【问题描述】:

我有一个对象列表:List = ['Doc1.xlsx','Doc2.csv','Doc3.pdf'] 及其名称列表:List1 = ['Doc1_name.xlsx','Doc2_name.csv','Doc3_name.pdf']。 我需要将它们附加到现有的 PDF 中。我尝试使用以下代码,该代码仅在我有一个附件时才有效。现在我正在尝试遍历附件以附加所有附件,但在Final.pdf 中将仅附加最后一个对象'Doc3.pdf'

fileReader = PdfFileReader('Existing_pdf.pdf', 'rb')
fileWriter = PdfFileWriter()
fileWriter = appendPagesFromReader(fileReader)

for j in range(1, len(List)):
    fileWriter.addAtachment(List1[j],List[j])

with open('Final.pdf', 'wb') as output_pdf:
    fileWriter.write(output_pdf)

【问题讨论】:

    标签: python python-3.x pdf attachment pypdf2


    【解决方案1】:

    在我看来,addAttachment-Method 总是替换当前附件。

    来自PyPDF2 Github中的pdf.py:

    def addAttachment(self, fname, fdata):
        file_entry = DecodedStreamObject()
        file_entry.setData(fdata)
        file_entry.update({
                NameObject("/Type"): NameObject("/EmbeddedFile")
                })
    
        efEntry = DictionaryObject()
        efEntry.update({ NameObject("/F"):file_entry })
    
        filespec = DictionaryObject()
        filespec.update({
                NameObject("/Type"): NameObject("/Filespec"),
                NameObject("/F"): createStringObject(fname),  # Perhaps also try TextStringObject
                NameObject("/EF"): efEntry
                })
    
        embeddedFilesNamesDictionary = DictionaryObject()
        embeddedFilesNamesDictionary.update({
                NameObject("/Names"): ArrayObject([createStringObject(fname), filespec])
                })
    
        embeddedFilesDictionary = DictionaryObject()
        embeddedFilesDictionary.update({
                NameObject("/EmbeddedFiles"): embeddedFilesNamesDictionary
                })
        # Update the root
        self._root_object.update({
            NameObject("/Names"): embeddedFilesDictionary
            })
    

    我相信的地方

    self._root_object.update({
            NameObject("/Names"): embeddedFilesDictionary
            })
    

    替换附件,而不是添加它。

    编辑: 这个脚本对我有用,可以附加两个 .txt 文件。 它使用上面的addAttachment 方法,我稍微调整了它以启用附加多个文件。

    from PyPDF2 import PdfFileReader, PdfFileWriter
    from PyPDF2.generic import DecodedStreamObject, NameObject, DictionaryObject, createStringObject, ArrayObject
    
    
    def appendAttachment(myPdfFileWriterObj, fname, fdata):
        # The entry for the file
        file_entry = DecodedStreamObject()
        file_entry.setData(fdata)
        file_entry.update({NameObject("/Type"): NameObject("/EmbeddedFile")})
    
        # The Filespec entry
        efEntry = DictionaryObject()
        efEntry.update({ NameObject("/F"):file_entry })
    
        filespec = DictionaryObject()
        filespec.update({NameObject("/Type"): NameObject("/Filespec"),NameObject("/F"): createStringObject(fname),NameObject("/EF"): efEntry})
    
        if "/Names" not in myPdfFileWriterObj._root_object.keys():
            # No files attached yet. Create the entry for the root, as it needs a reference to the Filespec
            embeddedFilesNamesDictionary = DictionaryObject()
            embeddedFilesNamesDictionary.update({NameObject("/Names"): ArrayObject([createStringObject(fname), filespec])})
    
            embeddedFilesDictionary = DictionaryObject()
            embeddedFilesDictionary.update({NameObject("/EmbeddedFiles"): embeddedFilesNamesDictionary})
            myPdfFileWriterObj._root_object.update({NameObject("/Names"): embeddedFilesDictionary})
        else:
            # There are files already attached. Append the new file.
            myPdfFileWriterObj._root_object["/Names"]["/EmbeddedFiles"]["/Names"].append(createStringObject(fname))
            myPdfFileWriterObj._root_object["/Names"]["/EmbeddedFiles"]["/Names"].append(filespec)
    
    
    fr = PdfFileReader('dummy.pdf','rb')
    fw = PdfFileWriter()
    fw.appendPagesFromReader(fr)
    
    my_attach_files = ['test.txt','test2.txt']
    for my_test in my_attach_files:
        with open(my_test, 'rb') as my_test_attachment:
            my_test_data = my_test_attachment.read()
        appendAttachment(fw, my_test, my_test_data)
    
    with open('dummy_new.pdf','wb') as file:
        fw.write(file)
    

    希望这对你有用。

    【讨论】:

    • 我不知道,我应该在这里更改什么来获取所有文件。有没有其他可能的方法来附加多个文件? (其他python包)?
    • 我已经用一个脚本编辑了我的答案,该脚本定义了一个添加多个附件的新函数。试试这是否适合你
    猜你喜欢
    • 2019-02-08
    • 2016-02-07
    • 2018-06-12
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 2017-09-18
    • 2011-03-01
    • 1970-01-01
    相关资源
    最近更新 更多