使用Pandas Excelwriter写入StringIO对象?

A U*_*ser 11 python excel stringio pandas xlsxwriter

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

io = StringIO.StringIO()
pd.DataFrame().to_csv(io)
Run Code Online (Sandbox Code Playgroud)

但是当使用excel编写器时,我遇到了很多麻烦.

io = StringIO.StringIO()
writer = pd.ExcelWriter(io)
pd.DataFrame().to_excel(writer,"sheet name")
writer.save()   
Run Code Online (Sandbox Code Playgroud)

返回一个

AttributeError: StringIO instance has no attribute 'rfind'
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个ExcelWriter没有调用的对象pd.ExcelWriter()但是遇到了一些麻烦.这是我到目前为止所尝试的:

from xlsxwriter.workbook import Workbook
writer = Workbook(io)
pd.DataFrame().to_excel(writer,"sheet name")
writer.save()
Run Code Online (Sandbox Code Playgroud)

但现在我得到了一个 AttributeError: 'Workbook' object has no attribute 'write_cells'

如何将excel格式的pandas数据帧保存到StringIO对象?

jmc*_*ara 28

Pandas期望ExcelWriter构造函数的文件名路径,尽管每个编写器引擎都支持StringIO.也许这应该在Pandas中作为bug /功能请求引发.

与此同时,这是使用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()
Run Code Online (Sandbox Code Playgroud)

更新:从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')
Run Code Online (Sandbox Code Playgroud)

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

  • 这只是在熊猫中添加的,请参见此处:https://github.com/pydata/pandas/pull/10376.将在0.17.0发布(7月底) (3认同)
  • 对我来说它有很大帮助 - 但在将输出提供给 Flask 时缺少一件关键的事情:output.seek(0) (2认同)

Nic*_*ady 12

这些对我来说都不起作用。我有一个想法,我想从 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
Run Code Online (Sandbox Code Playgroud)

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


clo*_*her 5

如果你不介意使用xlwt作为你的编写器,那么看一下pandas.io.excel源看起来不应该是一个太大的问题.其他引擎可能也不是那么困难,但是xlwt很容易跳出来,因为它的save方法需要一个流或一个文件路径.

你需要最初传入一个文件名只是为了让pandas高兴,因为它检查引擎的文件扩展名,以确保它是一种支持的格式.但是在xlwt引擎的情况下,它只是将文件名填充到对象的path属性中,然后在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())
Run Code Online (Sandbox Code Playgroud)

这是快速,简单和略微肮脏的方式.顺便说一句......一个更简洁的方法就是继承ExcelWriter(或其中一个现有的子类,例如_XlwtWriter) - 但老实说,更新路径属性所涉及的很少,我投票给你展示简单的方法而不是去稍长的路线.