I wrote something similar to what you want.  It outputs the file
directly instead of creating an intermediate file.  In my case I'm
selecting a set of fields in a big "join" but you can get the idea.
The "hash" function is just to create a signature so I can tell if
some of the fields were changed when I read the CSV file back in a
later step.

Just create a file-like object from StringIO, write to it, reset it to
the beginning, and return it as a stream.

def export_signup_sheet():
    if not request.args:
        request.flash='No selection for team and meet.'
        return
    (meetId,teamId)=request.args[0:2]
    exp=StringIO()
    dbsignups=db((db.signup.id_team_member==db.team_member.id)&
(db.signup.id_meet_event==db.meet_event.id)\
        &(db.meet_event.id_meet==meetId)&
(db.team_member.id_team==teamId)\
        &(db.event.id==db.meet_event.id_event)&
(db.swimmer.id==db.team_member.id_swimmer))
    rows=dbsignups.select(orderby=db.swimmer.last|db.swimmer.first|
db.meet_event.indx)
    filehash=hashlib.md5()
    exp.write('ID,Last name,First name,Event,Race,Course,Time\n')
    for row in rows:
        race='%s%s %s'%
(row.event.distance,row.event.course,event_stroke[row.event.stroke])
        exp.write('%s,%s,%s,%s,%s,%s,%s\n'%
(row.signup.id,row.swimmer.last,row.swimmer.first,row.meet_event.indx,
            race,row.signup.course,s_to_t2(row.signup.best_time)))
        filehash.update(str(row.signup.id)+row.swimmer.last
+row.swimmer.first+str(row.meet_event.indx)+race)
    exp.write('hash,%s\n'%filehash.hexdigest())
    exp.flush()
    exp.seek(0)
    response.headers['Content-Type']='text/application'
    response.headers['Content-Disposition']='attachment;
filename="%s.csv"'%'Meet_Signup'
    return response.stream(exp)



On Mar 13, 12:32 pm, SergeyPo <[email protected]> wrote:
> Hi all,
>
> can you recommend an elegant way to download CSV file from web2py?
> Using gluon code, I wrote a controller function that creates good CSV
> for me in cStringIO object, but my recordsets are large and I'd like
> to stream download file. I.e. approach when I write temp file and then
> download it is not good - I want to start file streaming to user
> immediately, definitely this involves some manipulations with response
> object...
>
> My controller:
>
> def download_csv():
>     def none_exception(value):  #taken from gluon.sql
>         if isinstance(value, unicode):
>             return value.encode('utf8')
>         if hasattr(value, 'isoformat'):
>             return value.isoformat()[:19].replace('T', ' ')
>         if value == None:
>             return ''
>         return value
>
>     sqlset = ........
>     rs = db(sqlset).select()
>     outfile = cStringIO.StringIO()
>     writer = csv.writer(outfile, dialect='excel-tab')
>     columns = [f for f in fields_array if not f.adv_omit_download]
>     row = [T(f.name) for f in columns]
>     writer.writerow(row)
>     for rec in rs:
>         row = [none_exception(eval('rec.' + str(f))) for f in columns]
>         writer.writerow(row)
>     outfile.getvalue() #contains valid CSV string but I want to stream
> it to user during cycle over rs
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web2py Web Framework" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to