using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json.Linq; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Data; using System.Dynamic; namespace WCS.WebApi.Helper { public class ExportExcelHelper { /// /// /// 文件名 /// 标题行 /// 数据源 /// public static ActionResult ExportExcel(string sheetName, List columns, IList results) { var isXlsx = false; IWorkbook workbook = new HSSFWorkbook(); if (results.Count + 1 > 65536)// 包括一行标题行 .xls文件最大行数 { workbook = new XSSFWorkbook(); isXlsx = true; } workbook.CreateSheet(sheetName); var rowIndex = 0; AddHeader(workbook, rowIndex, columns); rowIndex++; workbook = AddData(workbook, rowIndex, columns, results); // Save the Excel spreadsheet to a MemoryStream and return it to the client using (var exportData = new MemoryStream()) { workbook.Write(exportData); var saveAsFileName = string.Format("{0}-{1:d}.{2}", sheetName, DateTime.Now, (isXlsx ? "xlsx" : "xls")).Replace("/", "-"); var contentType = isXlsx ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "application/vnd.ms-excel"; return new FileContentResult(exportData.ToArray(), contentType) { FileDownloadName = saveAsFileName }; } } public static ActionResult Export(string sheetName, IList columns, IEnumerable results) { var isXlsx = false; IWorkbook workbook = new HSSFWorkbook(); if (results.Count() + 1 > 65536)// 包括一行标题行 .xls文件最大行数 { workbook = new XSSFWorkbook(); isXlsx = true; } workbook.CreateSheet(sheetName); var rowIndex = 0; AddHeader(workbook, rowIndex, columns); rowIndex++; workbook = AddData(workbook, rowIndex, columns, results); // Save the Excel spreadsheet to a MemoryStream and return it to the client using (var exportData = new MemoryStream()) { workbook.Write(exportData); var saveAsFileName = string.Format("{0}-{1:d}.{2}", sheetName, DateTime.Now, (isXlsx ? "xlsx" : "xls")).Replace("/", "-"); var contentType = isXlsx ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "application/vnd.ms-excel"; return new FileContentResult(exportData.ToArray(), contentType) { FileDownloadName = saveAsFileName }; } } public static ActionResult Export( string sheetName, string firstData, IList columns, IEnumerable results ) { IWorkbook workbook = new HSSFWorkbook(); var sheet = workbook.CreateSheet(sheetName); var rowIndex = 0; // first row data var firstRow = sheet.CreateRow(rowIndex); firstRow.CreateCell(0).SetCellValue(firstData); rowIndex++; AddHeader(workbook, rowIndex, columns); rowIndex++; workbook = AddData(workbook, rowIndex, columns, results); // Save the Excel spreadsheet to a MemoryStream and return it to the client using (var exportData = new MemoryStream()) { workbook.Write(exportData); string saveAsFileName = string.Format("{0}-{1:d}.xls", sheetName, DateTime.Now).Replace("/", "-"); return new FileContentResult(exportData.ToArray(), "application/vnd.ms-excel") { FileDownloadName = saveAsFileName }; } } #region 数据操作 public static IWorkbook AddData(IWorkbook workbook, int rowIndex, List columns, IList results) { const int MaxRowCount = 1048575; //.xlsx文件最大行数1048576 var sheet = workbook.GetSheetAt(0); // Add data rows foreach (var viewModel in results) { var row = sheet.CreateRow(rowIndex); if (rowIndex >= MaxRowCount) { row.CreateCell(0).SetCellValue("数据行数已超出Excel文件支持的最大行数!"); break; } for (var index = 0; index < columns.Count; index++) { var propertyName = columns[index].Name.Trim(); var cell = row.CreateCell(index); var propertyDictionary = (IDictionary)viewModel; if (propertyDictionary.ContainsKey(propertyName)) { var value = propertyDictionary[propertyName]; cell.SetCellValue(value == null ? "" : value.ToString()); } } rowIndex++; } return workbook; } public static IWorkbook AddData(IWorkbook workbook, int rowIndex, IList columns, IEnumerable results) { const int MaxRowCount = 1048575; //.xlsx文件最大行数1048576 var sheet = workbook.GetSheetAt(0); // Add data rows foreach (var viewModel in results) { var row = sheet.CreateRow(rowIndex); if (rowIndex >= MaxRowCount) { row.CreateCell(0).SetCellValue("数据行数已超出Excel文件支持的最大行数!"); break; } for (int index = 0; index < columns.Count; index++) { var cell = row.CreateCell(index); var dr = viewModel as DataRow; var value = (dr != null) ? dr[columns[index].Name] : viewModel.GetType().GetProperty(columns[index].Name)?.GetValue(viewModel, null); if (value == null) { var item = viewModel as ExpandoObject; if (item != null) { if (item.Any(w => w.Key == columns[index].Name)) { var keyValue = item.FirstOrDefault(w => w.Key == columns[index].Name); value = keyValue.Value; } } } if (value == null) { var item = viewModel as JObject; if (item != null) { value = item[columns[index].Name]; } } cell.SetCellValue(value == null ? "" : value.ToString()); } rowIndex++; } return workbook; } public static void AddHeader(IWorkbook workbook, int rowIndex, IList columns) { var sheet = workbook.GetSheetAt(0); var format = workbook.CreateDataFormat(); // Add header labels var headerRow = sheet.CreateRow(rowIndex); for (int index = 0; index < columns.Count; index++) { headerRow.CreateCell(index).SetCellValue(columns[index].Caption); if (!string.IsNullOrEmpty(columns[index].Format)) { var columnStyle = workbook.CreateCellStyle(); columnStyle.DataFormat = format.GetFormat(columns[index].Format); sheet.SetDefaultColumnStyle(index, columnStyle); } if (columns[index].ColumnWidth.HasValue && columns[index].ColumnWidth.Value > 0) { var columnWidth = columns[index].ColumnWidth.Value; sheet.SetColumnWidth(index, columnWidth * 256 / 7); } } } #endregion } public class ExportableColumn { public ExportableColumn(string caption, string name) : this(caption, name, null) { } public ExportableColumn(string caption, string name, string format) { Format = format; Caption = caption; Name = name; } public ExportableColumn(string caption, string name, string format, int? width) : this(caption, name, format) { ColumnWidth = width; } public string Name { get; } public string Caption { get; } public string Format { get; } /// /// 单位:像素,为空时使用默认值 /// public int? ColumnWidth { get; private set; } public ExportableColumn Width(int? width) { ColumnWidth = width; return this; } } }