From e0ddcb71f6dc07eea5f4c5421669e9ac49b7571e Mon Sep 17 00:00:00 2001 From: Horilla Date: Wed, 14 May 2025 09:43:33 +0530 Subject: [PATCH] [UPDT] HORILLA VIEWS: Export formats and general formats/styles updates --- horilla_views/cbv_methods.py | 4 +- horilla_views/generic/cbv/views.py | 57 +++++++++++++++- horilla_views/templates/generic/as_list.html | 2 +- .../templates/generic/components.html | 15 ++++- .../generic/delete_confirmation.html | 6 +- .../generic/export_fields_modal.html | 13 +++- .../templates/generic/export_pdf.html | 65 +++++++++++++++++++ .../templates/generic/group_by_table.html | 4 ++ .../generic/horilla_detailed_view.html | 2 + .../templates/generic/horilla_list_table.html | 2 +- .../generic/horilla_profile_view.html | 9 +++ .../templates/generic/pipeline/pipeline.html | 2 +- 12 files changed, 167 insertions(+), 14 deletions(-) create mode 100644 horilla_views/templates/generic/export_pdf.html diff --git a/horilla_views/cbv_methods.py b/horilla_views/cbv_methods.py index c0297a848..98968366a 100644 --- a/horilla_views/cbv_methods.py +++ b/horilla_views/cbv_methods.py @@ -529,7 +529,7 @@ def flatten_dict(d, parent_key=""): return dict(items) -def export_xlsx(json_data, columns): +def export_xlsx(json_data, columns, file_name="quick_export"): """ Quick export method """ @@ -657,5 +657,5 @@ def export_xlsx(json_data, columns): output.read(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ) - response["Content-Disposition"] = 'attachment; filename="quick_export.xlsx"' + response["Content-Disposition"] = f'attachment; filename="{file_name}.xlsx"' return response diff --git a/horilla_views/generic/cbv/views.py b/horilla_views/generic/cbv/views.py index 14effb4bc..d6352992b 100644 --- a/horilla_views/generic/cbv/views.py +++ b/horilla_views/generic/cbv/views.py @@ -2,6 +2,7 @@ horilla/generic/views.py """ +import io import json import logging from typing import Any @@ -14,10 +15,12 @@ from django.core.cache import cache as CACHE from django.core.paginator import Page from django.http import HttpRequest, HttpResponse, QueryDict from django.shortcuts import render +from django.template.loader import render_to_string from django.urls import resolve, reverse from django.utils.decorators import method_decorator from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, FormView, ListView, TemplateView +from xhtml2pdf import pisa from base.methods import closest_numbers, eval_validate, get_key_instances from horilla.filters import FilterSet @@ -49,7 +52,13 @@ class HorillaListView(ListView): view_id: str = """""" - export_file_name: str = None + export_file_name: str = "quick_export" + export_formats: list = [ + ("xlsx", "Excel"), + ("json", "Json"), + ("csv", "CSV"), + ("pdf", "PDF"), + ] template_name: str = "generic/horilla_list_table.html" context_object_name = "queryset" @@ -445,7 +454,7 @@ class HorillaListView(ListView): ) context["bulk_update_fields"] = self.bulk_update_fields context["bulk_path"] = get_bulk_path - + context["export_formats"] = self.export_formats return context def select_all(self, *args, **kwargs): @@ -463,6 +472,7 @@ class HorillaListView(ListView): request = getattr(_thread_locals, "request", None) ids = eval_validate(request.POST["ids"]) _columns = eval_validate(request.POST["columns"]) + export_format = request.POST.get("format", "xlsx") queryset = self.model.objects.filter(id__in=ids) _model = self.model @@ -589,6 +599,49 @@ class HorillaListView(ListView): column = (column[0], column[1]) columns.append(column) + if export_format == "json": + response = HttpResponse( + json.dumps(json_data, indent=4), content_type="application/json" + ) + response["Content-Disposition"] = ( + f'attachment; filename="{self.export_file_name}.json"' + ) + return response + # CSV + elif export_format == "csv": + csv_data = dataset.export("csv") + response = HttpResponse(csv_data, content_type="text/csv") + response["Content-Disposition"] = ( + f'attachment; filename="{self.export_file_name}.csv"' + ) + return response + elif export_format == "pdf": + + headers = dataset.headers + rows = dataset.dict + + # Render to HTML using a template + html_string = render_to_string( + "generic/export_pdf.html", + { + "headers": headers, + "rows": rows, + }, + ) + + # Convert HTML to PDF using xhtml2pdf + result = io.BytesIO() + pisa_status = pisa.CreatePDF(html_string, dest=result) + + if pisa_status.err: + return HttpResponse("PDF generation failed", status=500) + + # Return response + response = HttpResponse(result.getvalue(), content_type="application/pdf") + response["Content-Disposition"] = ( + f'attachment; filename="{self.export_file_name}.pdf"' + ) + return response return export_xlsx(json_data, columns) diff --git a/horilla_views/templates/generic/as_list.html b/horilla_views/templates/generic/as_list.html index 83503d55d..2ade051f0 100644 --- a/horilla_views/templates/generic/as_list.html +++ b/horilla_views/templates/generic/as_list.html @@ -36,5 +36,5 @@ {% endfor %} - + diff --git a/horilla_views/templates/generic/components.html b/horilla_views/templates/generic/components.html index 8a7915c7d..ef1b8b458 100644 --- a/horilla_views/templates/generic/components.html +++ b/horilla_views/templates/generic/components.html @@ -1,4 +1,5 @@ - + +