Skip to content

Instantly share code, notes, and snippets.

@firdavsDev
Forked from kelwys/actions.py
Created June 10, 2024 07:31
Show Gist options
  • Save firdavsDev/99e2357d1c4f9bb5b8a8cbe3906595d3 to your computer and use it in GitHub Desktop.
Save firdavsDev/99e2357d1c4f9bb5b8a8cbe3906595d3 to your computer and use it in GitHub Desktop.
Export Django Admin to Excel with Action
from openpyxl import Workbook
from django.http import HttpResponse
from datetime import datetime, date
from .export_excel import ExportExcelAction
from openpyxl.styles import Font
from unidecode import unidecode
def style_output_file(file):
black_font = Font(color='000000', bold=True)
for cell in file["1:1"]:
cell.font = black_font
for column_cells in file.columns:
length = max(len((cell.value)) for cell in column_cells)
length += 10
file.column_dimensions[column_cells[0].column_letter].width = length
return file
def convert_data_date(value):
return value.strftime('%d/%m/%Y')
def convert_boolean_field(value):
if value:
return 'Yes'
return 'No'
def export_as_xls(self, request, queryset):
opts = self.model._meta
field_names = self.list_display
file_name = unidecode(opts.verbose_name)
wb = Workbook()
ws = wb.active
ws.append(ExportExcelAction.generate_header(self, self.model, field_names))
for obj in queryset:
row = []
for field in field_names:
is_admin_field = hasattr(self, field)
if is_admin_field:
value = getattr(self, field)(obj)
else:
value = getattr(obj, field)
if isinstance(value, datetime) or isinstance(value, date):
value = convert_data_date(value)
elif isinstance(value, bool):
value = convert_boolean_field(value)
row.append(str(value))
ws.append(row)
ws = style_output_file(ws)
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = f'attachment; filename={file_name}.xlsx'
wb.save(response)
return response
export_as_xls.short_description = "Exportar para excel"
from actions import export_as_xls
class SomeAdmin(admin.ModelAdmin):
.
.
.
actions = [export_as_xls]
class ExportExcelAction:
@classmethod
def generate_header(cls, admin, model, list_display):
def default_format(value):
return value.replace('_', ' ').upper()
header = []
for field_display in list_display:
is_model_field = field_display in [f.name for f in model._meta.fields]
is_admin_field = hasattr(admin, field_display)
if is_model_field:
field = model._meta.get_field(field_display)
field_name = getattr(field, 'verbose_name', field_display)
header.append(default_format(field_name))
elif is_admin_field:
field = getattr(admin, field_display)
field_name = getattr(field, 'short_description', default_format(field_display))
header.append(default_format(field_name))
else:
header.append(default_format(field_display))
return header
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment