- Author:
- PunisherGu
- Posted:
- October 24, 2019
- Language:
- Python
- Version:
- 1.0
- Score:
- 0 (after 0 ratings)
I separate this in two files, like this: export_excel.py and actions.py
I tried to treat all possible forms of information that may appear in admin, such as properties, functions and normal fields, always getting the column name verbose_name or short_description depending on the case.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #export_excel.py
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
-----------------------------------------------------------------------------------------------------------------
#actions.py
from openpyxl import Workbook
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from datetime import datetime, date
from action_export.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):
if not request.user.is_staff:
raise PermissionDenied
opts = self.model._meta
field_names = self.list_display
file_name = unidecode(opts.verbose_name)
blank_line = []
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 = "Export as excel"
----------------------------------------------------------------------------------------------------------------
In admin just do:
from actions import export_as_xls
class SomeAdmin(admin.ModelAdmin):
.
.
.
actions = [export_as_xls]
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
you saved my say, thx so much!
#
Please login first before commenting.