How to use
Save the snippet to a file utils.py, and add the following view to your Django app:
from django.http import HttpResponse
from .utils import queryset_to_workbook
def download_workbook(request):
queryset = User.objects.all()
columns = (
'first_name',
'last_name',
'email',
'is_staff',
'groups')
workbook = queryset_to_workbook(queryset, columns)
response = HttpResponse(mimetype='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="export.xls"'
workbook.save(response)
return response
Note: you can use dotted notation ('foreign_key.foreign_key.field'
) in the columns parameter to access fields that are accessible through the objects returned by the queryset (in that case you probably want to use select_related
with your queryset).
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 | import xlwt
import datetime
from django.forms.forms import pretty_name
from django.core.exceptions import ObjectDoesNotExist
HEADER_STYLE = xlwt.easyxf('font: bold on')
DEFAULT_STYLE = xlwt.easyxf()
CELL_STYLE_MAP = (
(datetime.date, xlwt.easyxf(num_format_str='DD/MM/YYYY')),
(datetime.time, xlwt.easyxf(num_format_str='HH:MM')),
(bool, xlwt.easyxf(num_format_str='BOOLEAN')),
)
def multi_getattr(obj, attr, default=None):
attributes = attr.split(".")
for i in attributes:
try:
obj = getattr(obj, i)
except AttributeError:
if default:
return default
else:
raise
return obj
def get_column_head(obj, name):
name = name.rsplit('.', 1)[-1]
return pretty_name(name)
def get_column_cell(obj, name):
try:
attr = multi_getattr(obj, name)
except ObjectDoesNotExist:
return None
if hasattr(attr, '_meta'):
# A Django Model (related object)
return unicode(attr).strip()
elif hasattr(attr, 'all'):
# A Django queryset (ManyRelatedManager)
return ', '.join(unicode(x).strip() for x in attr.all())
return attr
def queryset_to_workbook(queryset, columns, header_style=None,
default_style=None, cell_style_map=None):
workbook = xlwt.Workbook()
report_date = datetime.date.today()
sheet_name = 'Export {0}'.format(report_date.strftime('%Y-%m-%d'))
sheet = workbook.add_sheet(sheet_name)
if not header_style:
header_style = HEADER_STYLE
if not default_style:
default_style = DEFAULT_STYLE
if not cell_style_map:
cell_style_map = CELL_STYLE_MAP
obj = queryset.first()
for y, column in enumerate(columns):
value = get_column_head(obj, column)
sheet.write(0, y, value, header_style)
for x, obj in enumerate(queryset, start=1):
for y, column in enumerate(columns):
value = get_column_cell(obj, column)
style = default_style
for value_type, cell_style in cell_style_map:
if isinstance(value, value_type):
style = cell_style
sheet.write(x, y, value, style)
return workbook
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 9 months, 4 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 4 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 5 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
How to make it work with annotate queries?
#
I'm getting error when I need to show in columns "FileField.url" and "DateTimeField". I'm using Django 1.8. Any clues?
#
Please login first before commenting.