Add support for downloading batch rows as XLSX file
This commit is contained in:
parent
10c30cd21a
commit
6cfc72c875
|
@ -67,6 +67,9 @@
|
|||
% if master.has_rows and master.rows_downloadable_csv and request.has_perm('{}.row_results_csv'.format(permission_prefix)):
|
||||
<li>${h.link_to("Download row results as CSV", url('{}.row_results_csv'.format(route_prefix), uuid=instance.uuid))}</li>
|
||||
% endif
|
||||
% if master.has_rows and master.rows_downloadable_xlsx and request.has_perm('{}.row_results_xlsx'.format(permission_prefix)):
|
||||
<li>${h.link_to("Download row results as XLSX", url('{}.row_results_xlsx'.format(route_prefix), uuid=instance.uuid))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="object_helpers()"></%def>
|
||||
|
|
|
@ -74,6 +74,7 @@ class BatchMasterView(MasterView):
|
|||
has_rows = True
|
||||
rows_deletable = True
|
||||
rows_downloadable_csv = True
|
||||
rows_downloadable_xlsx = True
|
||||
refreshable = True
|
||||
refresh_after_create = False
|
||||
cloneable = False
|
||||
|
@ -1333,6 +1334,9 @@ class BatchMasterView(MasterView):
|
|||
def get_row_results_csv_filename(self, batch):
|
||||
return '{}.{}.csv'.format(self.get_route_prefix(), batch.id_str)
|
||||
|
||||
def get_row_results_xlsx_filename(self, batch):
|
||||
return '{}.{}.xlsx'.format(self.get_route_prefix(), batch.id_str)
|
||||
|
||||
def clone(self):
|
||||
"""
|
||||
Clone current batch as new batch
|
||||
|
|
|
@ -45,6 +45,7 @@ from rattail.threads import Thread
|
|||
from rattail.csvutil import UnicodeDictWriter
|
||||
from rattail.files import temp_path
|
||||
from rattail.excel import ExcelWriter
|
||||
from rattail.gpc import GPC
|
||||
|
||||
import colander
|
||||
import deform
|
||||
|
@ -141,6 +142,7 @@ class MasterView(View):
|
|||
rows_bulk_deletable = False
|
||||
rows_default_pagesize = 20
|
||||
rows_downloadable_csv = False
|
||||
rows_downloadable_xlsx = False
|
||||
|
||||
mobile_rows_creatable = False
|
||||
mobile_rows_creatable_via_browse = False
|
||||
|
@ -2354,6 +2356,64 @@ class MasterView(View):
|
|||
row[field] = getattr(obj, field, None)
|
||||
return row
|
||||
|
||||
def row_results_xlsx(self):
|
||||
"""
|
||||
Download current *row* results as XLSX.
|
||||
"""
|
||||
obj = self.get_instance()
|
||||
results = self.get_effective_row_data(sort=True)
|
||||
fields = self.get_row_xlsx_fields()
|
||||
path = temp_path(suffix='.xlsx')
|
||||
writer = ExcelWriter(path, fields, sheet_title=self.get_row_model_title_plural())
|
||||
writer.write_header()
|
||||
|
||||
rows = []
|
||||
for row_obj in results:
|
||||
data = self.get_row_xlsx_row(row_obj, fields)
|
||||
row = [data[field] for field in fields]
|
||||
rows.append(row)
|
||||
|
||||
writer.write_rows(rows)
|
||||
writer.auto_freeze()
|
||||
writer.auto_filter()
|
||||
writer.auto_resize()
|
||||
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 = str('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
filename = self.get_row_results_xlsx_filename(obj)
|
||||
response.content_disposition = str('attachment; filename={}'.format(filename))
|
||||
return response
|
||||
|
||||
def get_row_xlsx_fields(self):
|
||||
"""
|
||||
Return the list of row fields to be written to XLSX download.
|
||||
"""
|
||||
# TODO: should this be shared at all? in a better way?
|
||||
return self.get_row_csv_fields()
|
||||
|
||||
def get_row_xlsx_row(self, row, fields):
|
||||
"""
|
||||
Return a dict for use when writing the row's data to XLSX download.
|
||||
"""
|
||||
xlrow = {}
|
||||
for field in fields:
|
||||
value = getattr(row, field, None)
|
||||
|
||||
if isinstance(value, GPC):
|
||||
value = six.text_type(value)
|
||||
|
||||
xlrow[field] = value
|
||||
return xlrow
|
||||
|
||||
def get_row_results_xlsx_filename(self, obj):
|
||||
return '{}.xlsx'.format(self.get_row_grid_key())
|
||||
|
||||
def row_results_csv(self):
|
||||
"""
|
||||
Download current row results data for an object, as CSV
|
||||
|
@ -3265,6 +3325,14 @@ class MasterView(View):
|
|||
config.add_view(cls, attr='row_results_csv', route_name='{}.row_results_csv'.format(route_prefix),
|
||||
permission='{}.row_results_csv'.format(permission_prefix))
|
||||
|
||||
# download row results as Excel
|
||||
if cls.has_rows and cls.rows_downloadable_xlsx:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.row_results_xlsx'.format(permission_prefix),
|
||||
"Download {} results as XLSX".format(row_model_title))
|
||||
config.add_route('{}.row_results_xlsx'.format(route_prefix), '{}/{{uuid}}/rows-xlsx'.format(url_prefix))
|
||||
config.add_view(cls, attr='row_results_xlsx', route_name='{}.row_results_xlsx'.format(route_prefix),
|
||||
permission='{}.row_results_xlsx'.format(permission_prefix))
|
||||
|
||||
# create row
|
||||
if cls.has_rows:
|
||||
if cls.rows_creatable or cls.mobile_rows_creatable:
|
||||
|
|
Loading…
Reference in a new issue