大部分功能逻辑都在,少量自定义异常类和扩展方法 ,可用类似代码自己替换
//EpPlus读取生成Excel帮助类+读取csv帮助类,epplus只支持开放的Excel文件格式:xlsx,不支持 xls格式
/* ============================================================================== * 功能描述:EppHelper * 创 建 者:蒲奎民 * 创建日期:2016-07-21 14:30:35 * CLR Version :4.0.30319.42000 * ==============================================================================*/ using OfficeOpenXml; using OfficeOpenXml.Style; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using YCF.HRMS.Utilities.ExceptionHeper; using YCF.HRMS.Utilities.ExtensionHelper; /* * 引用文件: * packages\EPPlus.4.1.0\lib\net40\EPPlus.dll * packages\EPPlus.Extensions.1.0.0.0\lib\net40\EPPlus.Extensions.dll */ namespace YCF.HRMS.Utilities.CommomHelper { /// <summary> /// EpPlus读取Excel帮助类+读取csv帮助类 /// </summary> public class EppHelper { #region 由List创建简单Exel.列头取字段的Description或字段名 /// <summary> /// 由List创建简单Exel.列头取字段的Description或字段名 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="filePath">The file path.</param> /// <param name="dataList">The data list.</param> public static void CreateExcelByList<T>(string filePath, List<T> dataList) where T : class { string dirPath = Path.GetDirectoryName(filePath); string fileName = Path.GetFileName(filePath); FileInfo newFile = new FileInfo(filePath); if (newFile.Exists) { newFile.Delete(); // ensures we create a new workbook newFile = new FileInfo(filePath); } PropertyInfo[] properties = null; if (dataList.Count > 0) { Type type = dataList[0].GetType(); properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); var filedDescriptions = CommonFunctions.GetPropertyDescriptions<T>(true);//字段与excel列名对应关系 using (ExcelPackage package = new ExcelPackage(newFile)) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("sheet1"); //设置表头单元格格式 using (var range = worksheet.Cells[1, 1, 1, properties.Length]) { range.Style.Font.Bold = true; range.Style.Fill.PatternType = ExcelFillStyle.Solid; range.Style.Fill.BackgroundColor.SetColor(Color.DarkBlue); range.Style.Font.Color.SetColor(Color.White); } int row = 1, col; object objColValue; string colValue; //表头 for (int j = 0; j < properties.Length; j++) { row = 1; col = j + 1; var description = filedDescriptions.Where(o => o.Key == properties[j].Name).Select(o => o.Value).FirstOrDefault(); worksheet.Cells[row, col].Value = (description == null || description.Description.IsNullOrEmpty()) ? properties[j].Name : description.Description; } worksheet.View.FreezePanes(row + 1, 1); //冻结表头 //各行数据 for (int i = 0; i < dataList.Count; i++) { row = i + 2; for (int j = 0; j < properties.Length; j++) { col = j + 1; objColValue = properties[j].GetValue(dataList[i], null); colValue = objColValue == null ? "" : objColValue.ToString(); worksheet.Cells[row, col].Value = colValue; } } package.Save(); } } } #endregion #region 读取Excel数据到DataSet /// <summary> /// 读取Excel数据到DataSet /// </summary> /// <param name="filePath">The file path.</param> /// <returns></returns> public static DataSet ReadExcelToDataSet(string filePath) { DataSet ds = new DataSet("ds"); DataRow dr; object objCellValue; string cellValue; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite)) using (ExcelPackage package = new ExcelPackage()) { package.Load(fs); foreach (var sheet in package.Workbook.Worksheets) { if (sheet.Dimension == null) continue; var columnCount = sheet.Dimension.End.Column; var rowCount = sheet.Dimension.End.Row; if (rowCount > 0) { DataTable dt = new DataTable(sheet.Name); for (int j = 0; j < columnCount; j++)//设置DataTable列名 { objCellValue = sheet.Cells[1, j + 1].Value; cellValue = objCellValue == null ? "" : objCellValue.ToString(); dt.Columns.Add(cellValue, typeof(string)); } for (int i = 2; i <= rowCount; i++) { dr = dt.NewRow(); for (int j = 1; j <= columnCount; j++) { objCellValue = sheet.Cells[i, j].Value; cellValue = objCellValue == null ? "" : objCellValue.ToString(); dr[j - 1] = cellValue; } dt.Rows.Add(dr); } ds.Tables.Add(dt); } } } return ds; } #endregion #region 读取csv数据到List<T>,列头与字段的Description对应 /// <summary> /// 读取csv数据到List<T>,列头与字段的Description对应 /// </summary> /// <typeparam name="T">输出类型</typeparam> /// <param name="filePath">文件路径</param> /// <returns></returns> public static List<T> ReadCsvToModelList<T>(string filePath, string uploadMonth, long userId) where T : class { List<T> list = new List<T>(); object objCellValue; string cellValue; string columnName; var filedDescriptions = CommonFunctions.GetPropertyDescriptions<T>(false);//字段与excel列名对应关系 var fieldIndexs = new List<KeyValuePair<int, FieldDescriptionModel>>();//Excel列索引与字段名对应关系 int lineCount = 1; string mes = ""; Type type = typeof(T); int iUserId = int.Parse(userId.ToString()); var properties = type.GetProperties(); using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (StreamReader sr = new StreamReader(fs, Encoding.Default)) { string line; var columnCount = 0; bool isEmptyCellValue = false;//是否有必须填写但实际没填写的数据 while (true) { isEmptyCellValue = false; line = sr.ReadLine(); if (string.IsNullOrWhiteSpace(line)) { break; } string[] split = SplitCsvLine(line); if (lineCount == 1)//列头 { columnCount = split.Length; for (int j = 0; j < columnCount; j++)//设置DataTable列名 { objCellValue = split[j]; cellValue = objCellValue == null ? "" : objCellValue.ToString(); var cellFieldName = filedDescriptions.Where(o => o.Key == cellValue).Select(o => o.Value).FirstOrDefault(); fieldIndexs.Add(new KeyValuePair<int, FieldDescriptionModel>(j, cellFieldName)); } lineCount++; continue; } //当第一列为空时退出csv读取 if (string.IsNullOrWhiteSpace(split[0])) { break; } if (split.Length > columnCount) { mes += lineCount.ToString() + ","; //string.Format("第{0}行读取有误,数据列数{1}大于标题列数{2},请检查该行单元格内是否有逗号<\br>", lineCount, split.Length, dataTypes.Length); lineCount++; continue; } if (split.Length < columnCount) { mes += lineCount.ToString() + ",";//string.Format("第{0}行数据读取有误,数据列数{1}小于标题列数{2},请检查该行单元格内是否有逗号<\br>", lineCount, split.Length, dataTypes.Length); lineCount++; continue; } T model = Activator.CreateInstance<T>(); for (int j = 0; j < columnCount; j++) { objCellValue = split[j]; var field = fieldIndexs.First(o => o.Key == j).Value; columnName = field.FieldName; if (columnName.IsNullOrEmpty()) continue; PropertyInfo p = properties.FirstOrDefault(o => string.Equals(o.Name, columnName, StringComparison.InvariantCultureIgnoreCase)); if (p == null) continue; SetPropertyValue<T>(ref model, ref p, ref objCellValue, ref field, ref isEmptyCellValue); } if (isEmptyCellValue) { continue; } SetPropertyValueForKnowColumns<T>(ref model, ref properties, ref uploadMonth, ref userId, ref iUserId); list.Add(model); lineCount++; } } if (mes != "") throw new BusinessException("第" + mes.TrimEnd(',') + "行读取有误,请检查该行单元格内是否有逗号"); #region 判断第一行数据是否合格,Excel列名和字段对不上的情况,检查一个就等于检查全部 var firstModel = list.FirstOrDefault(); CheckModelRequiredData<T>(ref firstModel, ref properties, ref filedDescriptions); #endregion return list; } #endregion #region 设置字段属性的值 /// <summary> /// 设置字段属性的值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model">The model.</param> /// <param name="p">The p.</param> /// <param name="objCellValue">The object cell value.</param> /// <param name="field">The field.</param> /// <param name="isEmptyCellValue">if set to <c>true</c> [is empty cell value].</param> /// <exception cref="BusinessException">出错,字段名: + p.Name + ,类型: + p.PropertyType.ToString() + ,数据: + (objCellValue == null ? : objCellValue.ToString()) + ,错误信息: + ex.Message</exception> private static void SetPropertyValue<T>(ref T model, ref PropertyInfo p, ref object objCellValue, ref FieldDescriptionModel field, ref bool isEmptyCellValue) where T : class { var propertyType = p.PropertyType.ToString(); switch (propertyType) { case "System.String": { if (objCellValue is string == false) { if (objCellValue == null) objCellValue = ""; else objCellValue = objCellValue.ToString(); if (field.IsRequire && objCellValue.ToString() == "") { isEmptyCellValue = true; break; } } if (objCellValue != null) objCellValue = objCellValue.ToString().Replace("\r\n", "").Trim(); } break; case "System.Decimal": case "System.Nullable`1[System.Decimal]": { if (objCellValue is decimal == false) { if (objCellValue != null) { if (objCellValue.ToString().EndsWith("%")) { objCellValue = Convert.ToDecimal(objCellValue.ToString().TrimEnd('%')) / 100M; } else objCellValue = Convert.ToDecimal(objCellValue.ToString()); } } } break; case "System.Int32": case "System.Nullable`1[System.Int32]": { if (objCellValue is int == false) { if (objCellValue != null) objCellValue = Convert.ToInt32(objCellValue); } } break; case "System.Int64": case "System.Nullable`1[System.Int64]": { if (objCellValue is long == false) { if (objCellValue != null) objCellValue = Convert.ToInt64(objCellValue); } } break; case "System.DateTime": case "System.Nullable`1[System.DateTime]": { if (objCellValue is DateTime == false) { if (objCellValue != null) objCellValue = ToDateTimeValue(objCellValue.ToString()); } } break; case "System.Boolean": case "System.Nullable`1[System.Boolean]": { if (objCellValue is bool == false) { if (objCellValue != null) { var tempValue = objCellValue.ToString().Trim(); if (tempValue == "#N/A") tempValue = ""; else if (tempValue == "是") tempValue = "True"; else if (tempValue == "否") tempValue = "False"; if (tempValue != "") objCellValue = Convert.ToBoolean(tempValue); else objCellValue = null; } } } break; } try { p.SetValue(model, objCellValue, null); } catch (Exception ex) { throw new BusinessException("出错,字段名:" + p.Name + ",类型:" + p.PropertyType.ToString() + ",数据:" + (objCellValue == null ? "" : objCellValue.ToString()) + ",错误信息:" + ex.Message); } } #endregion #region 其他已知属性赋默认值 /// <summary> /// 其他已知属性赋默认值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model">The model.</param> /// <param name="properties">The properties.</param> /// <param name="uploadMonth">The upload month.</param> /// <param name="userId">The user identifier.</param> /// <param name="iUserId">The i user identifier.</param> private static void SetPropertyValueForKnowColumns<T>(ref T model, ref PropertyInfo[] properties, ref string uploadMonth, ref long userId, ref int iUserId) { var monthProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "Month", StringComparison.InvariantCultureIgnoreCase)); if (monthProperty != null) { monthProperty.SetValue(model, uploadMonth, null); } var createTimeProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "CreationTime", StringComparison.InvariantCultureIgnoreCase)); if (createTimeProperty != null) { createTimeProperty.SetValue(model, DateTime.Now, null); } var modifyTimeProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "LastModificationTime", StringComparison.InvariantCultureIgnoreCase)); if (modifyTimeProperty != null) { modifyTimeProperty.SetValue(model, DateTime.Now, null); } var createUserIdProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "CreatorUserId", StringComparison.InvariantCultureIgnoreCase)); if (createUserIdProperty != null) { if (createTimeProperty.PropertyType.ToString() == "System.Int32") createUserIdProperty.SetValue(model, iUserId, null); else createUserIdProperty.SetValue(model, userId, null); } } #endregion #region 最后判断第一行数据是否合格,Excel列名和字段对不上的情况,检查一个就等于检查全部 /// <summary> /// 最后判断第一行数据是否合格,Excel列名和字段对不上的情况,检查一个就等于检查全部 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model">The model.</param> /// <param name="filedDescriptions">The filed descriptions.</param> private static void CheckModelRequiredData<T>(ref T firstModel, ref PropertyInfo[] properties, ref List<KeyValuePair<string, FieldDescriptionModel>> filedDescriptions) { if (firstModel != null) { var fieldNameList = filedDescriptions.Where(o => o.Value != null).Select(o => o.Value).ToList(); foreach (var p in properties) { var fieldNameModel = fieldNameList.FirstOrDefault(o => string.Equals(o.FieldName, p.Name, StringComparison.InvariantCultureIgnoreCase)); if (fieldNameModel == null || fieldNameModel.IsRequire == false) continue;//为空或没有Require标记,跳过 object objCellValue = p.GetValue(firstModel); if (objCellValue == null || objCellValue.ToString() == "") { throw new BusinessException("出错,字段名:" + p.Name + ",类型:" + p.PropertyType.ToString() + " 必填字段数据为空!"); } } } } #endregion #region 读取Excel数据到List<T>,列头与字段的Description对应 /// <summary> /// 读取Excel数据到List<T>,列头与字段的Description对应 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="filePath">The file path.</param> /// <returns></returns> public static List<T> ReadExcelToModelList<T>(string filePath, string uploadMonth, long userId, out string log, int titleRow = 1) where T : class { ExcelPackage package = null; FileStream fs = null; try { //ConcurrentBag<T> list = new ConcurrentBag<T>(); List<T> list = new List<T>(); log = string.Format("{0:yyyy-MM-dd HH:mm:ss}开始载入文件{1}\r\n", DateTime.Now, filePath); var filedDescriptions = CommonFunctions.GetPropertyDescriptions<T>(false);//字段与excel列名对应关系 var fieldIndexs = new List<KeyValuePair<int, FieldDescriptionModel>>();//Excel列索引与字段名对应关系 fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); package = new ExcelPackage(); package.Load(fs); log += string.Format("{0:yyyy-MM-dd HH:mm:ss}完成载入文件{1},开始解析\r\n", DateTime.Now, filePath); if (package.Workbook.Worksheets.Count == 0) { throw new BusinessException("读取的Excel中sheet数量为0,请检查文件格式是否为xlsx!"); } var sheet = package.Workbook.Worksheets[1]; if (sheet.Dimension == null) return list.ToList(); var columnCount = sheet.Dimension.End.Column; var rowCount = sheet.Dimension.End.Row; if (rowCount == 0) return list.ToList(); //DataTable dt = new DataTable(sheet.Name); for (int j = 1; j <= columnCount; j++)//列名与字段名对应关系 { object objCellValue = sheet.Cells[titleRow, j].Value; string cellValue = objCellValue == null ? "" : objCellValue.ToString(); if (cellValue.Len() == 0) continue; var cellFieldName = filedDescriptions.Where(o => o.Key == cellValue).Select(o => o.Value).FirstOrDefault(); fieldIndexs.Add(new KeyValuePair<int, FieldDescriptionModel>(j, cellFieldName)); //dt.Columns.Add(cellValue, typeof(string)); } Type type = typeof(T); int iUserId = int.Parse(userId.ToString()); var properties = type.GetProperties(); //List<int> rowIndexList = Enumerable.Range(titleRow + 1, rowCount - titleRow).ToList();//数据行的行号集合 //Parallel.ForEach(rowIndexList, (i) => for (int i = titleRow + 1; i <= rowCount; i++) { #region 处理Excel每行数据 object objCellValue = null; string columnName = null; bool isEmptyCellValue = false;//是否有必须填写但实际没填写的数据 T model = Activator.CreateInstance<T>(); for (int j = 1; j <= columnCount; j++) { objCellValue = sheet.Cells[i, j].Value; var fieldPair = fieldIndexs.FirstOrDefault(o => o.Key == j); var field = fieldPair.Value; columnName = field == null ? "" : field.FieldName; if (columnName.IsNullOrEmpty()) continue; PropertyInfo p = properties.FirstOrDefault(o => string.Equals(o.Name, columnName, StringComparison.InvariantCultureIgnoreCase)); if (p == null) continue; SetPropertyValue<T>(ref model, ref p, ref objCellValue, ref field, ref isEmptyCellValue); } if (!isEmptyCellValue) { SetPropertyValueForKnowColumns<T>(ref model, ref properties, ref uploadMonth, ref userId, ref iUserId); list.Add(model); } #endregion } //); #region 判断第一行数据是否合格,Excel列名和字段对不上的情况,检查一个就等于检查全部 var firstModel = list.FirstOrDefault(); CheckModelRequiredData<T>(ref firstModel, ref properties, ref filedDescriptions); #endregion log += string.Format("{0:yyyy-MM-dd HH:mm:ss}完成解析文件{1}\r\n", DateTime.Now, filePath); return list; } finally { if (package != null) package.Dispose();//释放Excel对象资源 if (fs != null)//关闭和释放文件流资源 { fs.Close(); fs.Dispose(); } } } #endregion #region Splits the CSV line. /// <summary> /// Splits the CSV line. /// </summary> /// <param name="s">The s.</param> /// <returns></returns> private static string[] SplitCsvLine(string s) { Regex regex = new Regex("\".*?\""); var a = regex.Matches(s).Cast<Match>().Select(m => m.Value).ToList(); var b = regex.Replace(s, "%_%"); var c = b.Split(','); for (int i = 0, j = 0; i < c.Length && j < a.Count; i++) { if (c[i] == "%_%") { c[i] = a[j++]; } } return c; } #endregion #region Excel中数字时间转换成时间格式 /// <summary> /// Excel中数字时间转换成时间格式 /// </summary> /// <param name="timeStr">数字,如:42095.7069444444/0.650694444444444</param> /// <returns>日期/时间格式</returns> public static DateTime ToDateTimeValue(string strNumber) { if (!string.IsNullOrWhiteSpace(strNumber)) { Decimal tempValue; DateTime tempret; if (DateTime.TryParse(strNumber, out tempret)) { return tempret; } if (strNumber.Length == 8 && strNumber.Contains(".") == false)//20160430 { strNumber = strNumber.Insert(4, "-").Insert(6 + 1, "-"); if (DateTime.TryParse(strNumber, out tempret)) { return tempret; } else return default(DateTime); } //先检查 是不是数字; if (Decimal.TryParse(strNumber, out tempValue)) { //天数,取整 int day = Convert.ToInt32(Math.Truncate(tempValue)); //这里也不知道为什么. 如果是小于32,则减1,否则减2 //日期从1900-01-01开始累加 // day = day < 32 ? day - 1 : day - 2; DateTime dt = new DateTime(1900, 1, 1).AddDays(day < 32 ? (day - 1) : (day - 2)); //小时:减掉天数,这个数字转换小时:(* 24) Decimal hourTemp = (tempValue - day) * 24;//获取小时数 //取整.小时数 int hour = Convert.ToInt32(Math.Truncate(hourTemp)); //分钟:减掉小时,( * 60) //这里舍入,否则取值会有1分钟误差. Decimal minuteTemp = Math.Round((hourTemp - hour) * 60, 2);//获取分钟数 int minute = Convert.ToInt32(Math.Truncate(minuteTemp)); //秒:减掉分钟,( * 60) //这里舍入,否则取值会有1秒误差. Decimal secondTemp = Math.Round((minuteTemp - minute) * 60, 2);//获取秒数 int second = Convert.ToInt32(Math.Truncate(secondTemp)); if (second >= 60) { second -= 60; minute += 1; } if (minute >= 60) { minute -= 60; hour += 1; } //时间格式:00:00:00 string resultTimes = string.Format("{0}:{1}:{2}", (hour < 10 ? ("0" + hour) : hour.ToString()), (minute < 10 ? ("0" + minute) : minute.ToString()), (second < 10 ? ("0" + second) : second.ToString())); var str = string.Format("{0} {1}", dt.ToString("yyyy-MM-dd"), resultTimes); try { return DateTime.Parse(str); } catch (Exception ex) { throw new Exception("DateTime.Parse出错,str:" + str, ex); } } } return default(DateTime); } #endregion } }
//Aspose.Cells生成xlsx文件帮助类
using Aspose.Cells; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace YCF.HRMS.Utilities.CommomHelper { /// <summary> /// Aspose.Cells生成xlsx文件 /// </summary> public static class AsposeCellsHelper { public static void CreateExcel<T>(IEnumerable<T> content, string filePath, string sheetName, int startRow,bool setBorder = false, string getColorMethodName = null) { var columnsAccessor = CreateColumnsAccessor<T>(); var colInvoker = ExpressionHelper.GetMemberAccessor(columnsAccessor); var t = typeof(T); Workbook workbook = new Workbook(); var sheet = workbook.Worksheets[0]; ; sheet.Name = sheetName; var freezeAttr = t.GetCustomAttribute<ExcelFreezeAttribute>(); //冻结表头 if (freezeAttr != null) sheet.FreezePanes(startRow + 1, 0 + 1, freezeAttr.FreezeRowIndex + startRow + 1, freezeAttr.FreezeColumnIndex + 1); var cells = workbook.Worksheets[0].Cells; int rowIndex = startRow; int colIndex = 0; for (int i = 0; i < colInvoker.Count(); i++) { var col = colInvoker.ElementAt(i); //删除隐藏属性 var widthAttr = col.Key.GetCustomAttribute<ExcelColumnAttribute>(); if (widthAttr != null) { if (widthAttr.Hide) { colInvoker.Remove(col.Key); i--; continue; } } var title = col.Key.Name; var desc = col.Key.GetCustomAttribute<DescriptionAttribute>(); if (desc != null) title = desc.Description; else { var display = col.Key.GetCustomAttribute<DisplayAttribute>(); if (display != null) title = display.Name; } var myCell = sheet.Cells[rowIndex, colIndex]; Style style = myCell.GetStyle(); myCell.PutValue(title); style.Font.IsBold = true; style.HorizontalAlignment = TextAlignmentType.Center; style.Font.Name = "宋体"; style.Font.Size = 10; if (setBorder) { style.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.BottomBorder].Color = System.Drawing.Color.Black; style.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.TopBorder].Color = System.Drawing.Color.Black; style.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.LeftBorder].Color = System.Drawing.Color.Black; style.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.RightBorder].Color = System.Drawing.Color.Black; } myCell.SetStyle(style); cells.SetColumnWidth(colIndex, 15); colIndex++; } rowIndex++; PropertyInfo[] properties = colInvoker.Keys.OfType<PropertyInfo>().ToArray(); Func<T, string> getHtmlColorFunc = null; if(getColorMethodName != null) { MethodInfo getColorMethod = typeof(T).GetMethod(getColorMethodName); if (getColorMethod != null) { var parameter = Expression.Parameter(typeof(T)); getHtmlColorFunc = Expression.Lambda<Func<T, string>>(Expression.Call(parameter, getColorMethod), parameter).Compile(); } } //格式 Func<PropertyInfo, Cell, Style> colunmnStyles = (p, cell) => { Style style = cell.GetStyle(); var type = p.PropertyType; if (type.IsGenericType) { type = type.GetGenericArguments()[0]; } if (type == typeof(DateTime)) { style.Custom = "yyyyMMdd"; } else if (type == typeof(double) || type == typeof(decimal)) { style.Custom = "0.00"; } style.Font.Name = "宋体"; style.Font.Size = 10; return style; }; var propertyValueSetter = properties.ToDictionary(p => p, p => { Action<object, Cell> valueSetter; var type = p.PropertyType; if (type.IsGenericType) { type = type.GetGenericArguments()[0]; } if (type == typeof(DateTime)) { valueSetter = (o, cell) => { if (o != null) { cell.PutValue(Convert.ToDateTime(o)); } }; } else if (type == typeof(double) || type == typeof(decimal) || type == typeof(int)) { valueSetter = (o, cell) => { if (o != null) { cell.PutValue(Convert.ToDouble(o)); } }; } else { valueSetter = (o, cell) => { if (o != null) { cell.PutValue(o.ToString()); } }; } return valueSetter; }); foreach (var item in content) { colIndex = 0; foreach (var propertyInfo in properties) { object value = propertyInfo.GetValue(item); var cell = sheet.Cells[rowIndex, colIndex++]; propertyValueSetter[propertyInfo](value, cell); var style = colunmnStyles(propertyInfo, cell); if (getHtmlColorFunc != null) { style.ForegroundColor = System.Drawing.ColorTranslator.FromHtml(getHtmlColorFunc(item)); style.Pattern = BackgroundType.Solid; } if (setBorder) { style.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.BottomBorder].Color = System.Drawing.Color.Black; style.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.TopBorder].Color = System.Drawing.Color.Black; style.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.LeftBorder].Color = System.Drawing.Color.Black; style.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin; style.Borders[BorderType.RightBorder].Color = System.Drawing.Color.Black; } cell.SetStyle(style); } rowIndex++; } workbook.Save(filePath, new Aspose.Cells.OoxmlSaveOptions(Aspose.Cells.SaveFormat.Xlsx)); workbook.Worksheets.Clear(); } internal static Expression<Func<T, object>> CreateColumnsAccessor<T>() { var type = typeof(T); var ps = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); var bindings = new List<MemberBinding>(); var parameter = Expression.Parameter(type, "p"); foreach (var p in ps) { bindings.Add(Expression.Bind(p, Expression.MakeMemberAccess(parameter, p))); } var creator = Expression.MemberInit(Expression.New(type), bindings); var columnsAccessor = Expression.Lambda<Func<T, object>>(creator, parameter); return columnsAccessor; } } /// <summary> /// 可加的列宽属性 /// </summary> /// <seealso cref="System.Attribute" /> [AttributeUsage(AttributeTargets.Property)] public class ExcelColumnAttribute : Attribute { public int Width { get; set; } public bool Hide { get; set; } } /// <summary> /// 可加颜色属性 /// </summary> /// <seealso cref="System.Attribute" /> [AttributeUsage(AttributeTargets.Class)] public class ExcelCellStyleAttribute : Attribute { public string HtmlColorAccessor { get; set; } } /// <summary> /// 可加冻结属性 /// </summary> /// <seealso cref="System.Attribute" /> [AttributeUsage(AttributeTargets.Class)] public class ExcelFreezeAttribute : Attribute { public int FreezeColumnIndex { get; set; } public int FreezeRowIndex { get; set; } } }aspose引用:packages\Aspose.Cells\7.0.3(2011-11-12)\Aspose.Cells.dll
之前写过npoi的读取excel的文章,现在epplus也可以。
对比:
npoi可读写xls和xlsx,epplus只支持读写xlsx. 读写效率应该都差不了多少,写入少量数据可用这两个,大量数据写的话最好要用aspose。
aspose写入速度比npoi和epplus快。