最新版ClosedXML通过API返回工作簿功能失效 输出空文件问题咨询
问题根因
核心问题出在CreateWorkbook方法中对XLWorkbook对象的using声明使用错误:
using块会在代码离开作用域时自动调用对象的Dispose方法,你在using块内返回workbook对象,方法返回前workbook就已经被释放- 最新版ClosedXML优化了
Dispose方法的实现,会清理工作簿的单元格内容、样式等业务数据,仅保留工作表名称这类基础结构,因此会出现「标签存在但无内容」的问题;旧版本Dispose逻辑未做深度清理,因此之前的代码可以正常运行
解决方案
改动最小的适配方案仅需要移除CreateWorkbook方法中不必要的using声明即可,无需修改现有响应逻辑:
private static ClosedXML.Excel.XLWorkbook CreateWorkbook(ControlReportsView model, string client) { // 移除using声明,避免工作簿对象提前被释放 var workbook = new ClosedXML.Excel.XLWorkbook(); CreateTestTab(model, client, workbook); return workbook; }
修改后你原有Get方法的workbook.SaveAs(stream)逻辑就可以正常写入全部内容到流中,无需调整其余响应配置。
如果需要进一步提升稳定性,也可以参考你现有正常运行的字节数组返回方案,避免流生命周期管理问题,仅需要对Get方法做小幅调整:
public HttpResponseMessage Get([FromUri]ControlReportsView model) { string client = "EU"; ClosedXML.Excel.XLWorkbook workbook = CreateWorkbook(model, client); MemoryStream stream = new MemoryStream(); workbook.SaveAs(stream); // 转成字节数组后释放工作簿和流对象,避免资源泄漏 byte[] fileBytes = stream.ToArray(); workbook.Dispose(); stream.Dispose(); var response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new ByteArrayContent(fileBytes); // 其余响应头配置保持原有逻辑不变 response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); response.Content.Headers.ContentDisposition.FileName = string.Format("{0}_{1:yyyyMMdd hhmmtt} to {2:yyyyMMdd hhmmtt}.xlsx", model.Type.ToString(), model.StartDate, model.EndDate); response.Headers.CacheControl = new CacheControlHeaderValue() { Private = true, MaxAge = TimeSpan.FromSeconds(300) }; return response; }
内容的提问来源于stack exchange,提问作者VBartilucci
相关产品推荐
相关产品推荐

