Вывод в файл csv сбрасывает данные в браузер, но не в файл

Я попытался вывести некоторые данные в файл csv в рамках golang beego, вот мой код

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()

Однако он показывает только данные записи в браузере, он не может загрузить файл. У меня есть некоторый контроллер регистрации и функция фильтрации перед этим контроллером файла загрузки, я не знаю, влияет ли это. Что не так с моим кодом? Спасибо


person want_to_be_calm    schedule 24.06.2015    source источник
comment
К вашему сведению (вы, вероятно, знаете это, я предполагаю, что приведенный выше код был упрощен для вопроса, но для других читателей), если вы все равно собираетесь зацикливаться на каждой записи, вы можете просто вызвать Write([]string{…}) для каждой записи, а не сохранять ее в [][]string. Однако, если вы хотите сначала обработать их все и сохранить в [][]string, вы можете использовать WriteAll чтобы записать все записи вместо того, чтобы снова зацикливаться самостоятельно.   -  person Dave C    schedule 24.06.2015


Ответы (1)


Вы всегда должны устанавливать заголовки ответа сначала и только после этого начинать записывать какие-либо данные в вывод. Я знаю, что вы вызвали writer.Flush() после установки полей заголовка, но это не гарантирует, что данные не будут сброшены или отправлены до этого, что будет означать отправку заголовков по умолчанию. После этого никакие дополнительные заголовки не могут быть отправлены или изменены.

Также правильным типом mime для CSV является text/csv, а не application/csv (rfc4180).

Кроме того, заголовки больше похожи на "предложение" для браузера. Во-первых, вы предлагаете, чтобы ответ был файлом, который нужно сохранить, но со стороны сервера вы не можете заставить браузер действительно сохранить ответ в файл, а не отображать его.

См. rfc1806, rfc2183 и rfc6266 для более подробной информации. о поле заголовка "Content-Disposition". В основном он передает информацию о презентации.

Поле заголовка ответа Content-Disposition используется для передачи дополнительных сведений о том, как обрабатывать полезные данные ответа, а также может использоваться для прикрепления дополнительных метаданных, таких как имя файла, которое будет использоваться при локальном сохранении полезных данных ответа.

person icza    schedule 24.06.2015