服务端以内存方式导出 Excel 并设置自动列宽
简介
基于 NPOI/DOCX 帮助类 修改,在服务端导出 Excel 应尽量直接在内存中处理,减少磁盘写入,同时实现设置自动列宽。
代码
帮助类修改
基于帮助类中 FillDataTable 方法修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
public static void AutoColumnWidth(ISheet sheet, int cols) { for (int col = 0; col <= cols; col++) { int columnWidth = sheet.GetColumnWidth(col) / 256; for (int rowIndex = 0; rowIndex <= sheet.LastRowNum; rowIndex++) { IRow row = sheet.GetRow(rowIndex); ICell cell = row.GetCell(col); int contextLength = Encoding.UTF8.GetBytes(cell.ToString()).Length; columnWidth = columnWidth < contextLength ? contextLength : columnWidth;
} sheet.SetColumnWidth(col, columnWidth * 256); } }
public static MemoryStream FillDataTableStream(string strSheetName, DataTable dtSourceData, bool WhetherThereFieldName, int iRows, int iColumn) { try { if (string.IsNullOrEmpty(strSheetName) || dtSourceData.Rows.Count < 1) { return null; }
IWorkbook iWorkBook = new XSSFWorkbook(); ISheet iSheet = iWorkBook.CreateSheet(strSheetName);
if (WhetherThereFieldName) { IRow rowDataTableField = iSheet.CreateRow(iRows); for (int iDataTableColumns = 0; iDataTableColumns < dtSourceData.Columns.Count; iDataTableColumns++) { ICell cellErrstatist = rowDataTableField.CreateCell(iDataTableColumns + iColumn); cellErrstatist.SetCellValue(dtSourceData.Columns[iDataTableColumns].ColumnName); } for (int iDataTableRows = 0; iDataTableRows < dtSourceData.Rows.Count; iDataTableRows++) { IRow rowDataTable = iSheet.CreateRow(iDataTableRows + iRows + 1); for (int iDataTableColumns = 0; iDataTableColumns < dtSourceData.Columns.Count; iDataTableColumns++) { ICell cellErrstatist = rowDataTable.CreateCell(iDataTableColumns + iColumn); string strSourceData = dtSourceData.Rows[iDataTableRows][iDataTableColumns].ToString(); Regex regexIsNumeric = new Regex(@"^(-?\d+)(\.\d+)?$"); if (regexIsNumeric.IsMatch(strSourceData)) { cellErrstatist.SetCellValue(double.Parse(strSourceData)); } else { cellErrstatist.SetCellValue(strSourceData); } }
AutoColumnWidth(iSheet, dtSourceData.Columns.Count - 1); } } else { for (int iDataTableRows = 0; iDataTableRows < dtSourceData.Rows.Count; iDataTableRows++) { IRow rowDataTable = iSheet.CreateRow(iDataTableRows + iRows); for (int iDataTableColumns = 0; iDataTableColumns < dtSourceData.Columns.Count; iDataTableColumns++) { ICell cellErrstatist = rowDataTable.CreateCell(iDataTableColumns + iColumn); string strSourceData = dtSourceData.Rows[iDataTableRows][iDataTableColumns].ToString(); Regex regexIsNumeric = new Regex(@"^(-?\d+)(\.\d+)?$"); if (regexIsNumeric.IsMatch(strSourceData)) { cellErrstatist.SetCellValue(double.Parse(strSourceData)); } else { cellErrstatist.SetCellValue(strSourceData); } } } }
MemoryStream stream = new MemoryStream(); iWorkBook.Write(stream, false); iWorkBook.Close(); return stream; } catch (Exception ex) { return null; } }
|
代码调用
调用使用服务端 .NET 6.0 API
1 2 3 4 5 6 7 8 9 10 11
| [HttpGet] public IActionResult Export() { DataTable dataTable = new DataTable();
...
MemoryStream msExcel = Helper.ExcelHelper.FillDataTableStream("Sheet1", dataTable, true, 0, 0); MemoryStream memoryStream = new MemoryStream(msExcel.ToArray()); return File(memoryStream, "application/octet-stream", Path.GetFileName($"{Guid.NewGuid()}.xlsx"), true); }
|