在 HttpResponse 中返回 python 字节数组

dge*_*gel 5 python django

我有一个 django 视图,我想返回一个 Excel 文件。代码如下:

def get_template(request, spec_pk):
    spec = get_object_or_404(Spec, pk=spec_pk)

    response = HttpResponse(spec.get_template(), mimetype='application/ms-excel')
    response['Content-Disposition'] = 'attachment; filename=%s_template.xls' % spec.name
    return response
Run Code Online (Sandbox Code Playgroud)

在该示例中, 的类型spec.get_template()包含<type 'bytearray'>Excel 电子表格的二进制数据。

问题是,当我尝试下载该视图并使用 Excel 打开它时,它会以乱码二进制数据的形式出现。我知道这bytearray是正确的,因为如果我执行以下操作:

f = open('temp.xls', 'wb')
f.write(spec.get_template())
Run Code Online (Sandbox Code Playgroud)

temp.xls我可以在Excel中完美打开。

我什至将我的观点修改为:

def get_template(request, spec_pk):
    spec = get_object_or_404(Spec, pk=spec_pk)
    f = open('/home/user/temp.xls', 'wb')
    f.write(spec.get_template())
    f.close()

    f = open('/home/user/temp.xls', 'rb')
    response = HttpResponse(f.read(), mimetype='application/ms-excel')
    response['Content-Disposition'] = 'attachment; filename=%s_template.xls' % spec.name
    return response
Run Code Online (Sandbox Code Playgroud)

它运行完美 - 我可以从浏览器将 xls 文件打开到 Excel,一切正常。

所以我的问题是 -bytearray在将其传递给HttpResponse. 为什么将其保存为二进制文件,然后重新打开它可以正常工作,但传递bytearray本身会导致乱码数据?

dge*_*gel 2

好吧,通过完全随机(并且非常持久)的试验和错误,我找到了使用 pythonbinascii模块的解决方案。

这有效:

response = HttpResponse(binascii.a2b_qp(spec.get_template()), mimetype='application/ms-excel')
Run Code Online (Sandbox Code Playgroud)

根据 python 文档binascii.a2b_qp

将带引号的可打印数据块转换回二进制并返回二进制数据。一次可以通过多于一行。如果可选参数标头存在且为 true,则下划线将被解码为空格。

希望有人告诉我为什么将其保存为二进制文件,然后重新打开它。