1.前端响应体需要设置blob,二进制流类型 2.kratos 服务,注意上下文使用的是http.context,数据写入响应体,并设置响应header
<script type="text/javascript">
function downloadExcel() {
const xhr = new XMLHttpRequest();
const url = 'http://nb.baiye.com/ai-sky/v1/comment/download?start_time=2023-09-01+00:00:00&end_time=2023-09-19+23:59:59';
xhr.open('GET', url, true);
xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
xhr.setRequestHeader('Accept-Language', 'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,pt;q=0.6,zh-TW;q=0.5,it;q=0.4,da;q=0.3');
xhr.setRequestHeader('Connection', 'keep-alive');
xhr.setRequestHeader('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36');
xhr.setRequestHeader('X-Token', 'eyJpdiI6IjFZZ0lZcVJ2YT0hcL1pzQlR1andPQVFCT0xoT2dKYnh2RjdUZGliSnhJZnQ1Sjk2ZmFTY2Q0MnJrZHVkT1RvaWNDMkV4K2tGM0I1dWhFamVVOXlkZ3BQTFFkXC9MN1p4d0dsNld6d0dQWT0iLCJtYWMiOiI4OTQyMWU0OTRlMzAxYjhhM2I4ZmM3ODFmYTdhYzA2YzFmOTYyN2Y0MzQ3MjU3NDA4NTNiNTAwNWQwYTAzOGU2In0=');
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
const blob = xhr.response;
// 下载文件
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = 'comments.xlsx';
downloadLink.click();
URL.revokeObjectURL(downloadLink.href);
} else {
console.error('请求失败', xhr.status);
}
}
};
xhr.responseType = 'blob';
xhr.send();
}
</script>
<button onclick="downloadExcel()">点击下载</button>
2.kratos 服务
.....
comment := srv.Route("/v1/comment")
comment.GET("/download", commentService.CommentDownload)
.....
import (
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/go-kratos/kratos/v2/transport/http"
)func (s *CommentService) CommentDownload(ctx http.Context) error {
rawURL := ctx.Request().URL
u, err := url.Parse(rawURL.String())
if err != nil {
return err
}
stime := u.Query().Get("start_time")
etime := u.Query().Get("end_time")f := excel.NewExcel()
sheetName := "Sheet1"
fileName := "comments.xlsx"
f.File.NewSheet(sheetName)
.....
f.SetHeader(sheetName, headers)
....
buf := new(bytes.Buffer)
err = f.File.Write(buf)
// 保存到本地
if err = f.File.SaveAs(fileName); err != nil {
return err
}
// 数据写入http响应体,并且设置响应header
_, err := ctx.Response().Write(content)
ctx.Response().Header().Set("Content-Disposition", "attachment; filename="+fileName)
ctx.Response().Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")