# -*- 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)