PyPDF2:复制PDF会产生空白页

2024-09-29 19:25:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用PyPDF2修改一个PDF文档(添加书签)。所以我需要读入整个源PDF文件,并把它写出来,尽可能保持数据的完整性。仅仅将每个页面写入一个新的PDF对象可能不足以保存文档元数据。

PdfFileWriter()确实有许多复制整个文件的方法:cloneDocumentFromReaderappendPagesFromReader和{}。然而,他们都有问题。

如果我使用cloneDocumentFromReaderappendPagesFromReader,我会得到一个有效的PDF文件,并且有正确的页数,但是所有页面都是空白的。

如果我使用cloneReaderDocumentRoot,我将得到一个最小的有效PDF文件,但是没有页面或数据。

This has been asked before,但没有成功的答案。 其他问题也问过Blank pages in PyPDF2,但我不能应用给出的答案。

我的代码是:

def bookmark(incomingFile):
    fileObj = open(incomingFile, 'rb')
    output = PdfFileWriter()
    input = PdfFileReader(fileObj)

    output.appendPagesFromReader(input)
    #output.cloneDocumentFromReader(input)
    myTableOfContents = [
            ('Page 1', 0), 
            ('Page 2', 1),
            ('Page 3', 2)
            ]
    # output.addBookmark(title, pagenum, parent=None, color=None, bold=False, italic=False, fit='/Fit')
    for title, pagenum in myTableOfContents:
        output.addBookmark(title, pagenum, parent=None)

    output.setPageMode("/UseOutlines")

    outputStream = open(incomingFile, "wb")
    output.write(outputStream)
    outputStream.close()
    fileObj.close()

当PyPDF2不能向PdfFileWriter对象添加书签时,我往往会出错,因为它没有任何页面或类似的页面。


Tags: 文件noneinputoutputpdftitlepage页面
1条回答
网友
1楼 · 发布于 2024-09-29 19:25:26

我也为此绞尽脑汁,最后发现PyPDF2有这个issue。 基本上,我将this answer's代码复制到C:\ProgramData\Anaconda3\lib\site-packages\PyPDF2\pdf.py(这将取决于您的发行版)中cloneDocumentFromReader函数的第382行。在

之后,我可以用writer.cloneDocumentFromReader(pdf)reader页附加到writer中,并且在我的例子中,可以更新PDF元数据(主题、关键字等)。在

希望这对你有帮助

    '''
    Create a copy (clone) of a document from a PDF file reader

    :param reader: PDF file reader instance from which the clone
        should be created.
    :callback after_page_append (function): Callback function that is invoked after
        each page is appended to the writer. Signature includes a reference to the
        appended page (delegates to appendPagesFromReader). Callback signature:

        :param writer_pageref (PDF page reference): Reference to the page just
            appended to the document.
    '''
    debug = False
    if debug:
        print("Number of Objects: %d" % len(self._objects))
        for obj in self._objects:
            print("\tObject is %r" % obj)
            if hasattr(obj, "indirectRef") and obj.indirectRef != None:
                print("\t\tObject's reference is %r %r, at PDF %r" % (obj.indirectRef.idnum, obj.indirectRef.generation, obj.indirectRef.pdf))

    # Variables used for after cloning the root to
    # improve pre- and post- cloning experience

    mustAddTogether = False
    newInfoRef = self._info
    oldPagesRef = self._pages
    oldPages = self.getObject(self._pages)

    # If there have already been any number of pages added

    if oldPages[NameObject("/Count")] > 0:

        # Keep them

        mustAddTogether = True
    else:

        # Through the page object out

        if oldPages in self._objects:
            newInfoRef = self._pages
            self._objects.remove(oldPages)

    # Clone the reader's root document

    self.cloneReaderDocumentRoot(reader)
    if not self._root:
        self._root = self._addObject(self._root_object)

    # Sweep for all indirect references

    externalReferenceMap = {}
    self.stack = []
    newRootRef = self._sweepIndirectReferences(externalReferenceMap, self._root)

    # Delete the stack to reset

    del self.stack

    #Clean-Up Time!!!

    # Get the new root of the PDF

    realRoot = self.getObject(newRootRef)

    # Get the new pages tree root and its ID Number

    tmpPages = realRoot[NameObject("/Pages")]
    newIdNumForPages = 1 + self._objects.index(tmpPages)

    # Make an IndirectObject just for the new Pages

    self._pages = IndirectObject(newIdNumForPages, 0, self)

    # If there are any pages to add back in

    if mustAddTogether:

        # Set the new page's root's parent to the old
        # page's root's reference

        tmpPages[NameObject("/Parent")] = oldPagesRef

        # Add the reference to the new page's root in
        # the old page's kids array

        newPagesRef = self._pages
        oldPages[NameObject("/Kids")].append(newPagesRef)

        # Set all references to the root of the old/new
        # page's root

        self._pages = oldPagesRef
        realRoot[NameObject("/Pages")] = oldPagesRef

        # Update the count attribute of the page's root

        oldPages[NameObject("/Count")] = NumberObject(oldPages[NameObject("/Count")] + tmpPages[NameObject("/Count")])

    else:

        # Bump up the info's reference b/c the old
        # page's tree was bumped off

        self._info = newInfoRef

相关问题 更多 >

    热门问题