You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

103 lines
4.6 KiB

# -*- coding: utf-8 -*-
"""ExcelResponse for emencia.django.newsletter"""
# Based on http://www.djangosnippets.org/snippets/1151/
import datetime
from django.http import HttpResponse
from django.db.models.query import QuerySet
from django.db.models.query import ValuesQuerySet
# from ..models import ContactSettings
from collections import OrderedDict
from functions.translate import fill_trans_fields_r
from theme.models import Theme
class ExcelResponse(HttpResponse):
"""ExcelResponse feeded by queryset"""
def __init__(self, data, output_name='excel_data', headers=None, sheet_name = "Sheet1", default_style=None,
force_csv=False, encoding='utf8'):
valid_data = False
qs = data.prefetch_related('contactsettings', 'contactsettings__theme', 'contactsettings__area')
# if isinstance(data, ValuesQuerySet):
# data = list(data)
# elif isinstance(data, QuerySet):
# data = list(data.values())
# print(data)
# if 'settings' in headers:
data = []
themes = dict(Theme.objects.language('ru').all().values_list('pk', 'name'))
for item in qs:
data.append([
item.email,
item.first_name,
item.contactsettings.exponent_practicum,
item.contactsettings.organiser_practicum,
item.creation_date.strftime('%d.%m.%Y'),
item.modification_date.strftime('%d.%m.%Y'),
', '.join([getattr(fill_trans_fields_r(obj=x, lang='ru'), 'name', '') for x in item.contactsettings.area.all()]),
', '.join([themes.get(x.pk) for x in item.contactsettings.theme.all()]),
])
headers = ('email', 'first_name', 'приактикум экспонента', 'практикум организатор', 'дата подписки', 'дата изменения', 'гео', 'темы')
# if hasattr(data, '__getitem__'):
# if isinstance(data[0], dict):
# if headers is None:
# headers = data[0].keys()
# data = [[row[col] for col in headers] for row in data]
data.insert(0, headers)
# if hasattr(data[0], '__getitem__'):
# valid_data = True
# assert valid_data is True, "ExcelResponse requires a sequence of sequences"
import StringIO
output = StringIO.StringIO()
# Excel has a limit on number of rows; if we have more than that, make a csv
use_xls = False
if len(data) <= 65536 and force_csv is not True:
try:
import xlwt
except ImportError:
pass
else:
use_xls = True
if use_xls:
book = xlwt.Workbook(encoding=encoding)
sheet = book.add_sheet(sheet_name)
styles = {'datetime': xlwt.easyxf(num_format_str='yyyy-mm-dd hh:mm:ss'),
'date': xlwt.easyxf(num_format_str='yyyy-mm-dd'),
'time': xlwt.easyxf(num_format_str='hh:mm:ss'),
'default': default_style or xlwt.Style.default_style}
for rowx, row in enumerate(data):
for colx, value in enumerate(row):
if isinstance(value, datetime.datetime):
cell_style = styles['datetime']
elif isinstance(value, datetime.date):
cell_style = styles['date']
elif isinstance(value, datetime.time):
cell_style = styles['time']
else:
cell_style = styles['default']
sheet.write(rowx, colx, value, style=cell_style)
book.save(output)
mimetype = 'application/vnd.ms-excel'
file_ext = 'xls'
else:
for row in data:
out_row = []
for value in row:
if not isinstance(value, basestring):
value = unicode(value)
value = value.encode(encoding)
out_row.append(value.replace('"', '""'))
output.write('"%s"\n' %
'","'.join(out_row))
mimetype = 'text/csv'
file_ext = 'csv'
output.seek(0)
super(ExcelResponse, self).__init__(content=output.getvalue(),
mimetype=mimetype)
self['Content-Disposition'] = 'attachment;filename="%s.%s"' % \
(output_name.replace('"', '\"')[:27], file_ext)