Want to prompt browser to save csv

丶灬走出姿态 提交于 2019-12-03 08:10:06
Marco Mariani

As a cleaner way to do that, you can register a renderer.

In your configuration set-up, add:

    config.add_renderer(name='csv',
                        factory='mypackage.renderers.CSVRenderer')

then in mypackage/renderers.py:

class CSVRenderer(object):
    def __init__(self, info):
        pass

    def __call__(self, value, system):
        fout = StringIO.StringIO()
        writer = csv.writer(fout, delimiter=';', quoting=csv.QUOTE_ALL)

        writer.writerow(value['header'])
        writer.writerows(value['rows'])

        resp = system['request'].response
        resp.content_type = 'text/csv'
        resp.content_disposition = 'attachment;filename="report.csv"'
        return fout.getvalue()

After that, you can decorate your view with the renderer:

@view_config(..., renderer='csv')
def myview(self):
    header = ['name', 'surname', 'address']

    rows = [
            (
                row['name'],
                row['surname'],
                row['address'],
            )
        for row in query_rows(.....)
        ]

    return {
            'header': header,
            'rows': rows
            }

The advantage of this approach is better testable view code (you just check for the dictionary values, no need to parse anything) and you can also add a XLS or whatever renderer to the same view:

@view_config(..., renderer='xls')
@view_config(..., renderer='csv')
def myview(self):
    ...

Try adding Content-Disposition:

response['Content-Disposition'] = 'attachment; filename="report.csv"'

It's better to set content type as well

response['Content-type'] = 'text/csv'
response['Content-Disposition'] = 'attachment; filename="report.csv"'
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!