Login

Action export django admin to excel exactly as it appears in list-display

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

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

geoom (on October 7, 2020):

you saved my say, thx so much!

#

Please login first before commenting.