使用Datatable.js和ClosedXML导出Excel时最后列出现未知标识符‘item’错误
使用Datatable.js触发后端导出,结合ClosedXML的XLTemplate生成Excel文件,导出后最后一列始终显示未知标识符‘item’错误。更换ReportedBy为ABC6、ABC7等其他参数后错误仍存在,但其余列数据显示正常。
相关代码
服务器端导出代码
string webRootPath = _env.WebRootPath; var template = new XLTemplate($"{webRootPath}\\ReportTemplates\\{model.ReportId.ToString()}Template.xlsx"); template.AddVariable("ReportDisplayName", model.ReportDisplayName); template.AddVariable("ReportParameters", model); switch (model.ReportId) { case ReportNames.FallReport: var fallReportData = returnModel.ReportData as List<FallReportViewModel>; template.AddVariable("ReportData", fallReportData); break; ... } // end of switch template.Generate(); using (MemoryStream stream = new MemoryStream()) { template.SaveAs(stream); var fileName = $"{model.ReportDisplayName}_{DateTime.Now.ToShortDateString()}.xlsx"; return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName); }
前端jQuery代码
buttons: [ { text: 'Export to PDF', action: function (e, dt, node, config) { .... } }, { text: 'Export to Excel', action: function (e, dt, node, config) { if (ValidateReportParameterAndContent()) { $("#ReportType").val("xls"); $("#ReportDisplayName").val($("#reportName").val()); $("#frmReport").submit(); setTimeout(function () { $(" .page-loader").css('display', 'none'); }, 3000); } } } ],
数据库查询代码
var myList = _context.MyReports.Include(r => r.PatientDemographic) .Where(r => r.CreatedDate.Date >= model.reportParameters.StartDate.Value && r.CreatedDate.Date <= model.reportParameters.EndDate.Value && !r.IsDeleted) .OrderBy(sortBy) .Skip(skip) .Take(take) .Select(a => new FallReportViewModel { ABC = a.PatientDemographic.ABC, PatientName = a.PatientDemographic.DisplayName, ReportedBy = "", ABC2 = a.DateOfFall.Value.Date.ToString(@"MM\/dd\/yyyy"), ABC3 = a.ABC3.Value.Date.ToString(@"MM\/dd\/yyyy"), CreatedBy = a.CreatedBy, CreatedDate = a.CreatedDate.Date, UpdatedDate = a.UpdatedDate, ABC5 = a.ABC5, ABC4 = a.ABC4, ABC2 = a.ABC2, ABC7 = a.ABC7.Name, }).ToList(); foreach (var item in myList) { var reportedByUser = agencyUsers.FirstOrDefault(au => au.ApplicationUserId == item.CreatedBy); if (reportedByUser != null) { item.ReportedBy = $"{reportedByUser.UserName} ({reportedByUser.UserType.UserTypeName})"; } }
注:ViewModel中已定义所有列的数据类型,其中ReportedBy列为string类型。
解决方案
检查Excel模板的最后一列语法
打开导出用的Excel模板,查看最后一列的单元格内容,确认模板表达式是否正确。比如应该使用{{ReportData.ReportedBy}}(或对应列的ViewModel属性名),而不是错误的{{item}}或未定义变量。验证模板循环语法
确认模板中遍历ReportData的循环标签是否正确闭合,比如是否用{{foreach ReportData}}开头,{{end}}结尾,且循环内部的变量引用均指向FallReportViewModel的属性。核对属性名一致性
确保模板中所有列的变量名与FallReportViewModel的属性名完全一致(注意大小写,ClosedXML模板语法区分大小写)。排查模板标签闭合问题
检查模板中是否存在未闭合的foreach、if等标签,这类语法错误可能导致解析器误识别变量,出现item未知错误。逐步排查列问题
临时移除模板中的最后一列,测试导出是否正常。如果正常,再逐列添加排查,定位到具体出错的列表达式。修正代码中的重复赋值问题
数据库查询代码中ABC2被重复赋值(先赋值为日期字符串,后被a.ABC2覆盖),虽然不是当前错误的直接原因,但可能引发其他数据异常,建议修正该重复赋值。
内容的提问来源于stack exchange,提问作者shubhkr1

