csv文件不能通过http响应下载

时间:2016-07-08 21:42:47

标签: python django httpresponse export-to-csv

我正在尝试将字典转换为csv,然后即时下载csv文件。当我返回响应时,我会看到httpresponse中的行。但我希望它将内容下载到本地计算机的csv文件中。

def export_csv_from_dict(data):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="accounts.csv"'

    keys = data[0].keys()
    dict_writer = csv.DictWriter(response, keys)
    dict_writer.writeheader()
    dict_writer.writerows(data)

    return response

def accounts_function(request):
    # rows is a list of dictionary [{'name': 'a'}, {'name': 'b'}]
    rows = get_rows_data(matched_accounts)
    return data.export_csv_from_dict(rows)

我在stackoverflow上尝试了很多不同的方法,例如filewrapper,使用FileResponse,使用写入临时文件并使用filewrapper返回它。还尝试使用StringIO。似乎没有人做我想做的事情。请有人解释我做错了什么。感谢。

在chrome调试器中,我看到了所需csv格式的正确内容。它不会弹出下载到计算机窗口/操作。

现在我正在触发它。不要以为这个

    $('#exp_csv').click(function(){
        $.ajax({
            'url': '/targeturl/',
            'type': 'get',
            data: {
                'exp_csv': true,
                'search_string': search
            },
            success: function(response){
                // do something
            },
            error: function(){
                // do something else
            }
        })
    });

2 个答案:

答案 0 :(得分:2)

您是否尝试过使用简单的硬编码行数据?以下基于您的示例的代码应该可以正常工作。如果它有效,那么在动态填充行数据时一定存在问题,这需要一些关于get_rows_data函数如何工作的额外信息。

def export_csv_from_dict(self, data):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    fieldnames = data[0].keys()
    writer = csv.DictWriter(response, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerows(data)
    return response

def accounts_function(self, request):
    rows = [{'first_name': 'Baked', 'last_name': 'Beans'},
            {'first_name': 'Lovely', 'last_name': 'Spam'},
            {'first_name': 'Wonderful', 'last_name': 'Spam'}]
    return self.export_csv_from_dict(rows)

答案 1 :(得分:1)

我在代码的基础上发现了一个草率的错误:

  

# rows is a list of dictionary [{'name': 'a'}, {'name': 'b'}]

这似乎是一种致命的结构。

  • 如果您有许多具有相同键的词典,为什么不使用仅包含值的列表并遍历每个行的列表?

    rows = ['a', 'b',]

  • 如果密钥不同:

      

    keys = data[0].keys()

    上述代码不会为您提供您期望的结果。它只返回列表中第一个字典的键。您应该遍历该列表并分别从每个字典中收集密钥,或者按如下方式构造rows

    rows = [{'name1': 'a', 'name2': 'b'},]