簡體   English   中英

如何在 Python 3 中將演示文稿保存到類似文件的對象

[英]How to save a presentation to a file-like object in Python 3

Python 3 用StringIO.StringIO替換了io.StringIO 我已經能夠使用前者成功保存演示文稿,但它似乎不適用於后者。

from pptx import Presentation
from io import StringIO

presentation = Presentation('presentation.pptx')
output = StringIO()
presentation.save(output)

上面的代碼產生:

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\site-packages\\pptx\\presentation.py", line 46, in save self.part.save(file) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\site-packages\\pptx\\parts\\presentation.py", line 118, in save self.package.save(path_or_stream) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\site-packages\\pptx\\opc\\package.py", line 166, in save PackageWriter.write(pkg_file, self.rels, self.parts) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\site-packages\\pptx\\opc\\pkgwriter.py", line 33, in write PackageWriter._write_content_types_stream(phys_writer, parts) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\site-packages\\pptx\\opc\\pkgwriter.py", line 47, in _write_content_types_stream phys_writer.write(CONTENT_TYPES_URI, content_types_blob) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\site-packages\\pptx\\opc\\phys_pkg.py", line 156, in write self._zipf.writestr(pack_uri.membername, blob) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\zipfile.py", line 1645, in writestr with self.open(zinfo, mode='w') as dest: File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\zipfile.py", line 1349, in open return self._open_to_write(zinfo, force_zip64=force_zip64) File "C:\\Users\\mgplante\\AppData\\Local\\Continuum\\Anaconda2\\envs\\ppt_gen\\lib\\zipfile.py", line 1462, in _open_to_write self.fp.write(zinfo.FileHeader(zip64)) TypeError: string argument expected, got 'bytes'

有沒有辦法在 Python 3 中將演示文稿保存到類似文件的對象,或者我將不得不在這個項目中使用 Python 2?

BytesIO()怎么樣?

from pptx import Presentation
from io import BytesIO

presentation = Presentation('presentation.pptx')
output = BytesIO()
presentation.save(output)
output.seek(0)
# from here do what you like with output, e.g. pass it to something expecting bytes with output.read()

這至少消除了錯誤。

Hannu 的回答非常正確,正是用於在python-pptx測試套件中驗證此行為的代碼:

stream = BytesIO()
presentation.save(stream)

https://github.com/scanny/python-pptx/blob/master/features/steps/presentation.py#L105

如果該代碼給你一個空白的演示文稿,那么其他事情正在發生。 我會重現該行為,使其穩定且可重復,然后提出“為什么我得到一個空白演示文稿?”的問題。 在另一個 SO 問題中,用它發布給你這種行為的完整的最小代碼。

這是我第二次聽說這樣的事情,這讓我懷疑實際上在幕后發生了一些系統性的事情來產生這種行為。 但與此同時,作為嘗試保存到流的部分失敗,您最終得到一個完整的演示文稿,只是沒有幻燈片,這是極不可能的。

可能導致這種情況的常見情況是保存新打開的默認演示文稿,例如:

prs = Presentation()
output = BytesIO()
prs.save(output)

這當然不是你可能會故意做的事情,但很容易偶然做到,所以我想我會提到。

如果你能幫助我們重復你的結果,我們會弄清楚的:)

我在開發類似 CGI 的演示文稿時遇到了同樣的問題。 我的 pptx 應該作為文件發送給用戶。 您可以使用 BytesIO 而不是 StringIO 將 pptx 作為文件發送

qs = cgi.FieldStorage()
link = qs.getfirst('link', 'default_link_for_debug')

...
...

target_stream = BytesIO()
prs.save(target_stream)
target_stream.seek(0) # important!

length = target_stream.getbuffer().nbytes
buffer = target_stream.getbuffer()
#buffer = target_stream.read() # it also works

if 'HTTP_HOST' in os.environ:
    sys.stdout.buffer.write(b'Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation\r\n')
    sys.stdout.buffer.write('Content-Disposition: attachment; filename="offer-{0}.pptx"\r\n'.format(link).encode('ascii'))
    sys.stdout.buffer.write('Content-Length: {0}\r\n'.format(length).encode('ascii'))
    sys.stdout.buffer.write(b'Pragma: no-cache\r\n')
    sys.stdout.buffer.write(b'\r\n')
    sys.stdout.buffer.write(buffer)

else: # for debug
    with open("offer-{0}.pptx".format(link),'wb') as out: 
        out.write(buffer) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM