2014-02-19 1 views
1

쿼리로 필터링 된 모델에서 Excel 파일을 생성하려고 할 때 제목에 설명 된 예외가 있습니다. 쿼리가 예상대로 작동하고 나에게 올바른 결과를 제공합니다. 그러나 실제로는 Excel 파일을 만들려고 할 때 큰 문제가 발생합니다.Xlsxwriter : TypeError : "expected string or buffer"

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 (우분투)와 함께 일하고 있어요 :

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을 가정

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

내 모델에게 연락 인()가 존재하고 입력 필드에 유효한 선택 세트를 리턴합니다.

답변

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) 
포장했다