📚
Golang Echo, Excelizeの出力をバイナリデータでHTTPリクエストのレスポンスとして返す
やりたいこと
- Excelizeで.xlsxファイルの生成
- ファイルとして保存せずにREST APIのレスポンスとして返す
どうやったか
ファイルを生成せずにHTTPリクエストのレスポンスに含めるには?という回答は以下のissueから回答を得ました。
WriteToBuffer() を使うことで、io.Readerとして bytes Bufferを受け取ることができます。
The execlize now support to get bytes.Buffer from the saved file by WriteToBuffer(), and we can get io.Reader
これをレスポンスと返す方法は以下の記事を参考にしました。他の実装例が見つからなかったのですごく助かりました。
具体的な実装
実際に実装したものの抜粋です。抜けがあったらごめんなさい。
バックエンド側(Go Echo)の抜粋
func CreateExcel(c echo.Context) error {
//excelファイル作成 具体的な内容は中略
f := excelize.NewFile()
buf, _ := f.WriteToBuffer()
r = strings.NewReader(buf.String())
//参考: https://github.com/qax-os/excelize/issues/127#issuecomment-435857445
setResponse(c, r)
return c.NoContent(http.StatusOK)
}
func setResponse(c echo.Context, body io.Reader) {
encodeName := url.QueryEscape("book.xlsx")
response := c.Response()
response.Header().Set("Cache-Control", "no-store")
response.Header().Set(echo.HeaderContentType, echo.MIMEOctetStream)
response.Header().Set(echo.HeaderAccessControlExposeHeaders, "Content-Disposition")
response.Header().Set(echo.HeaderContentDisposition, "attachment; filename="+encodeName)
response.WriteHeader(200)
io.Copy(response.Writer, body)
}
フロント側(axios) の実装部分
return axios
.get(`/url`, {
responseType: 'blob',
})
.then((response) => {
const filename = `book.xlsx` //フロント側でファイル名を決定
const a = document.createElement('a')
a.href = window.URL.createObjectURL(new Blob([response.data]))
a.setAttribute('download', filename)
a.click()
a.remove()
})
Discussion