There is no need to store the data in the session and then redirect to 
another action to create the file. Instead, just do it all at once. Also, 
if you want to store the file (safely) and make it easily retrievable, then 
add an upload field to the database table and store it that way. Finally, 
if you want to associated files with their creators, just add a reference 
field to the excelform table to reference the auth_user record of the 
currently logged in user. This can all be simplified as follows:

In a model file:

def create_excel(row):
    from openpyxl import load_workbook
    from openpyxl.writer.excel import save_virtual_workbook
    from cStringIO import StringIO
    wb = load_workbook(filename=
'/home/../Documents/web2py/applications/../static/excel.xlsx')
    sheet_ranges = wb['Sheet1']
    sheet_ranges['C4'] = row.last_name
    sheet_ranges['C6'] = row.first_name
    sheet_ranges['C8'] = row.age
    sheet_ranges['C10'] = row.location
    excel_file = StringIO()
    excel_file.write(save_virtual_workbook(wb))
    excel_file.seek(0)
    return db.excelform.excel_file.store(excel_file, 'spreadsheet.xlsx')

db.define_table('excelform',
    Field('last_name', 'string', requires=IS_NOT_EMPTY()),
    Field('first_name', 'string', requires=IS_NOT_EMPTY()),
    Field('age', 'string', requires=IS_NOT_EMPTY()),
    Field('location', 'string', requires=IS_NOT_EMPTY()),
    Field('excel_file', 'upload', compute=create_excel),
    Field('created_by', 'reference auth_user',
          default=auth.user_id, readable=False, writable=False))

The above adds the excel_file upload field to your model and defines it as 
a computed field. When an insert is made, the create_excel function is 
called. It creates the workbook, but instead of using wb.save() to create 
the file directly, it uses save_virtual_workbook to convert the workbook to 
a string. It then writes the string to a StringIO object, which is 
ultimately passed to the .store() method of the upload field. The .store() 
method creates the file and returns the filename that web2py created for 
it, which is ultimately stored in the upload field itself. The second 
argument to .store() is the filename you will see when you download the 
file (but no the filename used to actually store the file on the 
filesystem).

The created_by field is a reference to auth_user, with the default set to 
the ID of the current user (it is not readable or writable, so will not 
appear in the form).

Then, in the controller:

@auth.requires_login()
def excelform():
    record = db.excelform(request.args(0))
    form = SQLFORM(db.excelform, record,
                   message_onsuccess='Thanks! The form has been submitted.',
                   message_onfailure='Please correct the error(s).').process
()
    return dict(form=form)

The controller is now quite simple -- it just creates and processes the 
form -- the rest of the logic is handled in the model. Note, assuming being 
a registered user is required, you should use the @auth.requires_login() 
decorator here.

If you want to show only the files of the current user, you can do:

    grid = SQLFORM.grid(db.excelform.created_by == auth.user_id)

Anthony

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to