Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Want to prompt browser to save csv

Tags:

python

pyramid

Want to prompt browser to save csv using pyramid.response.Response searched for clues and found here's a link Django answer but i can't use it with Pyramid wsgi my code looks like this:

from pyramid.response import Response
def get_list_names_emails(request):
    session, env = request.db, request.client_env
    response = Response(content_type='text/csv')
    output = StringIO()
    writer = csv.writer(output)
    writer.writerow(['SomeName', 'SomeEmail', 'CompanyName])
    csv_output = output.getvalue()
    return csv_output
like image 760
Viszman Avatar asked Apr 02 '12 09:04

Viszman


People also ask

How do I save a CSV file in Safari?

Right-click on the page Safari has opened, and click Save Page As. Another prompt will show up, allowing you to choose the file name and where you wish to save the file.

How do I save a CSV file on my iPhone?

To export your contacts from iPhone to CSV, you need to change the export settings first: Click "More" > "Settings", choose "CSV" as the export format, and click "Save". Afterward, click "Phone to PC". Step 2. Select "Contacts" among the types of content and click "Transfer".


3 Answers

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):
    ...
like image 193
Marco Mariani Avatar answered Oct 06 '22 16:10

Marco Mariani


Try adding Content-Disposition:

response['Content-Disposition'] = 'attachment; filename="report.csv"'
like image 22
BluesRockAddict Avatar answered Oct 06 '22 16:10

BluesRockAddict


It's better to set content type as well

response['Content-type'] = 'text/csv'
response['Content-Disposition'] = 'attachment; filename="report.csv"'
like image 20
Maksym Polshcha Avatar answered Oct 06 '22 16:10

Maksym Polshcha