using NPOI.HSSF.UserModel; using NPOI.HSSF.Util; using NPOI.SS.UserModel; using NPOI.SS.Util; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Web.Hosting; namespace Epost.Common { public class ExcelHelper { #region 导出 /// /// /// /// 导出结果 /// 保存excel文件路径 /// /// /// /// /// public bool ExcelDataExport(DataTable table, string filename, string filetitle, string WebRootPath, out string resultMsg, out string excelFilePath) { var result = true; excelFilePath = ""; resultMsg = "successfully"; //Excel导出名称 try { //首先创建Excel文件对象 var workbook = new HSSFWorkbook(); //创建工作表,也就是Excel中的sheet,给工作表赋一个名称(Excel底部名称) var sheet = workbook.CreateSheet(filename); //sheet.DefaultColumnWidth = 20;//默认列宽 sheet.ForceFormulaRecalculation = true;//TODO:是否开始Excel导出后公式仍然有效(非必须) //设置顶部大标题样式 var cellStyleFont = CreateStyle(workbook, HorizontalAlignment.Center, VerticalAlignment.Center, 20, true, 700, "楷体", true, false, false, true, FillPattern.SolidForeground, HSSFColor.White.Index, HSSFColor.Black.Index, FontUnderlineType.None, FontSuperScript.None, false); //第一行表单 IRow row = CreateRow(sheet, 0, 28); var cell = row.CreateCell(0); sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, table.Columns.Count - 1)); cell.SetCellValue(filetitle);//合并单元格后,只需对第一个位置赋值即可(TODO:顶部标题) cell.CellStyle = cellStyleFont; //处理表格列头 row = sheet.CreateRow(1); for (int i = 0; i < table.Columns.Count; i++) { row.CreateCell(i).SetCellValue(table.Columns[i].ColumnName); row.Height = 350; sheet.AutoSizeColumn(i); } //处理数据内容 for (int i = 0; i < table.Rows.Count; i++) { row = sheet.CreateRow(2 + i); row.Height = 250; for (int j = 0; j < table.Columns.Count; j++) { row.CreateCell(j).SetCellValue(table.Rows[i][j].ToString()); sheet.SetColumnWidth(j, 256 * 15); } } string folder = DateTime.Now.ToString("yyyyMMdd"); //保存文件到静态资源文件夹中(wwwroot),使用绝对路径 var uploadPath = WebRootPath + "/File/" + folder + "/"; //excel保存文件名 string excelFileName = filename + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls"; //创建目录文件夹 if (!Directory.Exists(uploadPath)) { Directory.CreateDirectory(uploadPath); } //Excel的路径及名称 string excelPath = uploadPath + excelFileName; //使用FileStream文件流来写入数据(传入参数为:文件所在路径,对文件的操作方式,对文件内数据的操作) var fileStream = new FileStream(excelPath, FileMode.OpenOrCreate, FileAccess.ReadWrite); //向Excel文件对象写入文件流,生成Excel文件 workbook.Write(fileStream); //关闭文件流 fileStream.Close(); //释放流所占用的资源 fileStream.Dispose(); //excel文件保存的相对路径,提供前端下载 var relativePositioning = "/File/" + folder + "/" + excelFileName; excelFilePath = relativePositioning; } catch (Exception e) { result = false; resultMsg = e.Message; } return result; } /// /// 行内单元格常用样式设置 /// /// Excel文件对象 /// 水平布局方式 /// 垂直布局方式 /// 字体大小 /// 是否需要边框 /// 字体加粗 (None = 0,Normal = 400,Bold = 700 /// 字体(仿宋,楷体,宋体,微软雅黑...与Excel主题字体相对应) /// 是否增加边框颜色 /// 是否将文字变为斜体 /// 是否自动换行 /// 是否增加单元格背景颜色 /// 填充图案样式(FineDots 细点,SolidForeground立体前景,isAddFillPattern=true时存在) /// 单元格背景颜色(当isAddCellBackground=true时存在) /// 字体颜色 /// 下划线样式(无下划线[None],单下划线[Single],双下划线[Double],会计用单下划线[SingleAccounting],会计用双下划线[DoubleAccounting]) /// 字体上标下标(普通默认值[None],上标[Sub],下标[Super]),即字体在单元格内的上下偏移量 /// 是否显示删除线 /// public HSSFCellStyle CreateStyle(HSSFWorkbook workbook, HorizontalAlignment hAlignment, VerticalAlignment vAlignment, short fontHeightInPoints, bool isAddBorder, short boldWeight, string fontName = "宋体", bool isAddBorderColor = true, bool isItalic = false, bool isLineFeed = false, bool isAddCellBackground = false, FillPattern fillPattern = FillPattern.NoFill, short cellBackgroundColor = HSSFColor.Yellow.Index, short fontColor = HSSFColor.Black.Index, FontUnderlineType underlineStyle = FontUnderlineType.None, FontSuperScript typeOffset = FontSuperScript.None, bool isStrikeout = false) { HSSFCellStyle cellStyle = (HSSFCellStyle)workbook.CreateCellStyle(); //创建列头单元格实例样式 cellStyle.Alignment = hAlignment; //水平居中 cellStyle.VerticalAlignment = vAlignment; //垂直居中 cellStyle.WrapText = isLineFeed;//自动换行 //背景颜色,边框颜色,字体颜色都是使用 HSSFColor属性中的对应调色板索引,关于 HSSFColor 颜色索引对照表,详情参考:https://www.cnblogs.com/Brainpan/p/5804167.html //TODO:引用了NPOI后可通过ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillPattern 为单元格背景色的填充样式 //TODO:十分注意,要设置单元格背景色必须是FillForegroundColor和FillPattern两个属性同时设置,否则是不会显示背景颜色 if (isAddCellBackground) { cellStyle.FillForegroundColor = cellBackgroundColor;//单元格背景颜色 cellStyle.FillPattern = fillPattern;//填充图案样式(FineDots 细点,SolidForeground立体前景) } //是否增加边框 if (isAddBorder) { //常用的边框样式 None(没有),Thin(细边框,瘦的),Medium(中等),Dashed(虚线),Dotted(星罗棋布的),Thick(厚的),Double(双倍),Hair(头发)[上右下左顺序设置] cellStyle.BorderBottom = BorderStyle.Thin; cellStyle.BorderRight = BorderStyle.Thin; cellStyle.BorderTop = BorderStyle.Thin; cellStyle.BorderLeft = BorderStyle.Thin; } //是否设置边框颜色 if (isAddBorderColor) { //边框颜色[上右下左顺序设置] cellStyle.TopBorderColor = HSSFColor.DarkGreen.Index;//DarkGreen(黑绿色) cellStyle.RightBorderColor = HSSFColor.DarkGreen.Index; cellStyle.BottomBorderColor = HSSFColor.DarkGreen.Index; cellStyle.LeftBorderColor = HSSFColor.DarkGreen.Index; } /** * 设置相关字体样式 */ var cellStyleFont = (HSSFFont)workbook.CreateFont(); //创建字体 //假如字体大小只需要是粗体的话直接使用下面该属性即可 //cellStyleFont.IsBold = true; cellStyleFont.Boldweight = boldWeight; //字体加粗 cellStyleFont.FontHeightInPoints = fontHeightInPoints; //字体大小 cellStyleFont.FontName = fontName;//字体(仿宋,楷体,宋体 ) cellStyleFont.Color = fontColor;//设置字体颜色 cellStyleFont.IsItalic = isItalic;//是否将文字变为斜体 cellStyleFont.Underline = underlineStyle;//字体下划线 cellStyleFont.TypeOffset = typeOffset;//字体上标下标 cellStyleFont.IsStrikeout = isStrikeout;//是否有删除线 cellStyle.SetFont(cellStyleFont); //将字体绑定到样式 return cellStyle; } /// /// TODO:先创建行,然后在创建对应的列 /// 创建Excel中指定的行 /// /// Excel工作表对象 /// 创建第几行(从0开始) /// 行高 public HSSFRow CreateRow(ISheet sheet, int rowNum, float rowHeight) { HSSFRow row = (HSSFRow)sheet.CreateRow(rowNum); //创建行 row.HeightInPoints = rowHeight; //设置列头行高 return row; } /// /// 创建行内指定的单元格 /// /// 需要创建单元格的行 /// 单元格样式 /// 创建第几个单元格(从0开始) /// 给单元格赋值 /// public HSSFCell CreateCells(HSSFRow row, HSSFCellStyle cellStyle, int cellNum, string cellValue) { HSSFCell cell = (HSSFCell)row.CreateCell(cellNum); //创建单元格 cell.CellStyle = cellStyle; //将样式绑定到单元格 if (!string.IsNullOrWhiteSpace(cellValue)) { //单元格赋值 cell.SetCellValue(cellValue); } return cell; } #endregion #region 导入 /// /// 读取excel表格中的数据,将Excel文件流转化为dataTable数据源 /// 默认第一行为标题 /// /// excel文档文件流 /// 文档格式 /// 是否转化成功 /// 转换结果消息 /// public DataTable ExcelToDataTable(Stream stream, string fileType) { //isSuccess = false; //resultMsg = "Excel文件流成功转化为DataTable数据源"; var excelToDataTable = new DataTable(); try { IWorkbook workbook; //XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式 #region 判断excel版本 switch (fileType) { //2007以下版本excel case ".xlsx": workbook = new XSSFWorkbook(stream); break; case ".xls": workbook = new HSSFWorkbook(stream); break; default: throw new Exception("Excel文档格式有误"); } #endregion var sheet = workbook.GetSheetAt(0); var rows = sheet.GetRowEnumerator(); var headerRow = sheet.GetRow(0); int cellCount = headerRow.LastCellNum;//最后一行列数(即为总列数) //获取第一行标题列数据源,转换为dataTable数据源的表格标题名称 for (var j = 0; j < cellCount; j++) { var cell = headerRow.GetCell(j); excelToDataTable.Columns.Add(cell.ToString()); } //获取Excel表格中除标题以为的所有数据源,转化为dataTable中的表格数据源 for (var i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) { var dataRow = excelToDataTable.NewRow(); var row = sheet.GetRow(i); if (row == null) continue; //没有数据的行默认是null  for (int j = row.FirstCellNum; j < cellCount; j++) { if (row.GetCell(j) != null)//单元格内容非空验证 { //获取指定的单元格信息 var cell = row.GetCell(j); #region NPOI获取Excel单元格数据不同类型数据 switch (cell.CellType) { //首先在NPOI中数字和日期都属于Numeric类型 //通过NPOI中自带的DateUtil.IsCellDateFormatted判断是否为时间日期类型 //case CellType.Numeric when DateUtil.IsCellDateFormatted(cell): // dataRow[j] = cell.DateCellValue; // break; case CellType.Numeric: //其他数字类型 dataRow[j] = cell.NumericCellValue; break; //空数据类型 case CellType.Blank: dataRow[j] = ""; break; //公式类型 case CellType.Formula: { HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workbook); dataRow[j] = eva.Evaluate(cell).StringValue; break; } //布尔类型 case CellType.Boolean: dataRow[j] = row.GetCell(j).BooleanCellValue; break; //错误 case CellType.Error: // dataRow[j] = HSSFErrorConstants.GetText(row.GetCell(j).ErrorCellValue); break; //其他类型都按字符串类型来处理(未知类型CellType.Unknown,字符串类型CellType.String) default: dataRow[j] = cell.StringCellValue; break; } #endregion } } excelToDataTable.Rows.Add(dataRow); } //isSuccess = true; } catch (Exception e) { LogHelper.WriteLogInfo("上传" + e, LogHelper.Log_Type.ERROR); } return excelToDataTable; } #endregion } }