using System; using System.Collections; using System.Collections.Generic; using System.IO; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.POIFS.FileSystem; using MyCode.Project.Infrastructure.Common; using NPOI.SS.Util; using System.Linq; namespace MyCode.Project.Infrastructure.Exports { /// /// 导出Excel配置类 /// public class ExportExcelConfig { /// /// 查询条件 /// public object Condition { get; set; } /// /// Excel中的标题和实体属性中的字段Map,例如:标题->Title /// public List Properties { get; } public List Heads = new List(); /// /// 初始化一个类型的实例 /// public ExportExcelConfig() { Properties = new List(); Heads = new List(); } /// /// 根据数据实体和配置生成相应的Excel文件 /// /// 数据源 /// 文件名 /// public string CreateExcelFile(IList sourceData,string fileName) { //初始化枚举字典 var dicEnum = new Dictionary>(); //获取列表第一个元素的数据类型 Type type = null; if (sourceData.Count > 0) { type = sourceData[0].GetType(); } //创建2007的Excel HSSFWorkbook workbook = null; //如果文件存在,则直接获取采用追加的方式追加进去 string filePath = GetDownloadPath(fileName); string absFilePath = FileUtils.GetPhysicalPath(filePath); ISheet sheet = null; IRow row = null; // (absFilePath); workbook = new HSSFWorkbook(); sheet = workbook.CreateSheet(); //设置标题列样式 ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.VerticalAlignment = VerticalAlignment.Center; headStyle.Alignment = HorizontalAlignment.Center; //设置字体-加粗字体 IFont headFont = workbook.CreateFont(); headFont.IsBold = true; row = sheet.CreateRow(0); //设置默认边框 ICellStyle style0 = workbook.CreateCellStyle(); style0.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; style0.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; style0.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; style0.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; int dataRowIndex = 0; int endColIndex = 0; if (Heads == null || Heads.Count == 0) { //创建标题列 for (int i = 0; i < this.Properties.Count; i++) { var cell = row.CreateCell(i); cell.SetCellValue(this.Properties[i].Caption); cell.CellStyle = headStyle; cell.CellStyle.SetFont(headFont); if (this.Properties[i].Width > 0) { sheet.SetColumnWidth(i, this.Properties[i].Width); } //设置边框 row.Sheet.SetDefaultColumnStyle(i, style0); } } else { endColIndex = Heads.Max(t => t.EndColIndex); //设置边框 for (int i = 0; i <= endColIndex; i++) { row.Sheet.SetDefaultColumnStyle(i, style0); } CreadHeader(workbook, ref sheet, Heads); dataRowIndex = Heads.Max(t => t.EndRowIndex); } //创建内容列 for (int i = 0; i < sourceData.Count ; i++) { var entity = sourceData[i]; //创建新的内容行 //row = sheet.CreateRow(i + sheet.LastRowNum + 1); row = sheet.CreateRow(dataRowIndex + 1); //根据配置的属性列创建对应单元格 for (int j = 0; j < this.Properties.Count; j++) { var prop = this.Properties[j].EntityProp; //储存内容值 object value = null; //检查是否存在+号,如果存在则表示是拼接数据 if (prop.IndexOf("+", StringComparison.Ordinal) > -1) { value = GetValueOfAddSymbol(this.Properties, type, entity, j); } else { value = this.GetPropValue(prop, type, entity); } //根据数据类型填写对应的单元格 if (value == null) { row.CreateCell(j).SetCellValue(""); } else if (value is decimal) { row.CreateCell(j).SetCellValue(Convert.ToDouble(value)); } else if (value is double) { row.CreateCell(j).SetCellValue((double)value); } else if (value is DateTime) { row.CreateCell(j).SetCellValue(Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss")); } else if (value is bool) { row.CreateCell(j).SetCellValue((bool)value); } else if (value is int ) { //枚举 if (this.Properties[j].EnumType != null) { var enumValue = GetEnumValue(dicEnum, this.Properties[j].EnumType, this.Properties[j].EntityProp, Convert.ToInt32(value)); row.CreateCell(j).SetCellValue(enumValue); } else { row.CreateCell(j).SetCellValue((int)value); } } else { row.CreateCell(j).SetCellValue(value.ToString()); } } dataRowIndex++; } using (FileStream fs = File.OpenWrite(absFilePath)) { workbook.Write(fs); fs.Close(); fs.Dispose(); } workbook = null; //SaveFilePath = filePath; return filePath; } #region GetEnumValue(得到枚举值) /// /// 得到枚举值 /// /// 所有字典 /// 枚举类型 /// 属性名 /// 枚举值 /// private string GetEnumValue(Dictionary> dicAllEnum,Type enumType,string fieldName,int dicValue) { if (!dicAllEnum.ContainsKey(fieldName)) { dicAllEnum[fieldName] = EnumHelper.GetDictionary(enumType); } if (!dicAllEnum[fieldName].ContainsKey(dicValue)) { return dicValue.ToString(); } return dicAllEnum[fieldName][dicValue]; } #endregion #region GetDownloadPath(获取下载路径) /// /// 获取下载路径 /// /// 文件名 /// private string GetDownloadPath(string fileName) { string dirPath = "/download/exceltemp/"; string absFilePath = FileUtils.GetPhysicalPath(dirPath); if (!Directory.Exists(absFilePath)) { Directory.CreateDirectory(absFilePath); } //string newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_fff"); //string filePath = Path.Combine(dirPath, fileName + "_" + newFileName + ".xls"); //return filePath; return Path.Combine(dirPath, fileName); } #endregion #region GetPropValue(获取字段值) /// /// 获取字段值 /// /// 属性名 /// 类型 /// 实体对象 /// private object GetPropValue(string prop, Type type, object entity) { object value = null; //如果存在.号则表示是复杂类型属性,需要依次去获取数据 if (prop.IndexOf(".", StringComparison.Ordinal) > -1) { var props = prop.Split('.'); //获取第一级实体 value = type.GetProperty(props[0]).GetValue(entity); for (int p = 1; p < props.Length; p++) { //如果值为空,则直接退出 if (value == null) { break; } Type childType = value.GetType(); value = childType.GetProperty(props[p]).GetValue(value); } } else { value = type.GetProperty(prop).GetValue(entity); } return value; } #endregion #region GetValueOfAddSymbol(如果字段名用了+号) /// /// 如果字段名用了+号 /// /// /// /// /// private object GetValueOfAddSymbol(List listProp,Type type,object entity,int j) { var prop = listProp[j].EntityProp; //储存内容值 object value = null; var joinProps = prop.Split('+'); for (int jp = 0; jp < joinProps.Length; jp++) { var jprop = joinProps[jp]; var newValue = this.GetPropValue(jprop, type, entity); if (value != null) { if (newValue != null) { //这里只智齿字符串的累加,主要解决地址合并省市区的情况 value = value.ToString() + listProp[j].JoinPropChar + newValue.ToString(); } } else { value = newValue; } } return value; } #endregion #region CreadHeader(创建表头,支持多行) /// /// 创建表头,支持多行 /// /// /// /// /// /// /// 创建:余宇波 2020-09-04 /// private static void CreadHeader(HSSFWorkbook book,ref ISheet sheet, List heads) { //创建 表格头部 if (heads != null && heads.Count > 0) { List rows = new List(); IRow headRow = sheet.CreateRow(0);//创建空行 rows.Add(0); var style = GetCellStyle(book, heads[0]); foreach (var t in heads) { if (!rows.Contains(t.StartRowIndex)) //假如没有创建行 { rows.Add(t.StartRowIndex); headRow = sheet.CreateRow(t.StartRowIndex); } else { headRow = sheet.GetRow(t.StartRowIndex); } headRow.Height = (short)(t.Height * 20); //设置行高 为25 ICell cell = headRow.CreateCell(t.StartColIndex); //创建单元格 cell.SetCellValue(t.FieldName); //设置单元格内容 // 设置列宽 if (t.Width > 0) { sheet.SetColumnWidth(cell.ColumnIndex, t.Width * 256); } else { sheet.SetColumnWidth(cell.ColumnIndex, 13 * 256); } //合并单元格 if (t.EndColIndex > t.StartColIndex || t.EndRowIndex > t.StartRowIndex) { CellRangeAddress region1 = new CellRangeAddress(t.StartRowIndex, t.EndRowIndex, (short)t.StartColIndex, (short)t.EndColIndex); headRow.Sheet.AddMergedRegion(region1); } cell.CellStyle = style; } } } private static ICellStyle GetCellStyle(HSSFWorkbook book, NpoiHeadCfg headCfg) { ICellStyle style0 = book.CreateCellStyle(); // 2、行高 // row.Height = 30 * 20; //行高为30 // excelRow.Height = 25 * 20; // 单元格 列宽: //if (headCfg.Width > 0) { // cell.Row.Sheet.SetColumnWidth(cell.ColumnIndex, headCfg.Width * 256); //} //三、设置居中: //cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中 style0.Alignment = HorizontalAlignment.Left; style0.VerticalAlignment = VerticalAlignment.Center; //四、设置字体: IFont font = book.CreateFont(); font.FontName = "黑体";//.SetFontName("黑体"); font.FontHeightInPoints = (short)11.5;//.SetFontHeightInPoints((short)16);//设置字体大小 style0.SetFont(font);//选择需要用到的字体格式 //大坑,大坑,大坑,shunlu 2018-10-10 //必须设置单元格背景色 FillForegroundColor 和 FillPattern 的值才能正确显示背景色 style0.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index; //(short)1灰色 NPOI.HSSF.Util.HSSFColor.LightBlue.Index; style0.FillPattern = FillPattern.SolidForeground; // CellStyle.SOLID_FOREGROUND //二、设置边框: //cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框    cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框    cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框    cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框    三、设置居中:      cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中     //style0.BorderBottom = BorderStyle.Medium;// CellStyle.SOLID_FOREGROUND //style0.BorderRight = BorderStyle.Medium; style0.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; style0.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; style0.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; style0.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; //三、设置居中: //cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中 style0.Alignment = HorizontalAlignment.Left; style0.VerticalAlignment = VerticalAlignment.Center; // return style0; } #endregion } }