繁体   English   中英

NPOI-保存到文件后,.xlsx工作簿损坏

[英]NPOI - After saving to file corrupts .xlsx workbook

我使用此代码编写了一个令人兴奋的Excel文件。 写入文件后,当我手动打开文件时,文件已损坏。 我正在使用NPOI二进制2.3.0.0,请告诉如何避免excel损坏。

[Authorize]
public void ExportUsers()
{
    var path = Server.MapPath(@"~\Content\ExportTemplates\") + "sample.xlsx";

    FileStream sw = new FileStream(path, FileMode.Open, FileAccess.Read);

    IWorkbook workbook = WorkbookFactory.Create(sw);       

    ISheet sheet = workbook.GetSheetAt(0);
    IRow row = sheet.GetRow(12);

    ICell cell = row.CreateCell(row.LastCellNum);
    cell.SetCellValue("test");
    workbook.CreateSheet("Ripon");            
    sw.Close();

    using (var exportData = new MemoryStream())
    {
        workbook.Write(exportData);
        string saveAsFileName = string.Format("Export-{0:d}.xls", DateTime.Now).Replace("/", "-");
        System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
        System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", saveAsFileName));
        System.Web.HttpContext.Current.Response.Clear();
        System.Web.HttpContext.Current.Response.BinaryWrite(exportData.GetBuffer());
        System.Web.HttpContext.Current.Response.End();                    
    }
}

新文件已创建但已损坏。 我见过有人说此问题已在2.0.6版中修复,但仍不适用于我

这里有几个问题。

首先,您从.xlsx文件开始,然后将下载文件扩展名更改为.xls .xls.xlsx文件格式不同; 前者是二进制格式,而后者是压缩的XML格式。 如果您使用错误的扩展名保存文件,则Excel在打开文件时会报告该文件已损坏。

其次,您使用了错误的方法从MemoryStream获取数据。 GetBuffer将返回整个分配的内部缓冲区数组,如果缓冲区未完全满,它将包含超出数据末尾的所有未使用字节。 多余的空字节将导致下载的文件损坏。 如果只想获取缓冲区中的数据,则应改用ToArray

第三,看起来您正在使用ASP.NET MVC框架(基于方法中[Authorize]属性的存在),但是您正在直接操纵当前响应,而不是使用控制器的内置File方法来返回可下载的文件。 我建议尽可能使用内置方法,因为这会使您的代码更简洁。

这是更正的代码:

[Authorize]
public ActionResult ExportUsers()
{
    var path = Server.MapPath(@"~\Content\ExportTemplates\") + "sample.xlsx";

    FileStream sw = new FileStream(path, FileMode.Open, FileAccess.Read);

    IWorkbook workbook = WorkbookFactory.Create(sw);

    ISheet sheet = workbook.GetSheetAt(0);
    IRow row = sheet.GetRow(12);

    ICell cell = row.CreateCell(row.LastCellNum);
    cell.SetCellValue("test");
    workbook.CreateSheet("Ripon");
    sw.Close();

    var exportData = new MemoryStream();
    workbook.Write(exportData);
    exportData.Seek(0, SeekOrigin.Begin);  // reset stream to beginning so it can be read

    string saveAsFileName = string.Format("Export-{0:d}.xlsx", DateTime.Now).Replace("/", "-");

    return File(exportData, "application/vnd.ms-excel", saveAsFileName);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM