diff --git a/tests/views/test_submission_list.py b/tests/views/test_submission_list.py index 7577269e..59109332 100644 --- a/tests/views/test_submission_list.py +++ b/tests/views/test_submission_list.py @@ -39,6 +39,9 @@ def setUp(self): self.csv_url = "{}?date_from=2017-01-01&date_to=2017-01-02&action=CSV".format( self.list_url ) + self.xlsx_url = "{}?date_from=2017-01-01&date_to=2017-01-02&action=XLSX".format( + self.list_url + ) self.client.login(username="user", password="password") @@ -71,6 +74,12 @@ def test_get_csv(self): response.get("Content-Disposition"), "attachment;filename=export.csv" ) + def test_get_xlsx(self): + response = self.client.get(self.xlsx_url) + self.assertEqual( + response.get("Content-Disposition"), "attachment;filename=export.xlsx" + ) + class ListViewPermissionTestCase(AppTestCase): fixtures = ["test.json"] diff --git a/wagtailstreamforms/templates/streamforms/index_submissions.html b/wagtailstreamforms/templates/streamforms/index_submissions.html index 8a6f50da..501dc92a 100644 --- a/wagtailstreamforms/templates/streamforms/index_submissions.html +++ b/wagtailstreamforms/templates/streamforms/index_submissions.html @@ -1,5 +1,5 @@ {% extends "wagtailadmin/base.html" %} -{% load i18n %} +{% load i18n wagtailadmin_tags %} {% block titletag %}{% blocktrans with form_title=object.title|capfirst %}Submissions of {{ form_title }}{% endblocktrans %}{% endblock %} {% block extra_js %} {{ block.super }} @@ -86,7 +86,13 @@

- +
diff --git a/wagtailstreamforms/views/submission_list.py b/wagtailstreamforms/views/submission_list.py index dff60549..05e57cc6 100644 --- a/wagtailstreamforms/views/submission_list.py +++ b/wagtailstreamforms/views/submission_list.py @@ -3,11 +3,12 @@ from django.core.exceptions import PermissionDenied from django.http import Http404, HttpResponse -from django.utils.encoding import smart_str +from django.utils.encoding import force_text, smart_str from django.utils.translation import ugettext as _ from django.views.generic import ListView from django.views.generic.detail import SingleObjectMixin from wagtail.contrib.modeladmin.helpers import PermissionHelper +from xlsxwriter.workbook import Workbook from wagtailstreamforms import hooks from wagtailstreamforms.forms import SelectDateForm @@ -46,6 +47,8 @@ def get(self, request, *args, **kwargs): if request.GET.get("action") == "CSV": return self.csv() + elif request.GET.get("action") == "XLSX": + return self.xlsx() return super().get(request, *args, **kwargs) @@ -68,6 +71,42 @@ def csv(self): return response + def xlsx(self): + queryset = self.get_queryset() + data_fields = self.object.get_data_fields() + data_headings = [force_text(label) for name, label in data_fields] + + response = HttpResponse(content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + response["Content-Disposition"] = "attachment;filename=export.xlsx" + + # create workbook + workbook = Workbook( + response, + { + "in_memory": True, + "constant_memory": True, + "remove_timezone": True, + "default_date_format": "dd/mm/yy hh:mm:ss", + }, + ) + worksheet = workbook.add_worksheet() + + # write heading + for col_number, heading in enumerate(data_headings): + worksheet.write(0, col_number, heading) + + # write row data + for row_number, item in enumerate(queryset): + data_row = [] + form_data = item.get_data() + for name, label in data_fields: + data_row.append(force_text(form_data.get(name))) + for col_number, col_value in enumerate(data_row): + worksheet.write(row_number+1, col_number, col_value) + + workbook.close() + return response + def get_queryset(self): submission_class = self.object.get_submission_class() self.queryset = submission_class._default_manager.filter(form=self.object)