Reputation: 106
I'm using Excelize library for generating xlsx documents. When I use It's Write(io.writer)
func for saving xlsx to file, it works perfectly. But I need to generate and serve this file at web-server. I was trying this solution
func GetConsolidatedReport(w http.ResponseWriter, r *http.Request) {
var reportFile *excelize.File
...
var b bytes.Buffer
writr := bufio.NewWriter(&b)
reportFile.SaveAs("/tmp/testfile.xlsx")
reportFile.Write(writr)
writr.Flush()
fileContents := b.Bytes()
fileSize := strconv.Itoa(len(fileContents))
w.Header().Set("Content-Disposition", "attachment; filename=report.xlsx")
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Length", fileSize)
t := bytes.NewReader(b.Bytes())
io.Copy(w, t)
}
and after that i've got corrupted zip-file from web-server, but normal file saved in "/tmp/testfile.xlsx"
I've tried content-type as application/zip
, application/octet-stream
, application/vnd.*
but no luck.
Can you help me? Thank you in advance.
PS: By serving i mean on-the-fly generation of file, sorry for any misunderstanding.
PS2: It seems I get an overhead of downloaded file (8085 bytes of original and 13000+ of downloaded) and I can't figure it out where this overhead is come in.
Upvotes: 2
Views: 3078
Reputation: 322
i use *File.write api and it works:
package main
import (
"net/http"
"github.com/xuri/excelize/v2"
)
func main() {
s := http.Server{
Addr: ":8012",
}
http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
f := excelize.NewFile()
// Set value of a cell.
f.SetCellValue("Sheet1", "B2", 100)
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", "attachment; filename=example.xlsx")
w.Header().Set("Content-Transfer-Encoding", "binary")
f.Write(w)
})
s.ListenAndServe()
}
Upvotes: 1
Reputation: 8232
For serving a reader, you should consider http.ServeContent
. It will handle the header, content range and so on for you.
Change the line withio.Copy
with http.ServeContent(w,r,"testfile.xlsx",time.Now(),t)
and it shall work.
Documents: https://golang.org/pkg/net/http/#ServeContent
Upvotes: 3