using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using OfficeOpenXml; using OfficeOpenXml.Style; namespace CK.SCP.Utils { public class ExcelHelper { // Methods /// /// excle 2003 /// /// /// public static DataTable GetDataTable(Stream stream) { IWorkbook workbook; try { workbook = new HSSFWorkbook(stream); } catch (Exception exception) { try { workbook = new XSSFWorkbook(stream); } catch(Exception e) { throw e; } } ISheet sheetAt = workbook.GetSheetAt(0); IEnumerator rowEnumerator = sheetAt.GetRowEnumerator(); DataTable table = new DataTable(); IRow row = sheetAt.GetRow(0); if (row != null) { for (int j = 0; j < row.LastCellNum; j++) { ICell cell = row.GetCell(j); if (cell == null) { table.Columns.Add("cell" + j.ToString()); } else { table.Columns.Add(cell.ToString()); } } } int count = table.Columns.Count; for (int i = 0; rowEnumerator.MoveNext(); i++) { if (i > 0) { IRow current = (HSSFRow)rowEnumerator.Current; DataRow row3 = table.NewRow(); for (int k = 0; k < count; k++) { ICell cell2 = current.GetCell(k); if (cell2 == null) { row3[k] = null; } else { row3[k] = cell2.ToString(); } } table.Rows.Add(row3); } } return table; } /// /// excle 2007 /// /// /// public static DataTable GetDataTableOfXlsx(Stream stream) { IWorkbook workbook; try { workbook = new XSSFWorkbook(stream); } catch (Exception exception) { try { workbook = new XSSFWorkbook(stream); } catch (Exception e) { throw e; } } ISheet sheetAt = workbook.GetSheetAt(0); IEnumerator rowEnumerator = sheetAt.GetRowEnumerator(); DataTable table = new DataTable(); IRow row = sheetAt.GetRow(0); if (row != null) { for (int j = 0; j < row.LastCellNum; j++) { ICell cell = row.GetCell(j); if (cell == null) { table.Columns.Add("cell" + j.ToString()); } else { table.Columns.Add(cell.ToString()); } } } int count = table.Columns.Count; for (int i = 0; rowEnumerator.MoveNext(); i++) { if (i > 0) { IRow current = (XSSFRow)rowEnumerator.Current; DataRow row3 = table.NewRow(); for (int k = 0; k < count; k++) { ICell cell2 = current.GetCell(k); if (cell2 == null) { row3[k] = null; } else { row3[k] = cell2.ToString(); } } table.Rows.Add(row3); } } return table; } /// /// 删除空行 /// /// /// public static DataTable RemoveEmpty(DataTable dt) { List removelist = new List(); for (int i = 0; i < dt.Rows.Count; i++) { bool IsNull = true; for (int j = 0; j < dt.Columns.Count; j++) { if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim())) { IsNull = false; } } if (IsNull) { removelist.Add(dt.Rows[i]); } } for (int i = 0; i < removelist.Count; i++) { dt.Rows.Remove(removelist[i]); } return dt; } public static DataTable GetDataTable(string filePath) { HSSFWorkbook workbook; try { using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { workbook = new HSSFWorkbook(stream); } } catch (Exception exception) { throw exception; } ISheet sheetAt = workbook.GetSheetAt(0); IEnumerator rowEnumerator = sheetAt.GetRowEnumerator(); DataTable table = new DataTable(); IRow row = sheetAt.GetRow(0); if (row != null) { for (int j = 0; j < row.LastCellNum; j++) { ICell cell = row.GetCell(j); if (cell == null) { table.Columns.Add("cell" + j.ToString()); } else { table.Columns.Add(cell.ToString()); } } } int count = table.Columns.Count; for (int i = 0; rowEnumerator.MoveNext(); i++) { if (i > 0) { IRow current = (HSSFRow)rowEnumerator.Current; DataRow row3 = table.NewRow(); for (int k = 0; k < count; k++) { ICell cell2 = current.GetCell(k); if (cell2 == null) { row3[k] = null; } else { row3[k] = cell2.ToString(); } } table.Rows.Add(row3); } } return table; } /// /// 导入数据到excel文件 /// /// 待导入的数据 /// 文件路径 /// excel表名 /// 隐藏列索引 /// 列头字典;原始列头=>重命名列名 /// 标记红色加粗的列索引 /// 列头批注字典;列名=>批注内容 /// public static string SetDataTableToExcel(DataTable data, string fileName, string sheetName, int[] hiddenColmnIndexs = null, Dictionary header = null, int[] redHeaderClomnIndexs = null, Dictionary comments = null) { int num4 = 0; int num = 0; int column = 0; int rownum = 0; ISheet sheet = null; IWorkbook workbook = new HSSFWorkbook(); //todo:tans var stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); try { sheet = workbook.CreateSheet(sheetName); IRow row = sheet.CreateRow(0); column = 0; int maxCount = Math.Max(header != null ? header.Count : 0, data.Columns.Count); IDrawing patr1 = sheet.CreateDrawingPatriarch();// as HSSFPatriarch; //创建列头 while (column < data.Columns.Count) { var col = data.Columns[column]; var colName = col.ColumnName; ICell cell = row.GetCell(column); if (header != null && header.ContainsKey(colName)) { string temp = header[colName];//列重命名 header.Remove(colName); cell = row.CreateCell(column); cell.SetCellValue(temp); } //创建批注 colName = cell.StringCellValue; if (comments != null && comments.ContainsKey(colName)) { var commentStr = comments[colName]; IComment comment1 = patr1.CreateCellComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 3, 3, 7));// as HSSFComment; comment1.String = new HSSFRichTextString(commentStr); cell.CellComment = comment1; } column++; } //附加列头 int colCount = data.Columns.Count; foreach (var colName in header.Keys) { row.CreateCell(colCount).SetCellValue(header[colName]); colCount++; } //设置列头样式 redHeaderClomnIndexs = redHeaderClomnIndexs ?? new int[] { }; for (int i = 0, l = 0, rl = redHeaderClomnIndexs.Length; i < row.Cells.Count; i++, l++) { var cell = row.GetCell(i); if (cell == null) { continue; } //设置字体 IFont font = workbook.CreateFont(); font.Boldweight = (short)FontBoldWeight.Bold; if (l < rl) { int index = redHeaderClomnIndexs[l]; cell = row.GetCell(index); font.Color = (short)FontColor.Red; } //设置样式 ICellStyle style = workbook.CreateCellStyle(); style.Alignment = HorizontalAlignment.Center; style.SetFont(font); cell.CellStyle = style; } //创建数据列,并填充数据 rownum = 1; for (num = 0; num < data.Rows.Count; num++) { IRow row2 = sheet.CreateRow(rownum); for (column = 0; column < data.Columns.Count; column++) { row2.CreateCell(column).SetCellValue(data.Rows[num][column].ToString()); } rownum++; } //设置隐藏列 if (hiddenColmnIndexs != null && hiddenColmnIndexs.Length <= column) { for (int i = 0, l = hiddenColmnIndexs.Length; i < l; i++) { sheet.SetColumnHidden(hiddenColmnIndexs[i], true); } } //当创建完毕所有cell,设置居中才有效 for (int i = 0; i < row.Cells.Count; i++) { sheet.AutoSizeColumn(i); } workbook.Write(stream); } catch (Exception ex) { return null; } finally { stream.Close(); } return fileName; } } public class EpPlusHelper { private DataSet _dsExcel; private DataTable _dtExcel; private string _excelFileName; private List _readSheetNames; private string _pasword = string.Empty; public event Action ExportExcelCompleted = null; public EpPlusHelper() { } #region Read public DataTable ReadExcelToDt(string fileName, string password = "") { _excelFileName = fileName; _pasword = password; var excelFileExt = GetFileExt(fileName); switch (excelFileExt) { case ".XLSX": var poDv = new ProcessOperator { BackgroundWork = ReadExcelToDataTable }; poDv.BackgroundWorkerCompleted += ReadExcel_Completed; poDv.Start(); break; case ".XLS": throw new Exception($"需要使用NPOI解析后缀名为{excelFileExt}的文件!"); default: throw new Exception($"无法解析后缀名为{excelFileExt}的文件!"); } return _dtExcel; } private DataTable ReadData(ExcelWorksheet sheet) { var dt = new DataTable(sheet.Name); int colStart = sheet.Dimension.Start.Column; int colEnd = sheet.Dimension.End.Column; int rowStart = sheet.Dimension.Start.Row; int rowEnd = sheet.Dimension.End.Row; for (var i = colStart; i < colEnd + 1; i++)//从1开始计数 { var columnName = sheet.Cells[rowStart, i].Value.ToString(); dt.Columns.Add(columnName); } for (var row = rowStart + 1; row < rowEnd + 1; row++)//从1开始计数,跳过第一行 { var dr = dt.NewRow(); for (var col = colStart; col < colEnd + 1; col++)//从1开始计数 { dr[col - 1] = sheet.Cells[row, col]?.Value?.ToString(); } dt.Rows.Add(dr); } RemoveEmptyRow(dt); return dt; } private void ReadExcelToDataTable() { _readSheetNames = new List(); _dsExcel = new DataSet(); var fs = new FileStream(_excelFileName, FileMode.Open); try { using ( var package = string.IsNullOrEmpty(_pasword) ? new ExcelPackage(fs) : new ExcelPackage(fs, _pasword) ) { var validSheetList = GetValidSheetList(package); if (validSheetList.Count == 0) throw new Exception("未找到有效的Excel表单"); var sheet = validSheetList[0]; _readSheetNames.Add(sheet.Name); _dtExcel = ReadData(sheet); } } finally { fs.Close(); fs.Dispose(); } } private void ReadExcel_Completed(object sender, BackgroundWorkerEventArgs e) { if (e.BackGroundException == null) { if (_readSheetNames == null || _readSheetNames.Count == 0) { throw new Exception("文件读失败,未找到符合的系统要求的工作表!"); } } else { throw new Exception("文件读取失败,请联系管理员!"); } } private List GetValidSheetList(ExcelPackage package) { var list = new List(); for (var i = 1; i <= package.Workbook.Worksheets.Count; i++) { var sheet = package.Workbook.Worksheets[i]; var tableName = sheet.Name; if (!tableName.Equals("_xlnm#_FilterDatabase") && tableName.IndexOf("_", StringComparison.Ordinal) != tableName.Length - 1 && tableName.IndexOf("FilterDatabase", StringComparison.Ordinal) == -1) { list.Add(sheet); } } return list; } private void GetFileName(string fileName) { _excelFileName = fileName; } private string GetFileExt(string fileName) { return Path.GetExtension(fileName)?.ToUpper(); } #endregion #region Write public void WriteDsToExcel(string p_sheetName, DataSet ds, string title ,string password = "") { string fileName = p_sheetName + "-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xls"; // 文件名称 string urlPath = "/exportfiles/" + fileName; // 文件下载的URL地址,供给前台下载 string filePath = HttpContext.Current.Server.MapPath("\\" + urlPath); // 文件路径 // 1.检测是否存在文件夹,若不存在就建立个文件夹 string directoryName = Path.GetDirectoryName(filePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } WriteDataSetToExcel(ds, filePath, password,title); if (ExportExcelCompleted != null) { ExportExcelCompleted(filePath,fileName); } } private void WriteDataSetToExcel(DataSet ds, string excelFileName, string password ,string title) { var newFile = GetNewFile(excelFileName); _excelFileName = excelFileName; using (var package = string.IsNullOrEmpty(password) ? new ExcelPackage(newFile) : new ExcelPackage(newFile, password)) { foreach (DataTable dt in ds.Tables) { if (string.IsNullOrEmpty(dt?.TableName) || dt.Rows.Count == 0) continue; EpPlusHelper.RemoveEmptyRow(dt); var sheetName = "sheet1"; if (!string.IsNullOrEmpty(dt.TableName)) sheetName = dt.TableName; var worksheet = package.Workbook.Worksheets.Add(sheetName); if (title == null) { //表头 SetTitle(dt, worksheet); //各行数据 SetData(dt, worksheet); //设置单元格格式 SetFormat(worksheet); } else { //表头 SetTitle_h(dt, worksheet); //各行数据 SetData_h(dt, worksheet); //设置单元格格式 SetFormat_h(worksheet,title); } } if (package.Workbook.Worksheets.Count <= 0) return; if (string.IsNullOrEmpty(password)) package.Save(); else package.Save(password); } } private static FileInfo GetNewFile(string excelFileName) { var newFile = new FileInfo(excelFileName); if (newFile.Exists) { newFile.Delete(); // ensures we create a new workbook newFile = new FileInfo(excelFileName); } return newFile; } //public void WriteDtToExcel(DataTable dt, string password = "") //{ // WriteDtToExcel(dt, fileName, password); //} //public void WriteDtToExcel(DataTable dt, string excelFileName, string password) //{ // var excelFileExt = GetFileExt(excelFileName); // switch (excelFileExt) // { // case ".XLSX": // if (dt == null || dt.Rows.Count <= 0) throw new Exception("当前表单没有任何数据"); // var poDv = new ProcessOperator { BackgroundWork = () => WriteDataTableToExcel(dt, excelFileName, password) }; // poDv.BackgroundWorkerCompleted += WriteExcel_Completed; // poDv.Start(); // break; // case ".XLS": // throw new Exception($"需要使用NPOI解析后缀名为{excelFileExt}的文件!"); // default: // throw new Exception($"无法解析后缀名为{excelFileExt}的文件!"); // } //} private void WriteDataTableToExcel(DataTable dt, string excelFileName, string password) { var newFile = GetNewFile(excelFileName); _excelFileName = excelFileName; using (var package = string.IsNullOrEmpty(password) ? new ExcelPackage(newFile) : new ExcelPackage(newFile, password)) { var sheetName = "sheet1"; if (!string.IsNullOrEmpty(dt.TableName)) sheetName = dt.TableName; using (var worksheet = package.Workbook.Worksheets.Add(sheetName)) { //表头 SetTitle(dt, worksheet); //各行数据 SetData(dt, worksheet); //设置单元格格式 SetFormat(worksheet); if (string.IsNullOrEmpty(password)) package.Save(); else package.Save(password); } } } //private void WriteExcel_Completed(object sender, BackgroundWorkerEventArgs e) //{ // var newFile = new FileInfo(_excelFileName); // if (newFile.Exists) // Process.Start(_excelFileName); //} private static void SetFormat(ExcelWorksheet worksheet) { if (worksheet.Dimension == null) return; int colStart = worksheet.Dimension.Start.Column; int colEnd = worksheet.Dimension.End.Column; int rowStart = worksheet.Dimension.Start.Row; int rowEnd = worksheet.Dimension.End.Row; // using (var range = worksheet.Cells[1, 1, 1, dt.Columns.Count]) using (var range = worksheet.Cells[rowStart, colStart, rowStart, colEnd]) { range.Style.Fill.PatternType = ExcelFillStyle.LightGrid; range.Style.Fill.BackgroundColor.SetColor(Color.LightYellow); range.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } // using (var range = worksheet.Cells[1, 1, dt.Rows.Count + 1, dt.Columns.Count]) using (var range = worksheet.Cells[rowStart, colStart, rowEnd, colEnd]) { range.Style.Border.BorderAround(ExcelBorderStyle.Thin); range.Style.Font.Name = "微软雅黑"; range.Style.Font.Size = 12; range.AutoFitColumns(); } } /// /// 设置单元格(带标题) /// /// private static void SetFormat_h(ExcelWorksheet worksheet,string title) { if (worksheet.Dimension == null) return; int colStart = worksheet.Dimension.Start.Column; int colEnd = worksheet.Dimension.End.Column; int rowStart = worksheet.Dimension.Start.Row; int rowEnd = worksheet.Dimension.End.Row; using (var range = worksheet.Cells[1, 1, 1, worksheet.Dimension.End.Column]) { range.Merge = true; range.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; range.Value = title; range.Style.Font.Size = 24; } // using (var range = worksheet.Cells[1, 1, 1, dt.Columns.Count]) using (var range = worksheet.Cells[rowStart, colStart, rowStart, colEnd]) { range.Style.Fill.PatternType = ExcelFillStyle.LightGrid; range.Style.Fill.BackgroundColor.SetColor(Color.LightYellow); range.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } // using (var range = worksheet.Cells[1, 1, dt.Rows.Count + 1, dt.Columns.Count]) using (var range = worksheet.Cells[rowStart, colStart, rowEnd, colEnd]) { range.Style.Border.BorderAround(ExcelBorderStyle.Thin); range.Style.Font.Name = "微软雅黑"; range.Style.Font.Size = 12; range.AutoFitColumns(); } } private static void SetData(DataTable dt, ExcelWorksheet worksheet) { for (int i = 0; i < dt.Rows.Count; i++) { var row = i + 2; for (int j = 0; j < dt.Columns.Count; j++) { var col = j + 1; var s = dt.Rows[i][j]; ////////////////// //格式化日期字段 var dc = dt.Columns[j]; if (dc.DataType.FullName == "System.DateTime") { DateTime time; DateTime.TryParse(s.ToString(), out time); s = time.ToString("yyyy-MM-dd HH:mm:ss"); } //使用EPPLUS貌似不需要做这个转换了? // if (dc.DataType.FullName == "System.String") // { // s = "'" + s; // } decimal d; if (decimal.TryParse(s.ToString(), out d)) { if (Math.Round(d, 5) == 0) { s = 0; } } worksheet.Cells[row, col].Value = s; } } } /// /// 设置各行数据(带标题) /// /// /// private static void SetData_h(DataTable dt, ExcelWorksheet worksheet) { for (int i = 0; i < dt.Rows.Count; i++) { var row = i + 3; for (int j = 0; j < dt.Columns.Count; j++) { var col = j + 1; var s = dt.Rows[i][j]; ////////////////// //格式化日期字段 var dc = dt.Columns[j]; if (dc.DataType.FullName == "System.DateTime") { DateTime time; DateTime.TryParse(s.ToString(), out time); s = time.ToString("yyyy-MM-dd HH:mm:ss"); } //使用EPPLUS貌似不需要做这个转换了? // if (dc.DataType.FullName == "System.String") // { // s = "'" + s; // } decimal d; if (decimal.TryParse(s.ToString(), out d)) { if (Math.Round(d, 5) == 0) { s = 0; } } worksheet.Cells[row, col].Value = s; } } } private static void SetTitle(DataTable dt, ExcelWorksheet worksheet) { int row = 1; for (int i = 0; i < dt.Columns.Count; i++) { var dc = dt.Columns[i]; row = 1; var col = i + 1; worksheet.Cells[row, col].Value = dc.ColumnName; } worksheet.View.FreezePanes(row + 1, 1); //冻结表头 } /// /// 设置表头(带标题) /// /// /// private static void SetTitle_h(DataTable dt, ExcelWorksheet worksheet) { int row = 2; for (int i = 0; i < dt.Columns.Count; i++) { var dc = dt.Columns[i]; row = 2; var col = i + 1; worksheet.Cells[row, col].Value = dc.ColumnName; } worksheet.View.FreezePanes(row + 1, 1); //冻结表头 } #endregion public static void RemoveEmptyRow(DataTable dt) { if (dt == null || dt.Rows.Count == 0) return; var isEmpty = true; for (var idx = dt.Rows.Count - 1; idx >= 0; idx--) { var dr = dt.Rows[idx]; for (var i = 0; i < dt.Columns.Count; i++) { if (dr[i].ToString().Trim() != string.Empty) { isEmpty = false; } } if (isEmpty) dt.Rows.Remove(dr); } } } }