NPOI将Excel直接导出到前端,而无需将其保存在服务器上

时间:2018-12-06 08:59:25

标签: asp.net-core

是否可以将excel文件(带有NPOI)直接写入浏览器,而无需先将其保存在服务器上。

我尝试在控制器中执行以下操作,但未成功:

public async Task<IActionResult> ExportExcel(){

    var fs = new MemoryStream();

    IWorkbook workbook;
    workbook = new XSSFWorkbook();
    ISheet excelSheet = workbook.CreateSheet("Test);

    IRow row = excelSheet.CreateRow(0);
    row.CreateCell(0).SetCellValue("ID");
    row.CreateCell(1).SetCellValue("Name");

    row = excelSheet.CreateRow(1);
    row.CreateCell(0).SetCellValue(1);
    row.CreateCell(1).SetCellValue("User 1");

    workbook.Write(fs);

    byte[] bytes = new byte[fs.Length];
    fs.Read(bytes, 0, (int)fs.Length);


    return File(bytes, "application/vnd.ms-excel", sampleType.Abbreviation+".xlsx"); 
}

执行上述方法时,总是出现以下错误:

ObjectDisposedException: Cannot access a closed Stream.

...
System.IO.MemoryStream.get_Length()
byte[] bytes = new byte[fs.Length];
...

还是他们另一个出色的nuget程序包来处理(读取和写入)excel文件而不在服务器上存储文件?

PS:我使用的是dotnet core 2.1 en nuget软件包:https://www.nuget.org/packages/NPOI/

1 个答案:

答案 0 :(得分:1)

  1. 直接写到Response.Body
  2. 由于Excel被视为附件,因此我们还需要设置Response.Headers

为了使生活更轻松,我们可以首先创建一个扩展方法:

public static class IWorkBookExtensions {

    public static void WriteExcelToResponse(this IWorkbook book, HttpContext httpContext, string templateName)
    {
        var response = httpContext.Response;
        response.ContentType = "application/vnd.ms-excel";
        if (!string.IsNullOrEmpty(templateName))
        {
            var contentDisposition = new Microsoft.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            contentDisposition.SetHttpFileName(templateName);
            response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();
        }
        book.Write(response.Body);
    }
}

现在我们可以直接导出excel文件:

public async Task ExportExcel(){

    IWorkbook workbook;
    workbook = new XSSFWorkbook();
    ISheet excelSheet = workbook.CreateSheet("Test");

    IRow row = excelSheet.CreateRow(0);
    row.CreateCell(0).SetCellValue("ID");
    row.CreateCell(1).SetCellValue("Name");

    row = excelSheet.CreateRow(1);
    row.CreateCell(0).SetCellValue(1);
    row.CreateCell(1).SetCellValue("User 1");

    workbook.WriteExcelToResponse(HttpContext,"test.xlsx");
}

enter image description here