Add generic "download results as XLSX" feature
This commit is contained in:
parent
eaad87c704
commit
e5c5a071f2
|
@ -72,6 +72,9 @@
|
|||
% if master.results_downloadable_csv and request.has_perm('{}.results_csv'.format(permission_prefix)):
|
||||
<li>${h.link_to("Download results as CSV", url('{}.results_csv'.format(route_prefix)))}</li>
|
||||
% endif
|
||||
% if master.results_downloadable_xlsx and request.has_perm('{}.results_xlsx'.format(permission_prefix)):
|
||||
<li>${h.link_to("Download results as XLSX", url('{}.results_xlsx'.format(route_prefix)))}</li>
|
||||
% endif
|
||||
% if master.creatable and request.has_perm('{}.create'.format(permission_prefix)):
|
||||
% if master.creates_multiple:
|
||||
<li>${h.link_to("Create new {}".format(model_title_plural), url('{}.create'.format(route_prefix)))}</li>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2017 Lance Edgar
|
||||
# Copyright © 2010-2018 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -41,6 +41,8 @@ from rattail.util import prettify
|
|||
from rattail.time import localtime #, make_utc
|
||||
from rattail.threads import Thread
|
||||
from rattail.csvutil import UnicodeDictWriter
|
||||
from rattail.files import temp_path
|
||||
from rattail.excel import ExcelWriter
|
||||
|
||||
import formalchemy as fa
|
||||
from pyramid import httpexceptions
|
||||
|
@ -66,6 +68,7 @@ class MasterView(View):
|
|||
|
||||
listable = True
|
||||
results_downloadable_csv = False
|
||||
results_downloadable_xlsx = False
|
||||
creatable = True
|
||||
viewable = True
|
||||
editable = True
|
||||
|
@ -1472,6 +1475,57 @@ class MasterView(View):
|
|||
response.content_disposition = b'attachment; filename={}.csv'.format(self.get_grid_key())
|
||||
return response
|
||||
|
||||
def results_xlsx(self):
|
||||
"""
|
||||
Download current list results as XLSX.
|
||||
"""
|
||||
results = self.get_effective_data()
|
||||
fields = self.get_xlsx_fields()
|
||||
path = temp_path(suffix='.xlsx')
|
||||
writer = ExcelWriter(path, fields, sheet_title=self.get_model_title_plural())
|
||||
writer.write_header()
|
||||
|
||||
rows = []
|
||||
for obj in results:
|
||||
data = self.get_xlsx_row(obj, fields)
|
||||
row = [data[field] for field in fields]
|
||||
rows.append(row)
|
||||
|
||||
writer.write_rows(rows)
|
||||
writer.auto_freeze()
|
||||
writer.auto_filter()
|
||||
writer.save()
|
||||
|
||||
response = self.request.response
|
||||
with open(path, 'rb') as f:
|
||||
response.body = f.read()
|
||||
os.remove(path)
|
||||
|
||||
response.content_length = len(response.body)
|
||||
response.content_type = b'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
response.content_disposition = b'attachment; filename={}.xlsx'.format(self.get_grid_key())
|
||||
return response
|
||||
|
||||
def get_xlsx_fields(self):
|
||||
"""
|
||||
Return the list of fields to be written to XLSX download.
|
||||
"""
|
||||
fields = []
|
||||
mapper = orm.class_mapper(self.model_class)
|
||||
for prop in mapper.iterate_properties:
|
||||
if isinstance(prop, orm.ColumnProperty):
|
||||
fields.append(prop.key)
|
||||
return fields
|
||||
|
||||
def get_xlsx_row(self, obj, fields):
|
||||
"""
|
||||
Return a dict for use when writing the row's data to CSV download.
|
||||
"""
|
||||
row = {}
|
||||
for field in fields:
|
||||
row[field] = getattr(obj, field, None)
|
||||
return row
|
||||
|
||||
def row_results_csv(self):
|
||||
"""
|
||||
Download current row results data for an object, as CSV
|
||||
|
@ -1965,6 +2019,13 @@ class MasterView(View):
|
|||
config.add_view(cls, attr='results_csv', route_name='{}.results_csv'.format(route_prefix),
|
||||
permission='{}.results_csv'.format(permission_prefix))
|
||||
|
||||
if cls.results_downloadable_xlsx:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.results_xlsx'.format(permission_prefix),
|
||||
"Download {} as XLSX".format(model_title_plural))
|
||||
config.add_route('{}.results_xlsx'.format(route_prefix), '{}/xlsx'.format(url_prefix))
|
||||
config.add_view(cls, attr='results_xlsx', route_name='{}.results_xlsx'.format(route_prefix),
|
||||
permission='{}.results_xlsx'.format(permission_prefix))
|
||||
|
||||
|
||||
# create
|
||||
if cls.creatable or cls.mobile_creatable:
|
||||
|
|
Loading…
Reference in a new issue