Python xlsxwriter库中的UnicodeDecodeError

时间:2015-03-17 14:38:06

标签: python exception unicode export-to-excel xlsx

我试图编写一个方法来允许将数据从db导出到excel文件。我正在使用XlsxWriter库。

这是主要功能

def user_stats_to_excel():
    workbook = xlsxwriter.Workbook('user_stats_test.xlsx')
    worksheet = workbook.add_worksheet()

    worksheet.write_row(0, 0, UserStats.OUTPUT_ORDER)

    for i, user_stat in enumerate(UserStats.objects.all()):
    worksheet.write_row(i+1, 0, user_stat.output())

workbook.close()

然后在我的模型中我有:

def output(self, data=None):
    """ return a list that's ready for some csv writing """

    if data:
        self.data = data
    dir_self = dir(self)
    lst = []

    for name in self.O:
        if 'do_' + name in dir_self:
            out = getattr(self, "do_" + name)(name)
            if out is None:
                out = u""
            if isinstance(out, list):
                lst.extend(map(self.safe_encode, out))
            else:
                try:
                    lst.append(out.encode('utf-8'))
                except Exception:
                    lst.append(out)
        else:
            try:
                lst.append(self.data.get(name, "").encode('utf-8'))
            except Exception:
                lst.append(self.data.get(name, ""))

    return lst

def safe_encode(self, data):
    try:
        return data.encode('utf-8')
    except Exception:
        return data

正如您所看到的,我已经将编码放在任何地方,因为这是Python中unicode问题的常见修复。

我的堆栈跟踪是:

Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/james/pubfront/riidr/apps/stats/admin.py", line 34, in user_stats_to_excel
workbook.close()
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/workbook.py", line 286, in close
self._store_workbook()
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/workbook.py", line 509, in _store_workbook
xml_files = packager._create_package()
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/packager.py", line 140, in _create_package
self._write_shared_strings_file()
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/packager.py", line 280, in _write_shared_strings_file
sst._assemble_xml_file()
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/sharedstrings.py", line 53, in _assemble_xml_file
self._write_sst_strings()
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/sharedstrings.py", line 83, in _write_sst_strings
self._write_si(string)
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/sharedstrings.py", line 110, in _write_si
self._xml_si_element(string, attributes)
File "/Users/james/pubfront/riidr_venv/lib/python2.7/site-packages/xlsxwriter/xmlwriter.py", line 122, in _xml_si_element
self.fh.write("""<si><t%s>%s</t></si>""" % (attr, string))
File "/Users/james/pubfront/riidr_venv/lib/python2.7/codecs.py", line 688, in write
return self.writer.write(data)
File "/Users/james/pubfront/riidr_venv/lib/python2.7/codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 8: ordinal not in range(128)

我发现这是一个非常麻烦的调试,因为只有在user_stats_to_excel中调用workbook.close()时才会抛出错误,因此很难找到触发此问题的用户。我希望我不是唯一有这个问题的人

1 个答案:

答案 0 :(得分:1)

我们开始使用django utils来处理编码:https://docs.djangoproject.com/en/1.7/ref/utils/#module-django.utils.encoding

如果你没有使用django,那么厨房图书馆也有类似的功能: https://pythonhosted.org/kitchen/api-text-converters.html#kitchen.text.converters.to_bytes

我们唯一需要做的就是告诉xlsxwriter将url视为字符串 https://xlsxwriter.readthedocs.org/workbook.html#Workbook

workbook = xlsxwriter.Workbook(filename, {'strings_to_urls': False})