2014-02-19 5 views
1

У меня есть это исключение, как описано в заголовке, при попытке сгенерировать файл excel из модели, отфильтрованной запросом. Запрос работает так, как ожидалось, и дает мне правильные и полные результаты. Тем не менее, большое дело происходит, когда я пытаюсь, на самом деле, создать файл Excel:Xlsxwriter: TypeError: «ожидаемая строка или буфер»

File "/home/luismasuelli/Proyectos/CentralCar/main/views.py", line 100, in export_xls 
    workbook.close() 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/workbook.py", line 237, in close 
    self._store_workbook() 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/workbook.py", line 405, in _store_workbook 
    xml_files = packager._create_package() 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/packager.py", line 139, in _create_package 
    self._write_shared_strings_file() 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/packager.py", line 265, in _write_shared_strings_file 
    sst._assemble_xml_file() 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/sharedstrings.py", line 53, in _assemble_xml_file 
    self._write_sst_strings() 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/sharedstrings.py", line 83, in _write_sst_strings 
    self._write_si(string) 
    File "/home/luismasuelli/.virtualenvs/py27dj15/local/lib/python2.7/site-packages/xlsxwriter/sharedstrings.py", line 95, in _write_si 
    string = re.sub('(_x[0-9a-fA-F]{4}_)', r'_x005F\1', string) 
    File "/home/luismasuelli/.virtualenvs/py27dj15/lib/python2.7/re.py", line 151, in sub 
    return _compile(pattern, flags).sub(repl, string, count) 
TypeError: expected string or buffer 

Что может быть причиной меня это исключение? Я попытался изменить кодировку, чтобы поместить utf8, как это было предложено, но это не помогает мне здесь.

Я работаю с Xlsxwriter 0.5.2/питон 2.7.4 (Ubuntu) из приложения Джанго, следующим образом:

# -*- coding: utf8 -*- 
#... 
from StringIO import StringIO 
#... 
import datetime 
#... 
from django.http import HttpResponse, Http404 
#... 
import xlsxwriter 
#... 
from main.models import Contact 

#... 

def export_xls(request, period=''): 

    deltas = { 
     'D': datetime.timedelta(days=1), 
     'W': datetime.timedelta(days=7), 
     'M': datetime.timedelta(days=30), 
     '6M': datetime.timedelta(days=182), 
     'Y': datetime.timedelta(days=365) 
    } 

    query = Contact.objects.all().order_by('-enviado_en') 

    if period: 
     query = query.filter(enviado_en__gt=datetime.datetime.now() - deltas[period]) 

    stream = StringIO() 
    workbook = xlsxwriter.Workbook(stream, {'in_memory': True}) 
    worksheet = workbook.add_worksheet('Contactos') 
    #poner encabezados 
    header_format = workbook.add_format() 
    header_format.set_align("center") 
    header_format.set_bold() 
    header_format.set_font_name('Arial') 
    worksheet.set_column(9, 9, 40) 
    worksheet.write_string(0, 0, Contact._meta.get_field('enviado_en').verbose_name, header_format) 
    worksheet.write_string(0, 1, Contact._meta.get_field('nombre').verbose_name, header_format) 
    worksheet.write_string(0, 2, Contact._meta.get_field('apellido').verbose_name, header_format) 
    worksheet.write_string(0, 3, Contact._meta.get_field('email').verbose_name, header_format) 
    worksheet.write_string(0, 4, Contact._meta.get_field('telefono').verbose_name, header_format) 
    worksheet.write_string(0, 5, Contact._meta.get_field('ciudad').verbose_name, header_format) 
    worksheet.write_string(0, 6, Contact._meta.get_field('vehiculo').verbose_name, header_format) 
    worksheet.write_string(0, 7, Contact._meta.get_field('kilometraje').verbose_name, header_format) 
    worksheet.write_string(0, 8, Contact._meta.get_field('dia_preferente').verbose_name, header_format) 
    worksheet.write_string(0, 9, Contact._meta.get_field('mensaje').verbose_name, header_format) 
    #poner cada fila 
    body_format = workbook.add_format() 
    body_format.set_font_name('Arial') 
    current_row = 1 
    for contact in query: 
     worksheet.write(current_row, 0, contact.enviado_en.strftime("%d/%m/%Y %H/%M/%S"), body_format) 
     worksheet.write(current_row, 1, contact.nombre, body_format) 
     worksheet.write(current_row, 2, contact.apellido, body_format) 
     worksheet.write(current_row, 3, contact.email, body_format) 
     worksheet.write(current_row, 4, contact.telefono, body_format) 
     worksheet.write(current_row, 5, contact.ciudad, body_format) 
     worksheet.write(current_row, 6, contact.get_vehiculo_display(), body_format) 
     worksheet.write(current_row, 7, contact.get_kilometraje_display(), body_format) 
     worksheet.write(current_row, 8, contact.get_dia_preferente_display(), body_format) 
     worksheet.write(current_row, 9, contact.mensaje, body_format) 
     current_row += 1 
    workbook.close() 
    data = stream.getvalue() 
    response = HttpResponse(content=data, content_type='application/vnd.ms-excel') 
    response['Content-Disposition'] = 'attachment; filename=reporte-%s.xlsx' % datetime.datetime.now().strftime("%Y%m%d%H%M%S") 
    return response 

