使用 Pandas Excelwriter 写入 StringIO 对象?

问题描述 投票:0回答:4

我可以将 StringIO 对象传递给 pd.to_csv() 就好了:

io = StringIO.StringIO()
pd.DataFrame().to_csv(io)

但是当使用excel writer时,我遇到了很多麻烦。

io = StringIO.StringIO()
writer = pd.ExcelWriter(io)
pd.DataFrame().to_excel(writer,"sheet name")
writer.save()   

返回

AttributeError: StringIO instance has no attribute 'rfind'

我正在尝试创建一个

ExcelWriter
对象而不调用
pd.ExcelWriter()
但遇到了一些麻烦。这是我到目前为止所尝试过的:

from xlsxwriter.workbook import Workbook
writer = Workbook(io)
pd.DataFrame().to_excel(writer,"sheet name")
writer.save()

但现在我得到了

AttributeError: 'Workbook' object has no attribute 'write_cells'

如何将 Excel 格式的 pandas 数据框保存到

StringIO
对象?

python excel pandas stringio xlsxwriter
4个回答
44
投票

Pandas 需要 ExcelWriter 构造函数的文件名路径,尽管每个编写器引擎都支持

StringIO
。也许这应该作为 Pandas 中的错误/功能请求提出。

同时,这里是一个使用 Pandas

xlsxwriter
引擎的解决方法示例:

import pandas as pd
import StringIO

io = StringIO.StringIO()

# Use a temp filename to keep pandas happy.
writer = pd.ExcelWriter('temp.xlsx', engine='xlsxwriter')

# Set the filename/file handle in the xlsxwriter.workbook object.
writer.book.filename = io

# Write the data frame to the StringIO object.
pd.DataFrame().to_excel(writer, sheet_name='Sheet1')
writer.save()
xlsx_data = io.getvalue()

更新:从 Pandas 0.17 开始,现在可以更直接地执行此操作:

# Note, Python 2 example. For Python 3 use: output = io.BytesIO().
output = StringIO.StringIO()

# Use the StringIO object as the filehandle.
writer = pd.ExcelWriter(output, engine='xlsxwriter')

如果您需要在 Pandas 之外使用输出(例如在 Django 或 Flask 中),请记住倒回 writer:

output.seek(0)

另请参阅 XlsxWriter 文档中的将 Dataframe 输出保存到字符串


11
投票

这些对我来说都不起作用。我有一个想法,我想从 Django 返回一个 Excel 工作簿。我找到了我的解决方案从 pandas 文档

import io
bio = io.BytesIO()
writer = pd.ExcelWriter(bio, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
bio.seek(0)

# BONUS CONTENT
# .. because I wanted to return from an api
response = HttpResponse(bio, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=myfile.xlsx'
return response # returned from a view here

注意,我使用该值作为内容类型,因为根据 mozzilla 文档,它是 mime 类型。来自以下链接中的“.xlsx”。根据需要更换。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types


6
投票

浏览一下 pandas.io.excel 源代码,如果您不介意使用 xlwt 作为编写器,那么这应该不是什么太大的问题。其他引擎可能也不是那么困难,但 xlwt 也很容易,因为它的保存方法采用流或文件路径。

您最初需要传入一个文件名,只是为了让 pandas 满意,因为它会根据引擎检查文件扩展名,以确保它是受支持的格式。但对于 xlwt 引擎,它只是将文件名填充到对象的路径属性中,然后在 save 方法中使用它。如果您更改流的路径属性,当您调用 save 方法时,它会很高兴地保存到该流。

这是一个例子:

import pandas as pd
import StringIO
import base64

df = pd.DataFrame.from_csv('http://moz.com/top500/domains/csv')
xlwt_writer = pd.io.excel.get_writer('xlwt')
my_writer = xlwt_writer('whatever.xls')  #make pandas happy 
xl_out = StringIO.StringIO()
my_writer.path = xl_out  
df.to_excel(my_writer)
my_writer.save()
print base64.b64encode(xl_out.getvalue())

这是一种快速、简单但有点脏的方法。顺便说一句...一种更简洁的方法是对 ExcelWriter 进行子类化(或者它的现有子类之一,例如 _XlwtWriter)——但老实说,更新路径属性涉及的内容很少,我投票给您展示了简单的方法而不是继续路线稍长。


3
投票

对于那些不使用

xlsxwriter
作为
engine=
的人,这里有一个在内存中使用
to_excel
的解决方案:

openpyxl

说明:
in_memory_file = StringIO.StringIO() xlw = pd.ExcelWriter('temp.xlsx', engine='openpyxl') # ... do many .to_excel() thingies xlw.book.save(in_memory_file) # if you want to read it or stream to a client, don't forget this in_memory_file.seek(0)

包装类通过

ExcelWriter
属性公开引擎单独的工作簿。对于
.book
,您可以照常使用
openpyxl
方法!
    

© www.soinside.com 2019 - 2024. All rights reserved.