System.InvalidOperationException: Response Content-Length mismatch: too few bytes written (0 of 1628

      今天记录下通过微软官方开源技术open-xml-sdk操作excel写入内存流,并将该内存流返回给Web客户端,该方法服务器端不用保存本地Excel文件,没有和磁盘的IO开销,效率更高,也不存在服务器excel文件太多需要删除的情况。废话不多说,直接上代码:

public static IActionResult ExportTest(string fileName)
        {
            MemoryStream stream = new MemoryStream();
            //第一步,从输入输出流创建Excel文档包SpreadsheetDocument,这里使用内存流
            SpreadsheetDocument document = SpreadsheetDocument.Create(stream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
            //第二步,添加WorkbookPart,并创建Workbook对象
            WorkbookPart workbookPart = document.AddWorkbookPart();
            workbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
            //第三步,添加WorksheetPart,并创建Worksheet对象
            WorksheetPart worksheetPart = workbookPart.AddNewPart();
            worksheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(new SheetData());
            //第四步,给Workbook添加Worksheets
            Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
            //第五步,创建Sheet对象实例,并绑定到给Workbook中,并将此sheet加入Sheets
            Sheet sheet = new Sheet() { Id=document.WorkbookPart.GetIdOfPart(worksheetPart),SheetId=1,Name="mySheet"};
            sheets.Append(sheet);
            //第六步,保存workbook
            workbookPart.Workbook.Save();
            //第七步,关闭Excel文档包SpreadsheetDocument
            document.Close();

            //必须将流的当前位置置0,否则将引发异常
            //如果不设置为0,则流的当前位置在流的末端1629,然后读流就会从索引1629开始读取,实际上流的最大索引是1628,就会引发无效操作异常System.InvalidOperationException
            //System.InvalidOperationException: Response Content-Length mismatch: too few bytes written (0 of 1628)
            stream.Position = 0;

            string fileExt = Path.GetExtension(fileName);
            var provider = new FileExtensionContentTypeProvider();

            var memi = provider.Mappings[fileExt];
            FileStreamResult fileStreamResult = new FileStreamResult(stream, memi) { FileDownloadName = fileName };
            return fileStreamResult;
        }

需要添加的引用:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;

 

此过程中比较容易出错的点就是很多人容易忘记“stream.Position = 0;”这行代码,所以我记录下来,供大家参考。

你可能感兴趣的:(.NET)