【问题标题】:How to "write to variable" instead of "to file" in Python如何在 Python 中“写入变量”而不是“写入文件”
【发布时间】:2014-12-19 04:34:40
【问题描述】:

我正在尝试编写一个将 pdf 拆分为单独页面的函数。来自this SO answer。我复制了一个简单的函数,将 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

但是,这会将新 PDF 写入文件,而不是将新 PDF 列表作为文件变量返回。于是我把output.write(outputStream)这一行改成了:

pages.append(outputStream)

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

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

【问题讨论】:

  • 您是否尝试过读取数据,而不是存储文件句柄 - pages.append(outputStream.read())
  • 你试过用cStringIO.StringIO打开outputStream吗?
  • 上述用户所说的...您通常可以将StringIO 对象替换为文件并将结果作为字符串输出
  • @jonrsharpe - 我刚刚尝试过,这给了我一个IOError: File not open for reading 在线留言pages.append(outputStream.read())。还有其他想法吗?
  • @user4815162342 - 嗯,不,我没有尝试过 StringIO。关于如何做到这一点的任何提示?一个代码示例将非常受欢迎.. :)

标签: python pdf io outputstream pypdf


【解决方案1】:

“作为文件变量的 PDF 列表”的含义并不完全清楚。如果要创建字符串而不是包含 PDF 内容的文件,并返回此类字符串的列表,请替换 @ 987654321@ 和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

【讨论】:

  • (此答案仅适用于 Python 2)
  • @Garrett 不过,适应 Python 3 应该很简单。
【解决方案2】:

您可以在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

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

import shutil

with open('page0.pdf', 'wb') as out:
    shutil.copyfileobj(pages[0], out)

【讨论】:

    【解决方案3】:

    没用过PdfFileWriter,但觉得应该可以。

    def splitPdf(file_):
        pdf = PdfFileReader(file_)
        pages = []
        for i in range(pdf.getNumPages()):
            output = PdfFileWriter()
            output.addPage(pdf.getPage(i))
            pages.append(output)
        return pages
    
    def writePdf(pages):
        i = 1
        for p in pages:
            with open("document-page%s.pdf" % i, "wb") as outputStream:
                p.write(outputStream)
            i += 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      相关资源
      最近更新 更多