如何在Python中“写入变量”而不是“写入文件”

kra*_*r65 2 python pdf io outputstream pypdf

我正在尝试编写一个将pdf拆分为单独页面的函数。从这个SO答案。我复制了一个简单的函数,该函数将pdf拆分为单独的页面:

def splitPdf(file_):
    pdf = PdfFileReader(file_)
    pages = []
    for i in range(pdf.getNumPages()):
        output = PdfFileWriter()
        output.addPage(pdf.getPage(i))
        with open("document-page%s.pdf" % i, "wb") as outputStream:
            output.write(outputStream)
    return pages
Run Code Online (Sandbox Code Playgroud)

但是,这会将新的PDF写入文件,而不是将新PDF的列表作为文件变量返回。因此,我将行更改output.write(outputStream)为:

pages.append(outputStream)
Run Code Online (Sandbox Code Playgroud)

但是,当尝试在页面列表中写入元素时,出现了ValueError: I/O operation on closed file

有人知道我如何将新文件添加到列表中并返回它们,而不是将它们写入文件吗?欢迎所有提示!

par*_*ent 5

您可以在io模块中使用内存中的二进制流。这会将pdf文件存储在您的内存中。

import io

def splitPdf(file_):
    pdf = PdfFileReader(file_)
    pages = []
    for i in range(pdf.getNumPages()):
        outputStream = io.BytesIO()

        output = PdfFileWriter()
        output.addPage(pdf.getPage(i))
        output.write(outputStream)

        # Move the stream position to the beginning,
        # making it easier for other code to read
        outputStream.seek(0)

        pages.append(outputStream)
    return pages
Run Code Online (Sandbox Code Playgroud)

稍后要将对象写入文件,请使用shutil.copyfileobj

import shutil

with open('page0.pdf', 'wb') as out:
    shutil.copyfileobj(pages[0], out)
Run Code Online (Sandbox Code Playgroud)


use*_*342 5

还不清楚“作为文件变量的PDF列表”是什么意思。如果要创建字符串而不是包含PDF内容的文件,并返回这样的字符串列表,请open()使用StringIO和调用getvalue()以获取内容:

import cStringIO

def splitPdf(file_):
    pdf = PdfFileReader(file_)
    pages = []
    for i in range(pdf.getNumPages()):
        output = PdfFileWriter()
        output.addPage(pdf.getPage(i))
        io = cStringIO.StringIO()
        output.write(io)
        pages.append(io.getvalue())
    return pages
Run Code Online (Sandbox Code Playgroud)