【问题标题】:Django generate csv file on view and downloadDjango 在查看和下载时生成 csv 文件
【发布时间】:2017-06-02 01:55:47
【问题描述】:

我有这个代码:

    with open('stockitems_misuper.csv', 'wb') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerows(file_rows)

    response = HttpResponse(myfile, content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=stockitems_misuper.csv'
    return response

我得到错误:

对关闭文件的 I/O 操作

如何将创建的 csv 文件发送到前端?

【问题讨论】:

    标签: python django csv


    【解决方案1】:

    您正在传递正在写入的文件的句柄(不确定您的缩进,您可能只是在 with 块之外。

    只需在阅读模式下重新打开它。

    with open('stockitems_misuper.csv', 'w', newline="") as myfile:  # python 2: open('stockitems_misuper.csv', 'wb')
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerows(file_rows)
    
    with open('stockitems_misuper.csv') as myfile:
        response = HttpResponse(myfile, content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=stockitems_misuper.csv'
        return response
    

    或更好:写入io.StringIO() 实例,并传递它,避免创建文件。

    import io,csv
    
    buffer = io.StringIO()  # python 2 needs io.BytesIO() instead
    wr = csv.writer(buffer, quoting=csv.QUOTE_ALL)
    wr.writerows(file_rows)
    
    buffer.seek(0)
    response = HttpResponse(buffer, content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=stockitems_misuper.csv'
    
    return response
    

    【讨论】:

    • 我必须将导入更改为 from io import BytesIO as StringIObuffer = StringIO() 才能完成这项工作,但其他解决方案很棒!
    • 那是因为您使用的是 Python 2(在您的示例中,您使用“wb”来创建 csv 文件,因此它必须是 python 2,已编辑)
    • 缓冲区不会将完整的 file_rows 保存在内存中,从而消除流式 http 响应的优势吗?
    • 这可能可以做到,使用具有“读取”方法的自定义对象,该方法在需要时使用来自file_rows 的数据。更复杂。如果文件很小,不值得。
    • 这对于非常大的 CSV 文件是否可行?如果没有,那么我该如何实现它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    相关资源
    最近更新 更多