using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Text; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.SS.Util; using NPOI.XSSF.UserModel; using SAGA.DotNetUtils.NPOI; using SAGA.DotNetUtils.Extend; namespace SAGA.DotNetUtils.NPOI { /// /// NPOI操作帮助类 /// public class NPOIHelper { /// /// DataTable导出到Excel文件 /// /// 源DataTable /// 表头文本 /// 保存位置 public static void Export(DataTable dtSource, string strHeaderText, string strFileName) { using (MemoryStream ms = Export(dtSource, strHeaderText)) { using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)) { byte[] data = ms.ToArray(); fs.Write(data, 0, data.Length); fs.Flush(); } } } /// /// DataTable导出到Excel的MemoryStream /// /// 源DataTable /// 表头文本 public static MemoryStream Export(DataTable dtSource, string strHeaderText) { XSSFWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet(); ICellStyle dateStyle = workbook.CreateCellStyle(); IDataFormat format = workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-MM-dd"); #region 取得每列的列宽(最大宽度) int[] arrColWidth = new int[dtSource.Columns.Count]; foreach (DataColumn item in dtSource.Columns) { //GBK对应的code page是CP936 arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length; } for (int i = 0; i < dtSource.Rows.Count; i++) { for (int j = 0; j < dtSource.Columns.Count; j++) { int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length; if (intTemp > arrColWidth[j]) { arrColWidth[j] = intTemp; } } } #endregion int rowIndex = 0; foreach (DataRow row in dtSource.Rows) { #region 新建表,填充表头,填充列头,样式 if (rowIndex == 65535 || rowIndex == 0) { if (rowIndex != 0) { sheet = workbook.CreateSheet(); } #region 表头及样式 { IRow headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 25; headerRow.CreateCell(0).SetCellValue(strHeaderText); ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = HorizontalAlignment.Center; IFont font = workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1)); } #endregion #region 列头及样式 { IRow headerRow = sheet.CreateRow(1); ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = HorizontalAlignment.Center; IFont font = workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); foreach (DataColumn column in dtSource.Columns) { headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //设置列宽 sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256); } } #endregion rowIndex = 2; } #endregion #region 填充内容 ICellStyle contentStyle = workbook.CreateCellStyle(); contentStyle.Alignment = HorizontalAlignment.Left; IRow dataRow = sheet.CreateRow(rowIndex); foreach (DataColumn column in dtSource.Columns) { ICell newCell = dataRow.CreateCell(column.Ordinal); newCell.CellStyle = contentStyle; string drValue = row[column].ToString(); switch (column.DataType.ToString()) { case "System.String"://字符串类型 newCell.SetCellValue(drValue); break; case "System.DateTime"://日期类型 DateTime dateV; DateTime.TryParse(drValue, out dateV); newCell.SetCellValue(dateV); newCell.CellStyle = dateStyle;//格式化显示 break; case "System.Boolean"://布尔型 bool boolV = false; bool.TryParse(drValue, out boolV); newCell.SetCellValue(boolV); break; case "System.Int16"://整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(drValue, out intV); newCell.SetCellValue(intV); break; case "System.Decimal"://浮点型 case "System.Double": double doubV = 0; double.TryParse(drValue, out doubV); newCell.SetCellValue(doubV); break; case "System.DBNull"://空值处理 newCell.SetCellValue(""); break; default: newCell.SetCellValue(""); break; } } #endregion rowIndex++; } using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms); ms.Flush(); ms.Position = 0; //sheet.Dispose(); //workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet return ms; } } /// /// 用于Web导出 /// /// 源DataTable /// 表头文本 /// 文件名 //public static void ExportByWeb(DataTable dtSource, string strHeaderText, string strFileName) //{ // HttpContext curContext = HttpContext.Current; // // 设置编码和附件格式 // curContext.Response.ContentType = "application/vnd.ms-excel"; // curContext.Response.ContentEncoding = Encoding.UTF8; // curContext.Response.Charset = ""; // curContext.Response.AppendHeader("Content-Disposition", // "attachment;filename=" + HttpUtility.UrlEncode(strFileName + ".xls", Encoding.UTF8)); // curContext.Response.BinaryWrite(Export(dtSource, strHeaderText).GetBuffer()); // curContext.Response.End(); //} /// 读取excel /// 默认第一行为标头 /// 导出某一张表 /// /// excel文档路径 /// public static DataTable ImportAppointSheet(XSSFWorkbook hssfworkbook, int index) { ISheet sheet = hssfworkbook.GetSheetAt(index); if (sheet == null) return null; DataTable dt = new DataTable(sheet.SheetName); IRow headerRow = sheet.GetRow(0); if (headerRow == null) return dt; if (headerRow.Cells.Count==0) { headerRow = sheet.GetRow(1); } int cellCount = headerRow.LastCellNum; for (int j = 0; j < cellCount; j++) { ICell cell = headerRow.GetCell(j); dt.Columns.Add(cell.ToStr()); } for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); if(row==null)continue; DataRow dataRow = dt.NewRow(); for (int j = row.FirstCellNum; j < cellCount; j++) { if (row.GetCell(j) != null) dataRow[j] = row.GetCell(j).ToString(); } dt.Rows.Add(dataRow); } return dt; } /// /// 导出整个Excel /// /// /// public static DataSet Import(string strFileName) { DataSet ds = new DataSet(); XSSFWorkbook hssfworkbook; using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) { hssfworkbook = new XSSFWorkbook(file); } var sheetCount = hssfworkbook.Count; for (int i = 0; i < sheetCount; i++) { DataTable dt = ImportAppointSheet(hssfworkbook, i); if (dt != null) ds.Tables.Add(dt); } return ds; } /// /// 将Excel数据转换为实体列表 /// /// /// public static List ConvertExcelSheetToModel(string filePath) { var datas = new List(); var type = typeof(T); var sheetInfo = type.GetAttribute(); if (sheetInfo == null) return datas; var fileName = filePath; if (!File.Exists(fileName)) return datas; using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { IWorkbook workbook = null; //新建IWorkbook对象 var fileExtension = Path.GetExtension(fileName); if (fileExtension == ".xlsx") // 2007版本 { workbook = new XSSFWorkbook(fileStream); //xlsx数据读入workbook } else if (fileExtension == ".xls") // 2003版本 { workbook = new HSSFWorkbook(fileStream); //xls数据读入workbook } ISheet sheet = sheetInfo.SheetName == "" ? workbook.GetSheetAt(0) : workbook.GetSheet(sheetInfo.SheetName); IRow row; // List showIndex = new List { 1, 2, 3, 4 }; for (int i = sheetInfo.RowStartIndex; i < sheet.LastRowNum; i++) { row = sheet.GetRow(i); if (row != null) { datas.Add(ForeachClassProperties(row)); } } workbook.Close(); } return datas; } /// /// C#反射遍历对象属性 /// /// 对象类型 /// 对象 public static T ForeachClassProperties(IRow row) { Type t = typeof(T); var model = Activator.CreateInstance(); PropertyInfo[] PropertyList = t.GetProperties(); foreach (PropertyInfo item in PropertyList) { var index = item.GetCustomAttribute()?.Index; ICell cell = row.GetCell(index ?? 0); if (cell == null) { item.SetValue(model, ""); continue; } if (cell.IsMergedCell) { //row.Sheet. var sheet = row.Sheet; for (int i = 0; i < sheet.NumMergedRegions; i++) { var range = sheet.GetMergedRegion(i); if (range.IsInRange(cell.RowIndex, cell.ColumnIndex)) { var useRow = row.Sheet.GetRow(range.FirstRow); item.SetValue(model, useRow.GetCell(range.FirstColumn) + ""); break; } } } else { item.SetValue(model, row.GetCell(index ?? 0) + ""); } } return model; } } public class SheetInfoAttribute : Attribute { public string FilePath { get; set; } public string SheetName { get; set; } public int RowStartIndex { get; set; } } public class CellIndexAttribute : Attribute { public CellIndexAttribute(int index) { Index = index; } public int Index { get; set; } } public static class RefletcExtend { public static T GetAttribute(this Type type) where T : Attribute { return (T)type.GetCustomAttributes(typeof(T), false).FirstOrDefault(); } } }