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.pyapp.yaml 将所有 URL 路由到该处理程序;我已经将 xlwt/*.py 复制到 main.pyapp.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.saveStringIO 参数一起使用的简单问题(我还尝试了不需要的 out.seek(0)虽然不需要,但它仍然会产生正确的结果:-).