Будучи моя модель Контакт:

class Contact(models.Model): 

    DIAS = (
     #('?', 'Cualquiera'), 
     ('L', 'Lunes'), 
     ('M', 'Martes'), 
     ('I', 'Miercoles'), 
     ('J', 'Jueves'), 
     ('V', 'Viernes'), 
     ('S', 'Sábado') 
    ) 
    KILOMETRAJE = (
     #('??', '(No especifica)'), 
     ('00', '0km'), 
     ('05', '1 - 5000km'), 
     ('10', '5000km - 10000km'), 
     ('15', '10001km - 15000km'), 
     ('20', '15001km - 20000km'), 
     ('25', '20001km - 25000km'), 
     ('30', '25001km - 30000km'), 
     ('35', '30001km - 35000km'), 
     ('40', '35001km - 40000km'), 
     ('45', '40001km - 45000km'), 
     ('50', '45001km - 50000km'), 
     ('55', '50001km - 55000km'), 
     ('60', '55001km - 60000km'), 
     ('65', '60001km - 65000km'), 
     ('70', '65001km - 70000km'), 
     ('75', '70001km - 75000km'), 
     ('80', '75001km - 80000km'), 
     ('85', '80001km - 85000km'), 
     ('90', '85001km - 90000km'), 
     ('95', '90001km - 950000km'), 
     ('XX', '95001km - 100000km'), 
     ('++', 'Más de 100000km') 
    ) 

    enviado_en = models.DateTimeField(default=tznow, null=False, db_index=True, verbose_name=_(u"Enviado en")) 
    #campos de contacto 
    nombre = models.CharField(max_length=30, null=False, blank=False, db_index=True, verbose_name=_(u"Nombre")) 
    apellido = models.CharField(max_length=30, null=False, blank=False, db_index=True, verbose_name=_(u"Apellido")) 
    email = models.EmailField(null=False, blank=False, db_index=True, verbose_name=_(u"E-mail")) 
    telefono = models.CharField(max_length=10, null=False, blank=False, db_index=True, validators=[contact_phone_number_format], verbose_name=_(u"Teléfono")) 
    ciudad = models.CharField(max_length=20, null=False, blank=False, validators=[validate_ciudad], verbose_name=_(u"Ciudad")) 
    #campos solamente de cotizacion 
    vehiculo = models.CharField(max_length=20, blank=True, db_index=True, choices=vehicle_choices(), verbose_name=_(u"Vehículo")) 
    kilometraje = models.CharField(max_length=2, blank=True, db_index=True, choices=KILOMETRAJE, default='05', verbose_name=_(u"Kilometraje")) 
    #campos solamente de agendar cita 
    dia_preferente = models.CharField(max_length=1, blank=True, choices=DIAS, default='L', verbose_name=_(u'Día para cita')) 
    #mensaje 
    mensaje = models.TextField(max_length=4095, null=False, blank=False, verbose_name=_(u"Mensaje")) 

предположить vehicle_choices() существует и возвращает допустимый набор выбора для поля ввода.

ответ

3

Я нашел ответ: объекты verbose_name на самом деле являются прокси-серверами, возвращаемыми из ugettext_lazy. вызов force_unicode (ugl_obj) преобразует их в строку (преобразование не выполняется автоматически).

в моем случае, каждое значение в печати заголовка было завернуто, например .:

worksheet.write_string(0, 0, force_unicode(Contact._meta.get_field('enviado_en').verbose_name), header_format) 
Смежные вопросы