GAE/webapp2:服务 Excel 由脚本使用 xlwt 创建的文件
GAE/webapp2: Serving Excel file created by script using xlwt
我正在尝试使用 google 应用程序引擎,webapp2
and a script based on xlwt
调用其 save
方法来创建特定的 excel 文件 原位,让用户自己下载。
现在我已经根据不同的网站尝试了几种不同的方法,但是 none 到目前为止都没有成功。我将概述我的尝试,如果你们中有人知道如何让它工作,我将不胜感激。
非常感谢。如果您需要更多信息,请告诉我,我会立即更新,我看到了。
注意
xls_create(arg, filename_or_stream)
是调用 xlwt.save() 并创建要下载的 excel 文件的函数。
尝试 1:"Using StreamIO"
这是我迄今为止最好的尝试。它甚至给了我一个 excel 文件,但由于某种原因它没有完全 "finish the content"。看起来它只写了它应该写的内容的四分之一。检查我的脚本 stand_alone 一切正常,所以我 100% 确信这不是我的脚本的问题,而是下面的代码。
附录
原来这里的主要错误是在a_list = self.request.get('a_list')
这一行我没有放allow_multiple=True
。因此,只有列表的第一个值,我正在传递,被使用。
我推荐 AlexMartelli 关于如何使用下面的 xlwt、webapp2 和 GAE 的最小示例来执行与我类似的操作。
class XLSCreator(webapp2.RequestHandler):
def post(self):
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
a_list = self.request.get('a_list')
# create a stringIO object
output = StringIO.StringIO()
# Create file in memory
xls_create(a_list, output)
# Set back to start
output.seek(0)
self.response.out.write(output.getvalue())
# When uncommented, process does not finish
#output.close()
尝试2:
接下来的两个是绝望的尝试;)我从所有代码中挑选出来,然后将其插入并尝试。遗憾的是,没有运气。
class XLSCreator(webapp2.RequestHandler):
def post(self):
fname = 'excelfile.xls'
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
self.response.headers['Content-Disposition'] = 'attachment; filename="%s"' % fname
a_list = self.request.get('a_list')
self.response.out.write(xls_create(a_list, fname))
尝试 3:
class XLSCreator(webapp2.RequestHandler):
def post(self):
fname = 'excelfile.xls'
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
self.response.headers['Content-Disposition'] = 'attachment; filename="%s"' % fname
a_list = self.request.get('a_list')
xls_create(a_list, self.response.out)
这是一个 "hello world" (!) GAE 处理程序,它试图执行您正在谈论的事情:这是 main.py
,app.yaml
将所有 URL 路由到该处理程序;我已经将 xlwt/*.py
复制到 main.py
和 app.yaml
所在目录的子目录 xlwt
中。
import webapp2
import StringIO
import xlwt
def makeit():
workbook = xlwt.Workbook()
sheet = workbook.add_sheet("Hello World")
sheet.write(0, 0, 'Hello world!')
out = StringIO.StringIO()
workbook.save(out)
return out
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
out = makeit()
self.response.write(out.getvalue())
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
使用我的 Chrome 浏览器访问此 GAE 应用程序上的 /
会下载一个 download.xls
文件(5632 字节),Mac 的 Preview
应用程序很乐意将其可视化为单单元电子表格。
现在,请尝试对此进行最低限度的修改,直到它重现您观察到的错误(也许生成的 xls
会序列化为超过 32MB,这被记录为 App Engine 响应的最大大小?) - 这应该有助于诊断问题的根本原因,现在我们知道,这不是将 xlwt.save
与 StringIO
参数一起使用的简单问题(我还尝试了不需要的 out.seek(0)
虽然不需要,但它仍然会产生正确的结果:-).
我正在尝试使用 google 应用程序引擎,webapp2
and a script based on xlwt
调用其 save
方法来创建特定的 excel 文件 原位,让用户自己下载。
现在我已经根据不同的网站尝试了几种不同的方法,但是 none 到目前为止都没有成功。我将概述我的尝试,如果你们中有人知道如何让它工作,我将不胜感激。
非常感谢。如果您需要更多信息,请告诉我,我会立即更新,我看到了。
注意
xls_create(arg, filename_or_stream)
是调用 xlwt.save() 并创建要下载的 excel 文件的函数。
尝试 1:"Using StreamIO"
这是我迄今为止最好的尝试。它甚至给了我一个 excel 文件,但由于某种原因它没有完全 "finish the content"。看起来它只写了它应该写的内容的四分之一。检查我的脚本 stand_alone 一切正常,所以我 100% 确信这不是我的脚本的问题,而是下面的代码。
附录
原来这里的主要错误是在a_list = self.request.get('a_list')
这一行我没有放allow_multiple=True
。因此,只有列表的第一个值,我正在传递,被使用。
我推荐 AlexMartelli 关于如何使用下面的 xlwt、webapp2 和 GAE 的最小示例来执行与我类似的操作。
class XLSCreator(webapp2.RequestHandler):
def post(self):
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
a_list = self.request.get('a_list')
# create a stringIO object
output = StringIO.StringIO()
# Create file in memory
xls_create(a_list, output)
# Set back to start
output.seek(0)
self.response.out.write(output.getvalue())
# When uncommented, process does not finish
#output.close()
尝试2:
接下来的两个是绝望的尝试;)我从所有代码中挑选出来,然后将其插入并尝试。遗憾的是,没有运气。
class XLSCreator(webapp2.RequestHandler):
def post(self):
fname = 'excelfile.xls'
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
self.response.headers['Content-Disposition'] = 'attachment; filename="%s"' % fname
a_list = self.request.get('a_list')
self.response.out.write(xls_create(a_list, fname))
尝试 3:
class XLSCreator(webapp2.RequestHandler):
def post(self):
fname = 'excelfile.xls'
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
self.response.headers['Content-Disposition'] = 'attachment; filename="%s"' % fname
a_list = self.request.get('a_list')
xls_create(a_list, self.response.out)
这是一个 "hello world" (!) GAE 处理程序,它试图执行您正在谈论的事情:这是 main.py
,app.yaml
将所有 URL 路由到该处理程序;我已经将 xlwt/*.py
复制到 main.py
和 app.yaml
所在目录的子目录 xlwt
中。
import webapp2
import StringIO
import xlwt
def makeit():
workbook = xlwt.Workbook()
sheet = workbook.add_sheet("Hello World")
sheet.write(0, 0, 'Hello world!')
out = StringIO.StringIO()
workbook.save(out)
return out
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'application/vnd.ms-excel'
out = makeit()
self.response.write(out.getvalue())
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
使用我的 Chrome 浏览器访问此 GAE 应用程序上的 /
会下载一个 download.xls
文件(5632 字节),Mac 的 Preview
应用程序很乐意将其可视化为单单元电子表格。
现在,请尝试对此进行最低限度的修改,直到它重现您观察到的错误(也许生成的 xls
会序列化为超过 32MB,这被记录为 App Engine 响应的最大大小?) - 这应该有助于诊断问题的根本原因,现在我们知道,这不是将 xlwt.save
与 StringIO
参数一起使用的简单问题(我还尝试了不需要的 out.seek(0)
虽然不需要,但它仍然会产生正确的结果:-).