【问题标题】:GAE/webapp2: Serving Excel file created by script using xlwtGAE/webapp2:服务由脚本使用 xlwt 创建的 Excel 文件
【发布时间】:2015-04-15 17:13:45
【问题描述】:

我正在尝试使用谷歌应用引擎 webapp2 和基于 xlwt 的脚本,该脚本调用其 save 方法来创建特定的 excel 文件原位并下载由用户。

现在我根据不同的网站尝试了几种不同的方法,但到目前为止都没有成功。我将概述我的尝试,如果你们中的任何人知道如何让它发挥作用,我将非常感激。

提前非常感谢。如果您需要更多信息,请告诉我,我会立即更新,我看到了。

注意
xls_create(arg, filename_or_stream) 是调用 xlwt.save() 并创建要下载的 excel 文件的函数。


尝试 1:“使用 StreamIO”
这是我迄今为止最好的尝试。它甚至给了我一个 excel 文件,但由于某种原因,它并没有完全“完成内容”。看起来它只写了它应该写的四分之一。在检查我的独立脚本时,一切正常,所以我 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:
接下来的两个是绝望的尝试;)我从代码中重新拾起,然后将其插入并尝试。不幸的是,没有运气。

类 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:

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

【问题讨论】:

  • 为什么是seek(0)getvalue'“文件”的全部内容'。另外,xls_save 的代码在哪里?您的错误可能隐藏在那里。
  • @AlexMartelli:我测试了 xls_create ad asurdum,当我单独使用它时它工作得很好,所以我可以自信地说这不是一个因素。为了方便起见,我想把它排除在外。 seek(0) 我发现我需要使用流(请参阅 StreamIO 的示例)
  • “叹息”,结果发现我的代码比我想象的要多得多。 xls_create 是“确实”起作用的一件事。我将在 Try 1: StreamIO 示例中注释我的答案,因为我错误地识别了这个问题
  • @AlexMartelli:我终于找到了获得seek(0) 部分的示例。 flask.pocoo.org/snippets/32我之前在用flask,我在那里看到过...如果没有必要,我想知道为什么它在里面...
  • 好问题——也许那个 sn-p 的作者正在尝试各种方法,而当前的方法工作时并没有注意到它实际上包含了无用的附加功能。在过去,我已经审查了工作代码,它恰好有两次 a=b+c 行(第二行显然无用但无害)——这无疑只是一个微小的编辑事故,但从某种意义上说,这里有一些相似之处:-)。

标签: python google-app-engine webapp2 xlwt


【解决方案1】:

这是一个“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),虽然不需要它仍然会产生正确的结果: -)。

【讨论】:

  • 如上面注释的内联。主要错误是由于self.request.get('a_list') 中缺少函数变量allow_multiple=True。虽然您的回答没有解决问题,但它帮助我进一步最小化了代码并隔离了潜在的错误来源。此外,它还提供了 GAE、webapp2 和 xlwt 的一个很好的最小示例;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 2018-09-13
相关资源
最近更新 更多