using Microsoft.VisualBasic; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using OfficeOpenXml; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace DG.Tool { public static class ExcelHelper { public static void Export(string fullName, List data) { ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; var ttype = typeof(T); var typeName = ttype.Name; var typeDescriptionAttr = ttype.GetCustomAttribute(); if (typeDescriptionAttr != null) { typeName = typeDescriptionAttr.Description; } var tps = ttype.GetProperties().ToList(); for (var i = tps.Count - 1; i >= 0; i--) { var attr = tps[i].GetCustomAttribute(); if (attr != null) { tps.RemoveAt(i); } } using (var package = new ExcelPackage(new FileInfo(fullName))) { var worksheet = package.Workbook.Worksheets.Add(typeName); for (var i = 0; i < tps.Count; i++) { var tp = tps[i]; var tpName = tp.Name; var tpDescriptionAttr = tp.GetCustomAttribute(); if (tpDescriptionAttr != null) { tpName = tpDescriptionAttr.Description; } worksheet.Cells[1, i + 1].Value = tpName; } for (var j = 0; j < data.Count; j++) { for (var k = 0; k < tps.Count; k++) { var val_display = ""; var val = tps[k].GetValue(data[j], null); if (val != null) { val_display = Convert.ToString(val); } worksheet.Cells[j + 2, k + 1].Value = val_display; } } package.Save(); } } /// /// excel导入 /// /// /// /// 数据从第几行开始 /// 只导入第一个Sheet的数据 /// public static List Import(byte[] bytes, int dataRow = 2, bool onlyFirstSheet = true) where T : class, new() { var ttype = typeof(T); var tps = ttype.GetProperties(); var items = new List(); using (var ms = new MemoryStream(bytes)) { ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; using (var package = new ExcelPackage(ms)) { var sheets = package.Workbook.Worksheets.ToList(); if (onlyFirstSheet) { sheets = new List { package.Workbook.Worksheets[0] }; } foreach (var sheet in sheets) { for (var i = dataRow; i <= sheet.Dimension.Rows; i++) { var one = Activator.CreateInstance(); for (var j = 0; j < tps.Length; j++) { var cell = sheet.Cells[i, j + 1]; if (cell == null) { continue; } var tp = tps[j]; var val = GetValue2(tp, cell.GetValue()); tp.SetValue(one, val, null); } items.Add(one); } } } } return items; } public static async Task ExportAsync(string fullName, List data) { ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; var ttype = typeof(T); var typeName = ttype.Name; var typeDescriptionAttr = ttype.GetCustomAttribute(); if (typeDescriptionAttr != null) { typeName = typeDescriptionAttr.Description; } var tps = ttype.GetProperties().ToList(); for (var i = tps.Count - 1; i >= 0; i--) { var attr = tps[i].GetCustomAttribute(); if (attr != null) { tps.RemoveAt(i); } } using (var package = new ExcelPackage(new FileInfo(fullName))) { var worksheet = package.Workbook.Worksheets.Add(typeName); for (var i = 0; i < tps.Count; i++) { var tp = tps[i]; var tpName = tp.Name; var tpDescriptionAttr = tp.GetCustomAttribute(); if (tpDescriptionAttr != null) { tpName = tpDescriptionAttr.Description; } worksheet.Cells[1, i + 1].Value = tpName; } for (var j = 0; j < data.Count; j++) { for (var k = 0; k < tps.Count; k++) { var val_display = ""; var val = tps[k].GetValue(data[j], null); if (val != null) { val_display = Convert.ToString(val); } worksheet.Cells[j + 2, k + 1].Value = val_display; } } await package.SaveAsync(); } } private static object GetValue2(PropertyInfo tp, string val) { if (tp.PropertyType == typeof(int) || tp.PropertyType == typeof(int?)) { if (int.TryParse(val, out int temp)) { return temp; } return default(int?); } if (tp.PropertyType == typeof(long) || tp.PropertyType == typeof(long?)) { if (long.TryParse(val, out long temp)) { return temp; } return default(long?); } if (tp.PropertyType == typeof(decimal) || tp.PropertyType == typeof(decimal?)) { if (decimal.TryParse(val, out decimal temp)) { return temp; } return default(decimal?); } if (tp.PropertyType == typeof(DateTime) || tp.PropertyType == typeof(DateTime?)) { if (DateTime.TryParse(val, out DateTime temp)) { return temp; } return default(DateTime?); } if (tp.PropertyType == typeof(bool) || tp.PropertyType == typeof(bool?)) { if (bool.TryParse(val, out bool temp)) { return temp; } return default(bool?); } return val; } /// /// 生成Excel文件(多行头部) /// /// 数据源 /// 文件名 /// public static void GridToExcelByNPOIMultiHeader(DataTable dt, string strExcelFileName, List> extHeaders) { HSSFWorkbook workbook = new HSSFWorkbook(); try { int sheetIndex = 0; int dataIndex = 0; ICellStyle HeadercellStyle = workbook.CreateCellStyle(); HeadercellStyle.BorderBottom = BorderStyle.Thin; HeadercellStyle.BorderLeft = BorderStyle.Thin; HeadercellStyle.BorderRight = BorderStyle.Thin; HeadercellStyle.BorderTop = BorderStyle.Thin; HeadercellStyle.Alignment = HorizontalAlignment.Center; ICellStyle cellStyle = workbook.CreateCellStyle(); //为避免日期格式被Excel自动替换,所以设定 format 为 『@』 表示一率当成text來看 cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("@"); cellStyle.BorderBottom = BorderStyle.Thin; cellStyle.BorderLeft = BorderStyle.Thin; cellStyle.BorderRight = BorderStyle.Thin; cellStyle.BorderTop = BorderStyle.Thin; //字体 IFont headerfont = workbook.CreateFont(); headerfont.Boldweight = (short)FontBoldWeight.Bold; HeadercellStyle.SetFont(headerfont); IFont cellfont = workbook.CreateFont(); cellfont.Boldweight = (short)FontBoldWeight.Normal; cellStyle.SetFont(cellfont); var index = extHeaders.Count; while (dataIndex < dt.Rows.Count) { sheetIndex++; ISheet sheet = workbook.CreateSheet($"Sheet{sheetIndex}"); if (index > 0) { for (var i = 0; i < index; i++) { IRow extHeaderRow = sheet.CreateRow(i); if (extHeaders[i].Count == 0) { ICell extCell = extHeaderRow.CreateCell(0); extCell.SetCellValue(""); extCell.CellStyle = HeadercellStyle; } else { for (var j = 0; j < extHeaders[i].Count; j++) { ICell cell = extHeaderRow.CreateCell(j); cell.SetCellValue(extHeaders[i][j]); cell.CellStyle = HeadercellStyle; } } } } //用column name 作为列名 int icolIndex = 0; IRow headerRow = sheet.CreateRow(index); foreach (DataColumn item in dt.Columns) { ICell cell = headerRow.CreateCell(icolIndex); cell.SetCellValue(item.ColumnName); cell.CellStyle = HeadercellStyle; icolIndex++; } //建立内容行 int iRowIndex = 1; int iCellIndex = 0; for (int count = 0; dataIndex < dt.Rows.Count; dataIndex++, count++) { if (count >= 65000) break; DataRow Rowitem = dt.Rows[dataIndex]; IRow DataRow = sheet.CreateRow(index + iRowIndex); foreach (DataColumn Colitem in dt.Columns) { ICell cell = DataRow.CreateCell(iCellIndex); cell.SetCellValue(Rowitem[Colitem].ToString()); cell.CellStyle = cellStyle; iCellIndex++; } iCellIndex = 0; iRowIndex++; } //自适应列宽度 for (int i = 0; i < icolIndex; i++) { sheet.AutoSizeColumn(i); } } if (System.IO.File.Exists(strExcelFileName)) System.IO.File.Delete(strExcelFileName); //写Excel FileStream file = new FileStream(strExcelFileName, FileMode.Create); workbook.Write(file); file.Flush(); file.Close(); } catch (Exception ex) { throw; } finally { workbook = null; } } /// /// 生成Excel文件 /// /// 数据源 /// 文件名 /// 如果是web下载,strExcelFileName则仅仅是文件名而非路径名 public static void GridToExcelByNPOI(DataTable dt, string strExcelFileName) { HSSFWorkbook workbook = new HSSFWorkbook(); try { int sheetIndex = 0; int dataIndex = 0; ICellStyle HeadercellStyle = workbook.CreateCellStyle(); HeadercellStyle.BorderBottom = BorderStyle.Thin; HeadercellStyle.BorderLeft = BorderStyle.Thin; HeadercellStyle.BorderRight = BorderStyle.Thin; HeadercellStyle.BorderTop = BorderStyle.Thin; HeadercellStyle.Alignment = HorizontalAlignment.Center; ICellStyle cellStyle = workbook.CreateCellStyle(); //为避免日期格式被Excel自动替换,所以设定 format 为 『@』 表示一率当成text來看 cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("@"); cellStyle.BorderBottom = BorderStyle.Thin; cellStyle.BorderLeft = BorderStyle.Thin; cellStyle.BorderRight = BorderStyle.Thin; cellStyle.BorderTop = BorderStyle.Thin; //字体 IFont headerfont = workbook.CreateFont(); headerfont.Boldweight = (short)FontBoldWeight.Bold; HeadercellStyle.SetFont(headerfont); IFont cellfont = workbook.CreateFont(); cellfont.Boldweight = (short)FontBoldWeight.Normal; cellStyle.SetFont(cellfont); while (dataIndex < dt.Rows.Count) { sheetIndex++; ISheet sheet = workbook.CreateSheet($"Sheet{sheetIndex}"); //用column name 作为列名 int icolIndex = 0; IRow headerRow = sheet.CreateRow(0); foreach (DataColumn item in dt.Columns) { ICell cell = headerRow.CreateCell(icolIndex); cell.SetCellValue(item.ColumnName); cell.CellStyle = HeadercellStyle; icolIndex++; } //建立内容行 int iRowIndex = 1; int iCellIndex = 0; for (int count = 0; dataIndex < dt.Rows.Count; dataIndex++, count++) { if (count >= 65000) break; DataRow Rowitem = dt.Rows[dataIndex]; IRow DataRow = sheet.CreateRow(iRowIndex); foreach (DataColumn Colitem in dt.Columns) { ICell cell = DataRow.CreateCell(iCellIndex); cell.SetCellValue(Rowitem[Colitem].ToString()); cell.CellStyle = cellStyle; iCellIndex++; } iCellIndex = 0; iRowIndex++; } //自适应列宽度 for (int i = 0; i < icolIndex; i++) { sheet.AutoSizeColumn(i); } } //如果没有传路径,就生成用于web下载的流 //if (isWebDownload) //{ // using (MemoryStream ms = new MemoryStream()) // { // workbook.Write(ms); // ms.Flush(); // ms.Position = 0; // byte[] bytes = ms.GetBuffer(); // HttpContext.GetUserIp(); // string UserAgent = WebRequest.DefaultWebProxy. // .g // Request.UserAgent // string UserAgent = HttpContext.Current.Request.ServerVariables["http_user_agent"].ToLower(); // string filename = strExcelFileName + ".xls"; // if (UserAgent.IndexOf("firefox") <= 0)//火狐,文件名不需要编码 // { // filename = HttpUtility.UrlEncode(filename, Encoding.UTF8); // } // HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"; // HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + filename); // HttpContext.Current.Response.BinaryWrite(bytes); // HttpContext.Current.Response.End(); // } //} //else { if (System.IO.File.Exists(strExcelFileName)) System.IO.File.Delete(strExcelFileName); //写Excel FileStream file = new FileStream(strExcelFileName, FileMode.Create); workbook.Write(file); file.Flush(); file.Close(); } } catch (Exception ex) { throw; } finally { workbook = null; } } /// /// 将DataTable数据导入到excel中 /// /// 要导入的数据 /// DataTable的列名是否要导入 /// 导出文件名全路径 /// 要导入的excel的sheet的名称 /// 导入数据行数(包含列名那一行) public static int DataTableToExcel(DataTable data, string fileName, bool isColumnWritten, string sheetName = "Sheet1") { int i = 0; int j = 0; int count = 0; ISheet sheet = null; IWorkbook workbook = null; string myDir = Path.GetDirectoryName(fileName); //判断文件夹是否存在 if (!Directory.Exists(myDir)) { //文件夹不存在则创建该文件夹 if (myDir != null) Directory.CreateDirectory(myDir); } using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) { if (fileName.IndexOf(".xlsx", StringComparison.Ordinal) > 0) // 2007版本 workbook = new XSSFWorkbook(); else if (fileName.IndexOf(".xls", StringComparison.Ordinal) > 0) // 2003版本 workbook = new HSSFWorkbook(); try { if (workbook != null) { sheet = workbook.CreateSheet(sheetName); } else { return -1; } if (isColumnWritten == true) //写入DataTable的列名 { IRow row = sheet.CreateRow(0); for (j = 0; j < data.Columns.Count; ++j) { row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName); } count = 1; } else { count = 0; } for (i = 0; i < data.Rows.Count; ++i) { IRow row = sheet.CreateRow(count); for (j = 0; j < data.Columns.Count; ++j) { row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString()); } ++count; } workbook.Write(fs); //写入到excel workbook.Close(); return count; } catch (Exception ex) { workbook?.Close(); throw new Exception(ex.Message); } } } public static DataTable ExcelToDataTable(string fileName, string sheetName, bool isFirstRowColumn, Dictionary columnTemplate = null, string[] requireColumns = null, int? maxRows = null) { ISheet sheet = null; DataTable data = new DataTable(); IWorkbook workbook = null; int startRow = 0; try { using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { try { workbook = new XSSFWorkbook(fs); } catch { workbook = new HSSFWorkbook(fs); } } if (sheetName != null) { if (workbook != null) { sheet = workbook.GetSheet(sheetName); if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet { sheet = workbook.GetSheetAt(0); } } } else { if (workbook != null) sheet = workbook.GetSheetAt(0); } if (sheet != null) { IRow firstRow = sheet.GetRow(0); int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数 if (isFirstRowColumn) { for (int i = firstRow.FirstCellNum; i < cellCount; ++i) { ICell cell = firstRow.GetCell(i); string cellValue = cell?.StringCellValue?.Trim(); if (!string.IsNullOrWhiteSpace(cellValue))//列名正确性验证 { if (columnTemplate != null && !columnTemplate.First().Value.Contains(cellValue)) throw new Exception($"{columnTemplate.First().Key}不存在列名:{cellValue}!正确列名为:{string.Join(",", columnTemplate.First().Value)}"); DataColumn column = new DataColumn(cellValue); data.Columns.Add(column); } } startRow = sheet.FirstRowNum + 1; } else { startRow = sheet.FirstRowNum; } //最后一列的标号 int rowCount = sheet.LastRowNum; if (maxRows != null) { if (rowCount > maxRows) throw new Exception($"请拆分文件,一次最多支持{maxRows}条数据"); } for (int i = startRow; i <= rowCount; ++i) { IRow row = sheet.GetRow(i); if (row == null || row.Cells.Count == 0 || row.FirstCellNum == -1 || row.Cells.All(d => d.CellType == CellType.Blank)) continue; //没有数据的行默认是null        DataRow dataRow = data.NewRow(); for (int j = row.FirstCellNum; j < cellCount; ++j) { var cellvalue = row.GetCell(j); if (cellvalue == null || (cellvalue.ToString().Trim() == "0")) { if (requireColumns != null && requireColumns.Contains(data.Columns[j].ColumnName)) { //throw new Exception($"第{i}行,第{j}列,【{data.Columns[j].ColumnName}】不能为空或0,必须填写!"); } } if (cellvalue != null) dataRow[j] = cellvalue.ToString().Trim(); else { dataRow[j] = ""; //string.Empty; } } data.Rows.Add(dataRow); } } workbook?.Close(); return data; } catch (Exception ex) { workbook?.Close(); throw new Exception(ex.Message); } } /// /// 将excel中的数据导入到DataTable中 /// /// excel工作薄sheet的名称 /// 第一行是否是DataTable的列名 /// 第一行是否是DataTable的列名 /// 开始行数 /// 开始收集数据行数 /// 返回的DataTable public static DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn, string fileName, int startRow = 0, int startData = 1) { ISheet sheet = null; DataTable data = new DataTable(); try { IWorkbook workbook = null; FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); if (fileName.IndexOf(".xlsx") > 0 || fileName.IndexOf(".xlsm") > 0) // 2007版本 workbook = new XSSFWorkbook(fs); else if (fileName.IndexOf(".xls") > 0) // 2003版本 workbook = new HSSFWorkbook(fs); if (sheetName != null) { sheet = workbook.GetSheet(sheetName); if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet { sheet = workbook.GetSheetAt(0); } } else { sheet = workbook.GetSheetAt(0); } if (sheet != null) { IRow firstRow = sheet.GetRow(startRow); int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数 if (isFirstRowColumn) { for (int i = firstRow.FirstCellNum; i < cellCount; ++i) { ICell cell = firstRow.GetCell(i); if (cell != null) { string cellValue = cell.StringCellValue.Replace(" ", "").Replace("?", ""); if (cellValue != null) { if (data.Columns[cellValue] != null) { cellValue += i; } DataColumn column = new DataColumn(cellValue); data.Columns.Add(column); } } } startRow += sheet.FirstRowNum + startData; } else { startRow = sheet.FirstRowNum; } //最后一列的标号 int rowCount = sheet.LastRowNum; for (int i = startRow; i <= rowCount; ++i) { IRow row = sheet.GetRow(i); if (row == null) continue; //没有数据的行默认是null        DataRow dataRow = data.NewRow(); for (int j = row.FirstCellNum; j < cellCount; ++j) { if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null dataRow[j] = row.GetCell(j).ToString(); } data.Rows.Add(dataRow); } } return data; } catch (Exception ex) { Console.WriteLine("Exception: " + ex.Message); return null; } } /// /// DataTable转成List /// /// /// /// public static List ToDataList(this DataTable dt) { var list = new List(); var plist = new List(typeof(T).GetProperties()); foreach (DataRow item in dt.Rows) { T s = Activator.CreateInstance(); for (int i = 0; i < dt.Columns.Count; i++) { PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); if (info != null) { try { if (!Convert.IsDBNull(item[i])) { object v = null; if (info.PropertyType.ToString().Contains("System.Nullable")) { v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType)); } else { v = Convert.ChangeType(item[i], info.PropertyType); } info.SetValue(s, v, null); } } catch (Exception ex) { throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message); } } } list.Add(s); } return list; } /// /// DataTable转成Dto /// /// /// /// public static T ToDataDto(this DataTable dt) { T s = Activator.CreateInstance(); if (dt == null || dt.Rows.Count == 0) { return s; } var plist = new List(typeof(T).GetProperties()); for (int i = 0; i < dt.Columns.Count; i++) { PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); if (info != null) { try { if (!Convert.IsDBNull(dt.Rows[0][i])) { object v = null; if (info.PropertyType.ToString().Contains("System.Nullable")) { v = Convert.ChangeType(dt.Rows[0][i], Nullable.GetUnderlyingType(info.PropertyType)); } else { v = Convert.ChangeType(dt.Rows[0][i], info.PropertyType); } info.SetValue(s, v, null); } } catch (Exception ex) { throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message); } } } return s; } /// /// list转化为table /// /// /// /// public static DataTable ListToDataTable(List entitys) { //检查实体集合不能为空 if (entitys == null || entitys.Count < 1) { return new DataTable(); } //取出第一个实体的所有Propertie Type entityType = entitys[0].GetType(); PropertyInfo[] entityProperties = entityType.GetProperties(); //生成DataTable的structure //生产代码中,应将生成的DataTable结构Cache起来,此处略 DataTable dt = new DataTable("dt"); for (int i = 0; i < entityProperties.Length; i++) { //dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType); dt.Columns.Add(entityProperties[i].Name); } //将所有entity添加到DataTable中 foreach (object entity in entitys) { //检查所有的的实体都为同一类型 if (entity.GetType() != entityType) { throw new Exception("要转换的集合元素类型不一致"); } DataRow dr = dt.NewRow(); dt.Rows.Add(dr); int rowCount = dt.Rows.Count; object[] entityValues = new object[entityProperties.Length]; for (int i = 0; i < entityProperties.Length; i++) { entityValues[i] = entityProperties[i].GetValue(entity, null); //给当前行的每列加数据 dt.Rows[rowCount][i] = entityValues[i]; } } return dt; } } }