using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.ComponentModel; using Microsoft.AspNetCore.Http; namespace Estsh.Core.Util { /// /// 和 model displayName 一起使用 /// 导入时只需要核对 列头与displayName值是否一致 /// public class ExcelHelper { /// /// 第一步 /// 上传Excel 并返回上传路径 /// /// /// 文件夹名称 /// /// 返回路径 /// private static string DepositExcel(IFormFile file, string directoryName) { //创建需要存放的位置 返回一个准确的路径 var path = CreateDirectory("Upload/Excels/" + directoryName); //文件名 string fileName = DateTime.Now.Ticks.ToString() + "." + file.FileName.Split('.').Last(); path = path + "/" + fileName; if (File.Exists(path)) { File.Delete(path); } using (var stream = new FileStream(path, FileMode.CreateNew)) { file.CopyTo(stream); } return path; } /// /// 第二步 /// 得到Excel 内容 /// /// /// private static ISheet GetSheet(string path) { ISheet sheet; using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) { MemoryStream ms = new MemoryStream(); if (Path.GetExtension(path) == ".xls") { HSSFWorkbook workbook = new HSSFWorkbook(file); //获取一个sheetName sheet = workbook.GetSheetAt(0); } else { XSSFWorkbook workbook = new XSSFWorkbook(file); //获取一个sheetName sheet = workbook.GetSheetAt(0); } } return sheet; } /// /// 第三步 /// 根据Excel 内容得到想要的List /// /// /// /// /// private static List GetList(ISheet sheet, int headNum) { List list = new List(); Dictionary dict = new Dictionary(); //获得列名所对应的字段名 var propertys = GetPropertyByType(false); //得到每个字段对应的序号 IRow head = sheet.GetRow(headNum); for (int i = 0; i < head.LastCellNum; i++) { ICell cell = head.GetCell(i); if (propertys.ContainsKey(cell.StringCellValue.Trim())) { dict.Add(i, propertys[cell.StringCellValue.Trim()]); } } if (dict.Count != head.LastCellNum) { throw new Exception("Import tables head and requirements inconsistency"); } var type = typeof(T).GetProperties(); int c = 0; try { for (int i = headNum + 1; i <= sheet.LastRowNum; i++) { c = i; IRow row = sheet.GetRow(i); if (row != null) { bool isAddList = true; T t = Activator.CreateInstance(); for (int j = 0; j < row.LastCellNum; j++) { ICell cell = row.GetCell(j); string name = ""; dict.TryGetValue(j, out name); if (cell != null) { if (cell.CellType == CellType.Blank)//空值 { isAddList = IsAdd(name, true); } else { var item = type.FirstOrDefault(m => m.Name == name); if (item != null) { if (item.PropertyType == typeof(DateTime)) { try { if (cell.CellType == CellType.String) { var value = Convert.ToDateTime(cell.ToString()); item.SetValue(t, value); } else { item.SetValue(t, cell.DateCellValue); } } catch { throw new Exception($"DateTime{cell.ToString()}格式不正确!"); } } else if (item.PropertyType == typeof(int)) { try { item.SetValue(t, Convert.ToInt32(cell.ToString())); } catch { throw new Exception($"int{cell.ToString()}格式不正确!"); } } else if (item.PropertyType == typeof(string)) { if (cell.CellType == CellType.String) { item.SetValue(t, cell.ToString() == null ? "" : cell.ToString().Trim()); isAddList = IsAdd(name, string.IsNullOrEmpty(cell.ToString())); } else { item.SetValue(t, cell.NumericCellValue.ToString()); } } else if (item.PropertyType == typeof(decimal?) || item.PropertyType == typeof(decimal)) { if (cell != null) { try { var value = 0m; if (cell.CellType == CellType.String) { value = Convert.ToDecimal(cell == null ? "0" : cell.ToString()); } else { value = Convert.ToDecimal(cell.NumericCellValue); } item.SetValue(t, value); isAddList = IsAdd(name, value == 0); } catch { throw new Exception($"decimal{cell.ToString()}格式不正确!"); } } } } } if (isAddList == false) { break; } } } if (isAddList) { list.Add(t); } } } } catch (Exception e) { throw e; } return list; } private static bool IsAdd(string name, bool isOk) { bool result = true; string[] isNotStrs = { }; if (isNotStrs.Contains(name) && isOk) { result = false; } return result; } #region 辅助方法 /// /// 创建目录 /// /// 目录路径 private static string CreateDirectory(string directoryPath = "") { var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content"); if (!string.IsNullOrEmpty(directoryPath)) { if (directoryPath.Substring(0, 1) != "/") { directoryPath = "/" + directoryPath; } path += directoryPath; } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return path; } /// /// 获得Excel列名 /// private static Dictionary GetPropertyByType(bool isToExcel) { Dictionary dict = new Dictionary(); var type = typeof(In); try { foreach (var item in type.GetProperties()) { var displayName = item.GetCustomAttribute(); if (displayName != null) { if (isToExcel) { dict.Add(item.Name, displayName.DisplayName); } else { dict.Add(displayName.DisplayName, item.Name); } } } } catch (Exception e) { throw e; } return dict; } #endregion /// /// 功能, /// 导入Excel /// 列头名和实体的DispName 要一致。 /// /// 要转换的实体 /// 上传的Excel文件 /// Excel头部行数 /// /// 获得转换后的List 集合 /// public static List GetList(IFormFile files, int headNum) { List list = new List(); string path = DepositExcel(files, typeof(T).Name); //得到上传文件内容 ISheet sheet = GetSheet(path); //转换成List var t = GetList(sheet, headNum); if (t != null && t.Count > 0) { list.AddRange(t); } return list; } /// /// 生成Excel流数据, /// return File(memoryStream.ToArray(), "application/vnd.ms-excel", fileName); //vnd.ms 此模式有些不兼容 /// 或者 /// return File(memoryStream.ToArray(), "application/ms-excel", "红包列表.xls") /// /// 数据模型 /// excel扩展名类型 /// 数据集 /// Excel的单个Sheet的行数,不能超过65535,否则会抛出异常 /// public static MemoryStream ToExcel(List data, string excelType = "xls", int sheetSize = 50000) { IWorkbook wk; if (excelType == "xlsx") { wk = new XSSFWorkbook(); } else { wk = new HSSFWorkbook(); } var itemType = Activator.CreateInstance().GetType(); int baseNum = 65535;//单个Sheet最大行数65535 int cNum = data.Count / baseNum; int myForCount = data.Count % baseNum == 0 ? cNum : cNum + 1; for (int i = 0; i < myForCount; i++) { var list = data.Skip(i * baseNum).Take(baseNum).ToList(); string sheetName = "sheet" + i + 1; CreateSheet(wk, list, itemType, sheetName); } if (myForCount == 0) { var list = data.Skip(1 * baseNum).Take(baseNum).ToList(); string sheetName = "sheet" + 1; var headers = GetPropertyByType(true); ISheet sheet = CreateHeaders(wk, headers, sheetName); } MemoryStream m = new MemoryStream(); wk.Write(m); return m; } /// /// 创建并得到一个 sheet /// /// /// /// /// /// /// /// /// private static void CreateSheet(IWorkbook wk, List data, Type itemType, string sheetName, int sheetSize = 50000) { try { ISheet sheet = null; var headers = GetPropertyByType(true); sheet = CreateHeaders(wk, headers, sheetName); if (data.Count > 0) { for (var i = 0; i < data.Count; i++) { //创建内容 IRow row = sheet.CreateRow(i % sheetSize + 1); //遍历填充每条数据 int j = 0; foreach (var item in headers) { var p = itemType.GetProperty(item.Key);//获取对应列名 if (p != null) { var value = p.GetValue(data[i]); value = value == null ? string.Empty : value; ICell cell = row.CreateCell(j); cell.SetCellValue(value.ToString().Trim()); } j++; } } } } catch (Exception ex) { throw ex; } } /// /// 创建sheet 表头 /// /// workbook /// 表头 /// /// /// 返回一个sheet /// private static ISheet CreateHeaders(IWorkbook wk, Dictionary headers, string sheetName) { var sheet = wk.CreateSheet(sheetName); IRow rowHead = sheet.CreateRow(0); ICellStyle style = wk.CreateCellStyle(); IFont font = wk.CreateFont();//创建字体样式 font.Boldweight = (short)FontBoldWeight.Bold; style.SetFont(font); int i = 0; foreach (var item in headers) { ICell cellHead = rowHead.CreateCell(i); cellHead.SetCellValue(item.Value); cellHead.CellStyle = style; i++; } return sheet; } } }