将数据输出到 CSV 文件时,数据被展示在浏览器上但并未被存储到文件中。

4

我尝试在golang beego框架中将一些数据输出到csv文件,以下是我的代码

records := make([][]string,len(devicesData))

for k,v := range devicesData{
    records[k] = []string{v.Fields.Country,v.Fields.Imei[0],v.Fields.Number[0]}
}

writer := csv.NewWriter(this.Controller.Ctx.ResponseWriter)
for _, record := range records {
    err := writer.Write(record)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
}

this.Ctx.Output.Header("Content-Type", "application/csv")
this.Ctx.Output.Header("Content-Disposition", "attachment; filename=MyVerySpecial.csv")

    writer.Flush()

然而,它只能在浏览器中显示记录数据,不能下载文件。在这个下载文件控制器之前,我有一些登录控制器和过滤函数,我不知道它是否受到影响。我的代码出了什么问题?谢谢。


如果您无论如何都要按记录循环,可以针对每个记录调用 Write([]string{...}) 而不是将其存储在 [][]string 中。但是,如果您确实想先处理它们并将它们存储在 [][]string 中,则可以使用 WriteAll 来写入所有记录,而不是再次进行循环。 - Dave C
1个回答

3

您应该始终先设置响应头,然后再开始编写任何输出数据。我知道您在设置标题字段后调用了writer.Flush(),但这绝不保证数据不会在此之前被刷新或发送 - 这将意味着发送默认标头。在此之后,不能发送或更改任何其他标头。

另外,CSV的正确MIME类型是text/csv而不是application/csv(rfc4180)。

此外,标头更像是对浏览器的“建议”。这表明您建议响应是要保存为文件的,但从服务器端,您无法强制浏览器真正将响应保存到文件而不是显示它。

有关"Content-Disposition"头字段的更多详细信息,请参见rfc1806, rfc2183rfc6266。基本上,它传递了演示信息。

Content-Disposition响应头字段用于传达有关如何处理响应有效载荷的其他信息,还可用于附加其他元数据,例如在本地保存响应有效载荷时要使用的文件名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接