【Excel】根据模板导出Excel,后端返回文件流前端下载

需求描述:

前端发送请求后,接收后端返回的文件流(一般是乱码),实现导出Excel(根据模板生成Excel)

OrderManageController.cs

/// <summary>
/// 通过模板导出Excel文件
/// </summary>
/// <param name="orderInfoList"></param>
[HttpPost, Route("ExportConfirmOrderList")]
public FileResult ExportConfirmOrderList(List<OrderInfoView> orderInfoList)
{
    string templatePath = ServerMapPath("/ui/FileTemplate/汇款信息模板.xlsx");
    string sheetName = "汇款信息";

    IWorkbook workBook;
    using (FileStream fs = System.IO.File.Open(templatePath, FileMode.Open, FileAccess.Read))
    {
        workBook = new XSSFWorkbook(fs);
    }

    using (MemoryStream ms = new MemoryStream())
    {
        var sheet = workBook.GetSheet(sheetName);
        int startRowIndex = 2;   //首行为提示文字,正式数据从第二行开始
        foreach (var orderInfo in orderInfoList)
        {
            var row = sheet.CreateRow(startRowIndex++);
            row.CreateCell(0).SetCellValue(orderInfo.ProjectCode1Name);
            row.CreateCell(1).SetCellValue(orderInfo.AppName);
            row.CreateCell(2).SetCellValue(orderInfo.PayAccountName);
            row.CreateCell(3).SetCellValue(orderInfo.OrderNo);
            row.CreateCell(4).SetCellValue(orderInfo.remitter);
            row.CreateCell(5).SetCellValue(orderInfo.RemittanceAmount.ToString());
            row.CreateCell(6).SetCellValue(orderInfo.RemittanceMobile);
            row.CreateCell(7).SetCellValue(orderInfo.RemitRemark);
        }

        workBook.Write(ms);
        ms.Seek(0, SeekOrigin.Begin);
        //return File(bt, "application/vnd.ms-excel", "汇款信息.xlsx");  如果这样写一直报会无法找到关闭的流的错误,因为return的时候ms流已经被Dispose()了  
        byte[] bt = ms.ToArray(); //解决方案:将ms用中间量存下来,转为byte数组以便于关闭ms 
        return File(bt, "application/vnd.ms-excel", "汇款信息.xlsx");
    } 
}

order.js

export function ExportConfirmOrderList(data) { 
    return request({
        url: '/order/ExportConfirmOrderList', 
        data, 
        method: 'post',
        responseType: 'blob'  //在请求接口的时候请求头要添加responseType: 'blob'
    }) 
}

orderList.vue

exportConfrimOrderToExcel(){ 
  ExportConfirmOrderList(this.exportdata).then(res => {
    // console.log(res)
    var that = this
    //创建一个隐藏的a连接,
    const link = document.createElement('a')
    link.style.display = 'none'

    //Blob对象(是一个可以存储二进制文件的容器);第一个参数为一个数据序列,可以是任意格式的值,第二个参数用于指定将要放入Blob中的数据的类型,比如:type: 'application/x-excel' 或 type: 'text/plain'
    const blob = new Blob([res], {type: 'application/vnd.ms-excel'})
    
    //URL.createObjectURL()方法通过传入的参数(参数:用于创建url的file对象,Blob对象或者MediaSource对象),创建一个指向该参数对象的URL,绑定到创建a标签的href属性上
    link.href = URL.createObjectURL(blob)
    link.download = '汇款信息.xlsx'   //自定义文件名

    //往body上面append这个a标签,并执行a标签的点击事件,进行文件的导出,最后导出成功后,把a标签从body上面移除
    document.body.appendChild(link) 
    link.click()  //模拟点击事件
    document.body.removeChild(link)
  })
},

 

posted @ 2022-04-02 15:26  智者见智  阅读(717)  评论(0编辑  收藏  举报