text: from openpyxl import Workbook
  from django.core.exceptions import PermissionDenied
  from django.http import HttpResponse
  from datetime import datetime, date
  from openpyxl.styles import Font
  from unidecode import unidecode
  
  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
  
  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)
      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"
  