Ant Design Pro V4.0结合.NET WebApi通过NPOI导出Excel功能

2 篇文章 0 订阅
1 篇文章 0 订阅

Ant Design Pro V4.0结合.NET WebApi通过NPOI导出Excel功能

整体思路
先说思路,通过WebApi生成二进制文件流,返给前端。前端通过Blob接收二进制文件流对象以及文件名,实现导出功能。

WebApi端实现
首先来个简单的,读取后端一个Excel文件并以文件流的形式导出

public HttpResponseMessage GetFileStream()
{
    //var path = @"C:\AZCode\AZEviewApiCodeFirst\AZ.EView\AZ.EView.API\wwwroot\Upload\316e9bf92ce14536b51ca52df57776c2.xlsx";
    var path = @"F:\webroot\AZEViewCodeFirst_api\wwwroot\Upload\d33652f18de840c689143408449cb4bc.xlsx";
    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
    result.Content = new StreamContent(stream);
    result.Content.Headers.ContentType =
        new MediaTypeHeaderValue("application/octet-stream");
    return result;
}

通过Postman或者前端调用发现,这里的文件流可正常下载Excel,那么接下来考虑通过NPOI导出一个Excel文件流的实现。

[HttpPost]
[Route("TagAddUser/GetFileStream")]
public HttpResponseMessage GetFileStream(int tagid)
{
    //...获取要导出的数据转成DataTable
    NPOIHelper nPOIHelper = new NPOIHelper();
    return nPOIHelper.TableToExcel(dt, Guid.NewGuid().ToString().Replace("-", "") + ".xlsx");
}

NPOI生成文件流方法,这里注意转换二进制

/// <summary>
/// Datable导出成Excel
/// </summary>
/// <param name="dt"></param>
/// <param name="file">文件名带扩展名</param>
public HttpResponseMessage TableToExcel(DataTable dt, string file)
{
    IWorkbook workbook;
    string fileExt = Path.GetExtension(file).ToLower();
    if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); } else { workbook = null; }
    if (workbook == null) { return null; }
    ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);

    //表头  
    IRow row = sheet.CreateRow(0);
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        ICell cell = row.CreateCell(i);
        cell.SetCellValue(dt.Columns[i].ColumnName);
    }

    //数据  
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        IRow row1 = sheet.CreateRow(i + 1);
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            ICell cell = row1.CreateCell(j);
            cell.SetCellValue(dt.Rows[i][j].ToString());
        }
    }

    //创建文件流  
    MemoryStream stream = new MemoryStream();
    //文件写入流(向流中写入字节序列)
    workbook.Write(stream);

    //转成二进制
    //stream.ToArray()

    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);

    result.Content = new ByteArrayContent(stream.ToArray());
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = HttpUtility.UrlEncode(file, Encoding.UTF8),
    };

    return result;
}

Ant Design Pro前端实现
前端用Blob去接,并保存,这种方式可以很从容优雅的操作后端返回的文件流

exportExcel = (key: number) => {
  let filename: string = '';
  fetch(`${API_URL}/TagAddUser/GetFileStream?tagid=${key}`, {
    method: 'POST',
  })
    .then(res => {
      var tempfilename = res.headers.get('content-disposition')?.split(';')[1].split('=')[1];
      if (tempfilename === undefined) {
        filename = 'fans.xlsx';
      } else if (tempfilename != undefined) {
        filename = tempfilename;
      }
      return res.blob()
    })
    .catch(error => console.error('Error:', error))
    .then((data) => {
      let blobUrl = window.URL.createObjectURL(data);
      this.download(blobUrl, filename);
    });


}

download = (blobUrl: any, name: string) => {
  const a = document.createElement('a');
  a.style.display = 'none';
  a.download = name;
  a.href = blobUrl;
  const body = document.getElementsByTagName("body")
  body[0].appendChild(a);
  a.click();
  document.body.removeChild(a);
}

Ant Design Table的Column属性绑定导出功能

progressColumns = [
  {
    title: "标签ID",
    dataIndex: 'id',
  },
  {
    title: "标签名",
    dataIndex: 'name',
  },
  {
    title: "粉丝数",
    dataIndex: 'count',
  },
  {
    title: '操作',
    key: 'action',
    render: (text: string, record: TableListItem) => {
      if (record.count > 0) {
        return (
          <span>
            <a onClick={(e) => this.exportExcel(record.id)}>导出粉丝</a>
          </span>
        );
      }
    },
  },

];

总结
React前端其实有很多数据转成.xlsx .csv的类库,也能实现导出Excel等功能,那样就是数据返给前端,大部分的工作由前端来做,但是综合考虑我还是更喜欢后端处理数据多一些,如果数据量是百万级很难想象一个超大的数据包丢给前端去处理会发生什么。

ps:本人是热衷于React的.NET后端程序猿

仅供学习参考,如有侵权联系我删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值