Files
wcs/WCS.WebApi/Helper/ExportExcelHelper.cs
hehaibing-1996 e89b64ea3a !提交代码
2024-04-15 18:43:28 +08:00

250 lines
9.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// </summary>
/// <param name="sheetName">文件名</param>
/// <param name="columns">标题行</param>
/// <param name="results">数据源</param>
/// <returns></returns>
public static ActionResult ExportExcel(string sheetName, List<ExportableColumn> columns, IList<dynamic> 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<T>(string sheetName, IList<ExportableColumn> columns, IEnumerable<T> 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<T>(
string sheetName,
string firstData,
IList<ExportableColumn> columns,
IEnumerable<T> 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<ExportableColumn> columns, IList<dynamic> 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<string, object>)viewModel;
if (propertyDictionary.ContainsKey(propertyName))
{
var value = propertyDictionary[propertyName];
cell.SetCellValue(value == null ? "" : value.ToString());
}
}
rowIndex++;
}
return workbook;
}
public static IWorkbook AddData<T>(IWorkbook workbook, int rowIndex, IList<ExportableColumn> columns, IEnumerable<T> 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<ExportableColumn> 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; }
/// <summary>
/// 单位:像素,为空时使用默认值
/// </summary>
public int? ColumnWidth { get; private set; }
public ExportableColumn Width(int? width)
{
ColumnWidth = width;
return this;
}
}
}