App Engine - 从云存储中下载文件

时间:2017-12-11 01:18:15

标签: python google-app-engine pdf

我正在使用Python 2.7和Reportlab创建.pdf文件,以便在我的应用引擎系统中显示/打印。如果重要的话,我正在使用ndb.Model来存储数据。

我能够在线生成相当于单个客户的银行对账单。那是;用户单击屏幕上的“pdf”按钮,.pdf语句将在新选项卡中显示在屏幕上,完全符合预期。

我正在使用以下代码将.pdf文件成功保存到Google云端存储

buffer = StringIO.StringIO()
self.p = canvas.Canvas(buffer, pagesize=portrait(A4))
self.p.setLineWidth(0.5)

try:

    # create .pdf of .csv data here

finally:
    self.p.save()
    pdfout = buffer.getvalue()
    buffer.close()

    filename = getgcsbucket() + '/InvestorStatement.pdf'  
    write_retry_params = gcs.RetryParams(backoff_factor=1.1)

    try:
        gcs_file = gcs.open(filename,
                            'w',
                            content_type='application/pdf',
                            retry_params=write_retry_params)
        gcs_file.write(pdfout)
    except:
        logging.error(traceback.format_exc())
    finally:
        gcs_file.close()

我使用以下代码创建一个显示在屏幕上的所有文件的列表,它显示上面存储的所有文件。

allfiles = []

bucket_name = getgcsbucket()

rfiles = gcs.listbucket(bucket_name)
for rfile in rfiles:
    allfiles.append(rfile.filename)

return allfiles

我的屏幕(html)显示([删除]和文件名)行。当用户单击[删除]按钮时,以下删除代码段工作(文件名为/ bucket / filename,完成)

filename = self.request.get('filename')
try:
    gcs.delete(filename)
except gcs.NotFoundError:
    pass

我的问题 - 鉴于我在屏幕上有一个文件列表,我希望用户点击文件名并将该文件下载到用户的计算机上。在Google的Chrome浏览器中,这会导致文件被下载,其名称显示在屏幕的左下角。

另一点,上面的例子是针对.pdf文件的。我还必须在列表中显示.csv文件,并希望它们也可以下载。我只想下载文件,不需要显示。

所以,我想要一个像......一样的片段。

filename = self.request.get('filename')
try:
    gcs.downloadtousercomputer(filename) ???
except gcs.NotFoundError:
    pass

我想我已经尝试了我在这里和其他地方都可以找到的一切。对不起,我太啰嗦了。有什么提示吗?

2 个答案:

答案 0 :(得分:1)

要下载文件而不是在浏览器中显示该文件,您需要在回复中添加标题:

self.response.headers["Content-Disposition"] = 'attachment; filename="%s"' % filename

您可以如上所示指定文件名,它适用于任何文件类型。

答案 1 :(得分:0)

您可以尝试的一个解决方案是从存储桶中读取文件并使用正确的标题打印内容作为响应:

import cloudstorage
...
def read_file(self, filename):        
    bucket_name = "/your_bucket_name"        
    file = bucket_name + '/' + filename        
    with cloudstorage.open(file) as cloudstorage_file: 
        self.response.headers["Content-Disposition"] = str('attachment;filename=' + filename)            
        contents = cloudstorage_file.read()         
        cloudstorage_file.close()            
        self.response.write(contents)

此处文件名可能是您作为GET参数发送的内容,并且需要是存储在您的存储桶中的文件,否则您将引发异常。

[1]在这里您可以找到一个样本。

[1] https://cloud.google.com/appengine/docs/standard/python/googlecloudstorageclient/read-write-to-cloud-storage