2012-09-05 26 views
6

Ich benutze Stackoverflow schon eine Weile und es hat mir sehr geholfen. Jetzt habe ich ein Problem, das ich selbst oder durch Suchen nicht lösen konnte. Ich versuche meine von openpyxl erzeugte Excel-Datei im Browser auszugeben, so wie ich es mit phpexcel gemacht habe. Die Methode scheint die gleiche zu sein, aber ich bekomme nur eine defekte Datei. Mein Code sieht so aus:Wie gebe ich xlsx aus, das von Openpyxl zum Browser generiert wurde?

from openpyxl.workbook import Workbook 
from openpyxl.writer.excel import ExcelWriter 
from openpyxl.writer.excel import save_virtual_workbook 
from openpyxl.cell import get_column_letter 
from StringIO import StringIO 

print 'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
print 'Content-Disposition: attachment;filename="results.xlsx"' 
print 'Cache-Control: max-age=0\n' 

output = StringIO() 

wb = Workbook() 

ws = wb.worksheets[0] 

ws.cell('A1').value = 3.14 

wb.save(output) 
print output.getvalue() 
#print save_virtual_workbook(wb) 

Ich benutze die Version 1.5.8 und Python 2.7. Keiner der Ansätze funktioniert. Wenn ich es nur vom Desktop und nicht vom Browser verwende, funktioniert es einwandfrei. Ich wäre sehr dankbar für Hilfe.

P.S. Bitte sagen Sie mir nicht, dass die Verwendung anderer Sprachen oder Programme einfacher wäre. Ich muss das mit Python lösen.

+0

Aus dieser Frage nehme ich an, Sie haben keine Erfahrungen über Web-Programmierung in Python. Sie können diesen Code nicht in eine * .py-Datei in Ihrem Dokumentstammverzeichnis einfügen und erwarten, dass er wie eine * .php-Datei ausgeführt wird. – Dikei

+0

Ihre Content- * Header sehen fehlerhaft aus. Sie sollten CR/LF Zeilenendungen verwenden. Kannst du ein einfaches 'text/html'-Sample erhalten, das korrekt von diesem Skript bedient wird? Wenn nein, fixiere das zuerst. – tripleee

+0

Ich habe genug Erfahrung zu wissen, um es von CGI-bin zu starten. Ich habe andere Skripts ausgeführt. Dies ist der erste, der nicht ausgibt, was ich brauche. Ja, sauber Text/HTML funktioniert perfekt, zumindest soweit ich getestet habe. Ich sehe nicht, warum ich CR/LF benutzen sollte ... – seeebek

Antwort

-5

Wenn Sie eine HTML-Tabelle erstellen möchten, die wie Ihre Tabelle aussieht, möchten Sie wahrscheinlich mit CSV arbeiten. Tun Sie dies statt Excel oder konvertieren Sie Ihr Excel nach dem Erstellen in CSV.

Auf jedem Fall, wenn Sie die Daten im CSV-Format haben, dann ist es einfach eine Frage des Python mit der HTML-Seite und Looping durch die CSV-Daten zu bauen, während der <table> Einfügen <tr> und <td> Tags, gegebenenfalls .

+0

Ja, ich habe nicht zu viel Erfahrung mit Web-Programmierung in Python. Mein Mork ist es, einige dieser Apps von PHP in Python zu übersetzen und jetzt stehe ich mit phppyton -> openpyxl fest. Ich brauche das gleiche Verhalten. welches Daten von einem anderen Skript erhält, es an dieses Skript sendet, es in eine Excel-Datei schreibt und als Download in den Browser ausgibt. Möglicherweise ohne vorher auf dem Server zu speichern. – seeebek

+0

@David die Frage bezieht sich speziell auf das Bereitstellen einer Excel-Datei. –

0

Ihre Skripte funktionieren für mich so, wie Sie es ohne Änderungen erwarten.

Ich kann nur annehmen, dass Sie ein Problem mit Ihrem CGI-Skript-Setup haben.

Stellen Sie sicher, dass das Verzeichnis, in dem das Skript läuft, tatsächlich vom Webserver bedient wird. Auf Apache können Sie dies mit erreichen:

ScriptAlias /cgi-bin/ /home/WWW/localhost/cgi-bin/ 

Stellen Sie sicher, das Skript, indem die Skriptberechtigungen excutable ist. Für die Kommandozeile (python scriptname) war das nicht nötig, für Ihren Webbrowser also. Und stellen Sie sicher, dass der Besitzer des Webservers die Skripte ausführen kann, da der Webserver wahrscheinlich nicht so läuft wie Sie.

1

Das Schreiben der xlsx-Ausgabe auf die Festplatte und die anschließende Bereitstellung über Apache funktionierten einwandfrei, aber das Aussetzen führte direkt zu Fehlern in Excel und anderen Problemen.

Ich habe ein paar zusätzliche Schritte und machte eine kleine Änderung an Ihrem Code:

buffer=output.getvalue() 

In den HTTP-Header:

print "Content-Length: " + str(len(buffer)) 

Und verwendet write() statt print() den Puffer zu schieben und in der Standardausgangsstrom:

stdout.write(buffer) 
+0

+1 für den Header "Content-Length". Ich könnte das nicht ohne es funktionieren. Wenn ich 'print save_virtual_workbook (wb)' benutzte, hatte meine resultierende komprimierte Datei zwei zusätzliche Bytes. Wenn ich 'stdout.write()' benutzte, hatte es ein zusätzliches Byte. Die Bereitstellung von 'Content-Length' hat es behoben. – Auspex

5

das ist Arbeit für mich. Ich benutze python 2.7 und aktuelle openpyxl und send_file von Kolben

... code ... 

import StringIO 
from openpyxl import Workbook 
wb = Workbook() 
ws = wb.active # worksheet 
ws.title = "Excel Using Openpyxl" 
c = ws.cell(row=5, column=5) 
c.value = "Hi on 5,5" 
out = StringIO.StringIO() 
wb.save(out) 
out.seek(0) 

return send_file(out, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 
      attachment_filename='xxl.xlsx', as_attachment=True) 
+2

Das ist schreckliches Aliasing! 'from io import BytesIO' ist der Weg dies zu tun. –

0

Da Excel ein binäres Format verwendet, sollten Sie BytesIO verwenden zu puffern.

from io import BytesIO

Aber welche Fehlermeldung erhalten Sie, wenn Sie save_virtual_workbook() verwenden, die tut dies für Sie?

2
output = HttpResponse(mimetype='application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') 
file_name = "Test.xlsx" 
output['Content-Disposition'] = 'attachment; filename='+ file_name 

wb = Workbook() 

ws = wb.worksheets[0] 

ws.cell('A1').value = 3.14 

wb.save(output) 

return output 

Ich habe diese Tipps verwendet, um meine Dateien mit openpyxl herunterzuladen. Hoffe, das wird helfen