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.
101 lines
4.8 KiB
101 lines
4.8 KiB
# -*- coding: utf-8 -*-
|
|
"""ExcelResponse for emencia.django.newsletter"""
|
|
# Based on http://www.djangosnippets.org/snippets/1151/
|
|
import datetime
|
|
# from ..models import ContactSettings
|
|
from collections import OrderedDict
|
|
|
|
from django.db.models.query import QuerySet, ValuesQuerySet
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
|
|
from theme.models import Theme
|
|
from city.models import City
|
|
from country.models import Country, Area
|
|
from functions.translate import fill_trans_fields_r
|
|
|
|
from ..models import ContactSettings
|
|
|
|
|
|
class ExcelResponse(HttpResponse):
|
|
"""ExcelResponse feeded by queryset"""
|
|
def __init__(self, request, data, output_name='excel_data', headers=None, sheet_name = "Sheet1", default_style=None,
|
|
force_csv=False, encoding='utf8'):
|
|
self.request = request
|
|
valid_data = False
|
|
contact_ids = list(data.values_list('pk', flat=True))
|
|
qs = ContactSettings.objects.filter(contact_id__in=contact_ids)
|
|
if not qs.count():
|
|
return HttpResponseRedirect(self.request.META['HTTP_REFERER'])
|
|
qs = qs.prefetch_related(
|
|
'contact', 'theme', 'area', 'city', 'country',
|
|
)
|
|
data = []
|
|
areas = dict(Area.objects.language('ru').all().values_list('pk', 'name'))
|
|
countries = dict(Country.objects.language('ru').all().values_list('pk', 'name'))
|
|
cities = dict(City.objects.language('ru').all().values_list('pk', 'name'))
|
|
themes = dict(Theme.objects.language('ru').all().values_list('pk', 'name'))
|
|
for item in qs:
|
|
data.append([
|
|
item.contact.email,
|
|
item.contact.first_name,
|
|
item.exponent_practicum,
|
|
item.organiser_practicum,
|
|
'; '.join([areas.get(x) for x in set(item.area.values_list('pk', flat=True))]),
|
|
'; '.join([countries.get(x) for x in set(item.country.values_list('pk', flat=True))]),
|
|
'; '.join([cities.get(x) for x in set(item.city.values_list('pk', flat=True))]),
|
|
'; '.join([themes.get(x) for x in set(item.theme.values_list('pk', flat=True))]),
|
|
item.contact.creation_date.strftime('%d.%m.%Y'),
|
|
item.contact.modification_date.strftime('%d.%m.%Y'),
|
|
])
|
|
headers = ('email', 'first_name', 'приактикум экспонента', 'практикум организатор', 'гео', 'страна', 'город', 'темы', 'дата подписки', 'дата изменения')
|
|
data.insert(0, headers)
|
|
|
|
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)
|
|
|