2015-01-21 12 views
8

mogę przekazać obiekt StringIO do pd.to_csv() po prostu w porządku:Zapis do obiektu StringIO przy użyciu Pandas Excelwriter?

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

Ale podczas korzystania z pisarzem Excel, mam dużo więcej kłopotów.

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

Zwraca

AttributeError: StringIO instance has no attribute 'rfind' 

próbuję utworzyć obiekt ExcelWriter bez wywoływania pd.ExcelWriter() ale mam pewne problemy. To, co starałem dotąd:

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

Ale teraz jestem coraz AttributeError: 'Workbook' object has no attribute 'write_cells'

Jak mogę zapisać dataframe pandy w formacie Excel do StringIO obiektu?

+1

Nie jestem pewien, czy możesz, a przynajmniej nie łatwo. Argumentem 'to_excel' jest * ścieżka * do pliku Excel, a nie rzeczywisty obiekt pliku. Dlaczego mimo to chcesz utworzyć reprezentację pliku Excel w pamięci? – BrenBarn

+0

Za pomocą Flask, aby pobrać raport do pobrania. –

Odpowiedz

16

Panda oczekuje nazwy ścieżki do konstruktorów ExcelWriter, chociaż każdy z silników zapisujących obsługuje StringIO. Być może to powinno być podniesione jako prośba o błąd/funkcję w Pandach.

W międzyczasie o to obejście przykład za pomocą silnika Pandy 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() 

Aktualizacja: Począwszy od Pandy 0,17 jest obecnie możliwe, aby to zrobić bardziej bezpośrednio:

# 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') 

Zobacz także Saving the Dataframe output to a string w dokumentacji XlsxWriter.

+0

Dziękuję - obejście w jednym wierszu działało idealnie! –

+3

To zostało właśnie dodane w pandach, zobacz tutaj: https://github.com/pydata/pandas/pull/10376. Będzie w wersji 0.17.0 (prawdopodobnie na końcu lipca) – Jeff

5

Spoglądanie na źródło pandas.io.excel wygląda na to, że nie powinno to być zbyt dużym problemem, jeśli nie masz nic przeciwko używaniu xlwt jako pisarza. Inne silniki mogą nie być tak trudne, ale xlwt wyskakuje równie łatwo, ponieważ jego metoda zapisu przyjmuje strumień lub ścieżkę do pliku.

Musisz najpierw przekazać nazwę pliku tylko po to, aby pandy były szczęśliwe, ponieważ sprawdza rozszerzenie nazwy pliku przed silnikiem, aby upewnić się, że jest obsługiwany. Ale w przypadku silnika xlwt po prostu umieszcza nazwę pliku w atrybucie ścieżki obiektu, a następnie używa go w metodzie zapisu. Jeśli zmienisz atrybut ścieżki do swojego strumienia, z przyjemnością zapiszesz ten strumień, gdy zadzwonisz do metody zapisu.

Oto przykład:

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()) 

To szybki, łatwy i nieco brudny sposób to zrobić. BTW ... czystszym sposobem na to jest podklasa ExcelWriter (lub jedna z jego istniejących podklas, np. _XlwtWriter) - ale szczerze mówiąc, tak mało jest zaangażowanych w aktualizowanie atrybutu ścieżki, głosowałem, aby pokazać ci prostą drogę, zamiast iść nieco dłuższa trasa.

2

Dla tych, którzy nie stosując xlsxwriter ich engine= dla to_excel o to rozwiązanie do korzystania openpyxl w pamięci:

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) 

wyjaśnienie: klasa ExcelWriter wrapper naraża silników indywidualnego skoroszytu za pośrednictwem właściwości .book.Dla openpyxl możesz wtedy użyć metody Workbook.save!

Powiązane problemy