NPOI相关DLL,直接上Nuget获取
这里作为笔记记录一下~

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.Collections;
using System.IO;
using System.Data;
using System.Windows.Forms;namespace Common.basefunc
{public static class ExcelHelper{#region 辅助方法/// <summary>/// 获取要保存的文件名称(含完整路径)/// </summary>/// <returns></returns>public static string GetSaveFilePath(){SaveFileDialog saveFileDig = new SaveFileDialog();saveFileDig.Filter = "Excel Office97-2003(*.xls)|*.xls|Excel Office2007及以上(*.xlsx)|*.xlsx";saveFileDig.FilterIndex = 0;saveFileDig.OverwritePrompt = true;string dir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);//获取当前系统桌面路径saveFileDig.InitialDirectory = dir;string filePath = null;if (saveFileDig.ShowDialog() == DialogResult.OK){filePath = saveFileDig.FileName;}return filePath;}/// <summary>/// 打开文件对话框,并返回文件的路径/// </summary>/// <returns></returns>public static string GetOpenFilePath(){//创建对话框的对象OpenFileDialog ofd = new OpenFileDialog();//设置对话框的标题ofd.Title = "请选择要打开的文件";//设置对话框可以多选ofd.Multiselect = true;//设置对话框的初始目录ofd.InitialDirectory = @"C:\Users\Administrator\Desktop";//设置对话框打开文件的类型ofd.Filter = "Excel文件(.xls)|*.xls|Excel文件(.xlsx)|*.xlsx";//展示对话框ofd.ShowDialog();//获得在打开对话框中选中的文件的路径string filePath = ofd.FileName;//全路径return filePath;}/// <summary>/// 判断Excel文件是否为兼容模式(.xls)/// </summary>/// <param name="filePath"></param>/// <returns></returns>public static bool GetIsCompatible(string filePath){return filePath.EndsWith(".xls", StringComparison.OrdinalIgnoreCase);}/// <summary>/// 创建工作薄/// </summary>/// <param name="isCompatible">true就是.xls</param>/// <returns></returns>public static IWorkbook CreateWorkbook(bool isCompatible){if (isCompatible){return new HSSFWorkbook();}else{return new XSSFWorkbook();}}/// <summary>/// 创建工作薄(依据文件流)/// </summary>/// <param name="isCompatible"></param>/// <param name="stream"></param>/// <returns></returns>public static IWorkbook CreateWorkbook(bool isCompatible, Stream stream){if (isCompatible){return new HSSFWorkbook(stream);}else{return new XSSFWorkbook(stream);}}#region 传入一个文件路径,返回一个IWorkbook对象/// <summary>/// 传入一个文件路径,返回一个IWorkbook对象/// </summary>/// <param name="filepath"></param>/// <returns></returns>public static IWorkbook CreateWorkbook(string filepath){IWorkbook workbook = null;bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fs = File.Open(filepath, FileMode.Open,FileAccess.Read, FileShare.ReadWrite)){//把xls文件读入workbook变量里,之后就可以关闭了  workbook = ExcelHelper.CreateWorkbook(isCompatible, fs);fs.Close();}return workbook;}#endregion#region 打开一个excel文件,设置单元格的值,再保存文件/// <summary>/// 打开一个excel文件,设置单元格的值,再保存文件/// </summary>/// <param name="ExcelPath"></param>/// <param name="sheetname"></param>/// <param name="column"></param>/// <param name="row"></param>/// <param name="value"></param>/// <returns></returns>public static bool SetCellValue(String ExcelPath, String sheetname, int column, int row, String value){bool returnb = false;try{IWorkbook wk = null;bool isCompatible = ExcelHelper.GetIsCompatible(ExcelPath);using (FileStream fs = File.Open(ExcelPath, FileMode.Open,FileAccess.Read, FileShare.ReadWrite)){//把xls文件读入workbook变量里,之后就可以关闭了  wk = ExcelHelper.CreateWorkbook(isCompatible, fs);fs.Close();}//把xls文件读入workbook变量里,之后就可以关闭了  //ISheet sheet = wk.GetSheet(sheetname);ISheet sheet = wk.GetSheetAt(0);ICell cell = sheet.GetRow(row).GetCell(column);cell.SetCellValue(value);using (FileStream fileStream = File.Open(ExcelPath,FileMode.OpenOrCreate, FileAccess.ReadWrite)){wk.Write(fileStream);fileStream.Close();}returnb = true;}catch (Exception){returnb = false;throw;}return returnb;}#endregion#region 打开一个文件,读取excel文件某个单元格的值(多少行,多少列)/// <summary>/// 打开一个文件,读取excel文件某个单元格的值(多少行,多少列)/// </summary>/// <param name="ExcelPath"></param>/// <param name="sheetname"></param>/// <param name="column"></param>/// <param name="row"></param>/// <returns></returns>public static String GetCellValue(string ExcelPath, String sheetname, int column, int row){String returnStr = null;try{IWorkbook wk = null;bool isCompatible = ExcelHelper.GetIsCompatible(ExcelPath);using (FileStream fs = File.Open(ExcelPath, FileMode.Open,FileAccess.Read, FileShare.ReadWrite)){//把xls文件读入workbook变量里,之后就可以关闭了  wk = ExcelHelper.CreateWorkbook(isCompatible, fs);fs.Close();}//把xls文件读入workbook变量里,之后就可以关闭了  //ISheet sheet = wk.GetSheet(sheetname);ISheet sheet = wk.GetSheetAt(0);ICell cell = sheet.GetRow(row).GetCell(column);returnStr = cell.ToString();}catch (Exception){returnStr = "Exception";throw;}return returnStr;}#endregion#region  打开一个文件,删除多少以后的数据(是删除,不是清空数据)/// <summary>/// 打开一个文件,删除多少以后的数据(是删除,不是清空数据)/// </summary>/// <param name="fileMatchPath"></param>/// <param name="rowIndex">从多少行后开始删除</param>public static void DelRowsData(string fileMatchPath, int startRowIndex){IWorkbook wk = null;bool isCompatible = ExcelHelper.GetIsCompatible(fileMatchPath);using (FileStream fs = File.Open(fileMatchPath, FileMode.Open,FileAccess.Read, FileShare.ReadWrite)){//把xls文件读入workbook变量里,之后就可以关闭了  wk = ExcelHelper.CreateWorkbook(isCompatible, fs);fs.Close();}ISheet sheet = wk.GetSheetAt(0);for (int i = startRowIndex; i <= sheet.LastRowNum; i++){if (sheet.GetRow(i) == null){i++;continue;}sheet.RemoveRow(sheet.GetRow(i));}//转为字节数组 MemoryStream stream = new MemoryStream();wk.Write(stream);var buf = stream.ToArray();//保存为Excel文件  这种方式能保存.xls和.xlsx文件using (FileStream fs = new FileStream(fileMatchPath, FileMode.Create, FileAccess.Write)){fs.Write(buf, 0, buf.Length);fs.Flush();}}#endregion/// <summary>/// 创建表格头单元格/// </summary>/// <param name="sheet"></param>/// <returns></returns>private static ICellStyle GetCellStyle(IWorkbook workbook){ICellStyle style = workbook.CreateCellStyle();style.FillPattern = FillPattern.SolidForeground;style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;return style;}/// <summary>/// 遍历打印二维数组/// </summary>/// <param name="array"></param>public static void PrintTwoArrayTest(object[,] array){Console.WriteLine("============测试打印二维数组==============");int row = array.GetLength(0);int column = array.GetLength(1);for (int r = 0; r < row; r++){for (int c = 0; c < column; c++){if (array[r, c] != null){string value = array[r, c].ToString();Console.Write($"{value}  |");}}Console.WriteLine();}}/// <summary>/// 传入2个二维数组,进行条件匹配替换,返回替换后的一个二维数组/// </summary>/// <param name="refArray">参考的数组</param>/// <param name="matchArray">带替换的数组</param>/// <param name="refColumn01">参考列1</param>/// <param name="refColumn02">参考列2</param>/// <param name="refColTarget01">被复制的值的列1</param>/// <param name="matchColumn01">带替换的参考列1</param>/// <param name="matchColumn02">带替换的参考列2</param>/// <param name="matchColTarget01">带粘贴的值的列1</param>/// <returns></returns>public static string[,] GetMatchArray(string[,] refArray, string[,] matchArray, int refColumn01, int refColumn02, int refColTarget01, int matchColumn01, int matchColumn02, int matchColTarget01){Console.WriteLine("============遍历2个二维数,匹配替换==============");int row = refArray.GetLength(0);int column = matchArray.GetLength(1);int row02 = matchArray.GetLength(0);int iMatch = 0;for (int r = 0; r < row; r++){string value01 = refArray[r, refColumn01];//第1列的数据string value02 = refArray[r, refColumn02];//第2列的数据if (value01 != null && value02 != null){if (value01.Length > 0 | value02.Length > 0){for (int r02 = 0; r02 < row02; r02++){string match01 = matchArray[r02, matchColumn01];//第1列的数据string match02 = matchArray[r02, matchColumn02];//第2列的数据if (value01 == match01 && value02 == match02){matchArray[r02, matchColTarget01] = refArray[r, refColTarget01];iMatch++;Console.WriteLine($"匹配了{iMatch}次");}}}}}return matchArray;}/// <summary>/// 传入2个数组,根据相同条件匹配,吧ref的目标写入match中/// </summary>/// <param name="refArray">参考的数组</param>/// <param name="matchArray">带替换的数组</param>/// <param name="refColumn01"></param>/// <param name="refColTarget01"></param>/// <param name="matchColumn01"></param>/// <param name="matchColTarget01"></param>/// <returns></returns>public static string[,] GetMatchArray(string[,] refArray, string[,] matchArray, int refColumn01, int refColTarget01, int matchColumn01, int matchColTarget01){Console.WriteLine("============遍历2个二维数,匹配替换==============");int row = refArray.GetLength(0);int column = matchArray.GetLength(1);int row02 = matchArray.GetLength(0);int iMatch = 0;for (int r = 0; r < row; r++){string value01 = string.Empty;value01 = refArray[r, refColumn01];//遍历第一个数组第1列的数据//value01 = value01.Trim();if (value01 != null){if (value01.Length > 0){for (int r02 = 0; r02 < row02; r02++){string match01 = string.Empty;match01 = matchArray[r02, matchColumn01];//遍历第一个数组第1列的数据//match01 = match01.Trim();                                          if (value01 == match01){matchArray[r02, matchColTarget01] = refArray[r, refColTarget01];iMatch++;Console.WriteLine($"匹配了{iMatch}次");}}}}}return matchArray;}/// <summary>/// 遍历一个数组,如果第二列的数值大于等于第一列的数值,替换字符串/// </summary>/// <param name="matchArray"></param>/// <param name="refColumn01"></param>/// <param name="refColumn02"></param>/// <param name="sValue"></param>/// <returns></returns>public static string[,] GetMatchArray(string[,] matchArray, int refColumn01, int refColumn02, string sValue){Console.WriteLine("============遍历2个二维数,匹配替换==============");int row = matchArray.GetLength(0);int column = matchArray.GetLength(1);int iMatch = 0;for (int r = 0; r < row; r++){string value01 = matchArray[r, refColumn01];//第1列的数据string value02 = matchArray[r, refColumn02];//第2列的数据try{int i01 = Convert.ToInt32(value01);int i02 = Convert.ToInt32(value02);if (i01 >= i02){matchArray[r, refColumn02] = sValue + $"(数量:{value02})";}}catch{}}return matchArray;}#region 打开excel文件,获取某一行的数据/// <summary>/// 打开excel文件,获取某一行的数据/// </summary>/// <param name="filepath">文件全路径</param>/// <param name="iRow">哪一行的数据</param>/// <param name="sheet_Number">哪一个sheet表</param>/// <returns></returns>public static ArrayList GetRowData(string filepath, int sheet_Number, int iRow){ArrayList arrayList = new ArrayList();bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fsRead = File.OpenRead(filepath)){IWorkbook workbook = ExcelHelper.CreateWorkbook(isCompatible, fsRead);ISheet sheet = workbook.GetSheetAt(sheet_Number - 1);IRow currentRow = sheet.GetRow(iRow - 1);for (int c = 0; c < currentRow.LastCellNum; c++){//获取每个单元格(r行c列的数据)ICell cell = currentRow.GetCell(c);//获取单元格的内容string value = string.Empty;if (cell != null){value = cell.ToString(); //如果单元格为空,这里会报错的arrayList.Add(value);}}return arrayList;}}#endregion/// <summary>///  打开excel文件,根据某一行的数据,根据字符串内容,返回这个字符串所在的列的索引/// </summary>/// <param name="filepath"></param>/// <param name="iRow"></param>/// <param name="sheet_Number">从1开始的</param>/// <param name="s1">注意字符串的顺序</param>/// <param name="s2"></param>/// <param name="s3"></param>/// <returns></returnsspublic static ArrayList GetDataIndexs(string filepath, int sheet_Number, int iRow, string s1, string s2, string s3){ArrayList arrayList = new ArrayList();bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fsRead = File.OpenRead(filepath)){IWorkbook workbook = ExcelHelper.CreateWorkbook(isCompatible, fsRead);ISheet sheet = workbook.GetSheetAt(sheet_Number - 1);IRow currentRow = sheet.GetRow(iRow - 1);for (int c = 0; c < currentRow.LastCellNum; c++){//获取每个单元格(r行c列的数据)ICell cell = currentRow.GetCell(c);//获取单元格的内容string value = string.Empty;if (cell != null){value = cell.ToString(); //如果单元格为空,这里会报错的if (value == s1 | value == s2 || value == s3){arrayList.Add(c);}}}Console.WriteLine("==========测试打印索引值============");foreach (var a in arrayList){Console.WriteLine($"{a} |");}return arrayList;}}/// <summary>/// 打开excel文件,根据某一行的字符串,然后这个字符串所在列的索引/// </summary>/// <param name="filepath"></param>/// <param name="sheet_Number"></param>/// <param name="iRow"></param>/// <param name="sValue"></param>/// <returns></returns>public static int GetDataIndex(string filepath, int sheet_Number, int iRow, string sValue){int i = 0;bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fsRead = File.OpenRead(filepath)){IWorkbook workbook = ExcelHelper.CreateWorkbook(isCompatible, fsRead);ISheet sheet = workbook.GetSheetAt(sheet_Number - 1);IRow currentRow = sheet.GetRow(iRow - 1);for (int c = 0; c < currentRow.LastCellNum; c++){//获取每个单元格(r行c列的数据)ICell cell = currentRow.GetCell(c);//获取单元格的内容string value = string.Empty;if (cell != null){value = cell.ToString(); //如果单元格为空,这里会报错的if (value == sValue){i = c;}}}}return i;}/// <summary>/// 打开一个文件,把第几行的数据取出来,返回一个字典 单元格的值:列的索引/// </summary>/// <param name="filepath"></param>/// <param name="sheet_Number">第几张工作表(从1开始)</param>/// <param name="iRow">第几行(从1开始)</param>/// <returns></returns>public static Dictionary<string, int> GetDataDictionary(string filepath, int sheet_Number, int iRow){Dictionary<string, int> DataDict = new Dictionary<string, int>();bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fsRead = File.OpenRead(filepath)){IWorkbook workbook = ExcelHelper.CreateWorkbook(isCompatible, fsRead);ISheet sheet = workbook.GetSheetAt(sheet_Number - 1);IRow currentRow = sheet.GetRow(iRow - 1);for (int c = 0; c < currentRow.LastCellNum; c++){//获取每个单元格(r行c列的数据)ICell cell = currentRow.GetCell(c);//获取单元格的内容string value = string.Empty;if (cell != null){value = cell.ToString(); //如果单元格为空,这里会报错的if (!DataDict.ContainsKey(value)){if (value == "*预计交货日期" | value == "预计交货日期"){value = "*预计交货日期";}DataDict.Add(value, c);}else{if (filepath.Contains("销售订单")) //销售订单模板的第二个备注填写收货地址{if (value == "备注") //如果有两个备注{//DataDict.Add("采购员", c);DataDict.Add("收货地址", c);}}}}}//Console.WriteLine("================开始遍历字典===============");//foreach (KeyValuePair<string, int> kv in DataDict)//通过KeyValuePair遍历元素//{//    Console.WriteLine($"Key:{kv.Key},Value:{kv.Value}");//}return DataDict;}}/// <summary>///  打开一个文件,根据第几张表第几行的中的两个字符,返回值:一个字典/// </summary>/// <param name="filepath"></param>/// <param name="sheet_Number"></param>/// <param name="strColumnKey"></param>/// <param name="strColumnValue"></param>/// <returns></returns>public static Dictionary<string, string> GetDataDictionary(string filepath, int sheet_Number, int iRow, string strColumnKey, string strColumnValue){Dictionary<string, int> dic = GetDataDictionary(filepath, 1, iRow);int iColumnKey = dic[strColumnKey];int iColumnValue = dic[strColumnValue];Dictionary<string, string> DataDict = new Dictionary<string, string>();bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fsRead = File.OpenRead(filepath)){IWorkbook workbook = ExcelHelper.CreateWorkbook(isCompatible, fsRead);ISheet sheet = workbook.GetSheetAt(sheet_Number - 1);for (int i = 0; i <= sheet.LastRowNum; i++){IRow rowdata = sheet.GetRow(i);ICell cellKey = rowdata.GetCell(iColumnKey);ICell cellValue = rowdata.GetCell(iColumnValue);if (cellKey != null && cellValue != null){if (!DataDict.ContainsKey(cellKey.ToString())){string strCellKey = cellKey.ToString();string strCellValue = cellValue.ToString();DataDict.Add(strCellKey, strCellValue);}}}return DataDict;}}#region 根据一个文件,获取一个Excel文件的最大行数和列数(不成熟不建议用)/// <summary>/// 根据一个文件,获取一个Excel文件的最大行数和列数(不成熟不建议用)/// </summary>/// <param name="filepath">excel表格保存的地址,包括"文件名.xls</param>/// <param name="sheet_number">代表将要读取的sheet表的索引位置</param>/// <returns>行数Array[0],列数Array[2]</returns>public static Array GetRowCountAndColumnCount(string filepath, int sheet_number){int rowMaxCount = 0;int columnMaxCount = 0;FileStream readStream = null;try{if (!string.IsNullOrEmpty(filepath) && sheet_number > 0){readStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);bool isCompatible = GetIsCompatible(filepath);IWorkbook workbook = CreateWorkbook(isCompatible, readStream);ISheet sheet = workbook.GetSheetAt(sheet_number - 1);if (sheet != null){rowMaxCount = sheet.LastRowNum + 1; //有效行数(NPOI读取的有效行数不包括列头,所以需要加1)for (int c = 0; c <= sheet.LastRowNum; c++){IRow row = sheet.GetRow(c);
#pragma warning disable CS1525 // 表达式项“=”无效if (row != null && row.LastCellNum > -1)
#pragma warning restore CS1525 // 表达式项“=”无效{columnMaxCount = row.LastCellNum;}}}}}catch (Exception e){Console.WriteLine(e);throw;}finally{if (readStream != null){readStream.Close();}}int[] array = new int[2];array[1] = rowMaxCount;array[2] = columnMaxCount;return array;}#endregion/// <summary>/// Excel转化为二维数组/// </summary>/// <param name="filepath">文件全路径</param>/// <param name="arrayRowNnmber">数组的行数</param>/// <param name="arrayColumnNumber">数组的列数</param>/// <param name="sheet_Number">要遍历的sheet索引</param>/// <returns>返回一个二维素组</returns>public static string[,] ToTwoArray(string filepath, int arrayRowNnmber, int arrayColumnNumber, int sheet_Number){string[,] array = new string[arrayRowNnmber, arrayColumnNumber];bool isCompatible = ExcelHelper.GetIsCompatible(filepath);using (FileStream fsRead = File.OpenRead(filepath)){IWorkbook workbook = ExcelHelper.CreateWorkbook(isCompatible, fsRead);ISheet sheet = workbook.GetSheetAt(sheet_Number - 1); //获取第一个工作表(sheet)int rowCount = sheet.LastRowNum;if (!isCompatible)//如果是xlsx格式的,行数要-2{rowCount = rowCount - 2;}for (int r = 0; r <= rowCount; r++){IRow currentRow = sheet.GetRow(r); //读取当前行数据Console.Write($"第{r}行有{currentRow.LastCellNum}列有数据:--->");for (int c = 0; c < currentRow.LastCellNum; c++){//获取每个单元格(r行c列的数据)ICell cell = currentRow.GetCell(c);//获取单元格的内容string value = string.Empty;if (cell != null){value = cell.ToString(); //如果单元格为空,这里会报错的}Console.Write($"{value}  |");array[r, c] = value;}Console.WriteLine();}return array;}}/// <summary>/// 从工作表中生成DataTable/// </summary>/// <param name="sheet"></param>/// <param name="headerRowIndex"></param>/// <returns></returns>private static DataTable GetDataTableFromSheet(ISheet sheet, int headerRowIndex){DataTable table = new DataTable();IRow headerRow = sheet.GetRow(headerRowIndex);int cellCount = headerRow.LastCellNum;for (int i = headerRow.FirstCellNum; i < cellCount; i++){if (headerRow.GetCell(i) == null || headerRow.GetCell(i).StringCellValue.Trim() == ""){// 如果遇到第一个空列,则不再继续向后读取cellCount = i + 1;break;}DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);table.Columns.Add(column);}for (int i = (headerRowIndex + 1); i <= sheet.LastRowNum; i++){IRow row = sheet.GetRow(i);if (row != null && !string.IsNullOrEmpty(row.Cells[0].StringCellValue)){DataRow dataRow = table.NewRow();for (int j = row.FirstCellNum; j < cellCount; j++){if (row.GetCell(j) != null){dataRow[j] = row.GetCell(j).ToString();}}table.Rows.Add(dataRow);}}return table;}#endregion#region 公共导出方法/// <summary>/// 由DataSet导出Excel/// </summary>/// <param name="sourceTable">要导出数据的DataTable</param>/// <returns>Excel工作表</returns>public static string ExportToExcel(DataSet sourceDs, string filePath = null){if (string.IsNullOrEmpty(filePath)){filePath = GetSaveFilePath();}if (string.IsNullOrEmpty(filePath)) return null;bool isCompatible = GetIsCompatible(filePath);IWorkbook workbook = CreateWorkbook(isCompatible);ICellStyle cellStyle = GetCellStyle(workbook);for (int i = 0; i < sourceDs.Tables.Count; i++){DataTable table = sourceDs.Tables[i];string sheetName = "result" + i.ToString();ISheet sheet = workbook.CreateSheet(sheetName);IRow headerRow = sheet.CreateRow(0);// handling header.foreach (DataColumn column in table.Columns){ICell cell = headerRow.CreateCell(column.Ordinal);cell.SetCellValue(column.ColumnName);cell.CellStyle = cellStyle;}// handling value.int rowIndex = 1;foreach (DataRow row in table.Rows){IRow dataRow = sheet.CreateRow(rowIndex);foreach (DataColumn column in table.Columns){dataRow.CreateCell(column.Ordinal).SetCellValue((row[column] ?? "").ToString());}rowIndex++;}}FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);workbook.Write(fs);fs.Dispose();workbook = null;return filePath;}/// <summary>/// 获取sheet表名/// </summary>/// <param name="filePath"></param>/// <returns></returns>public static string[] GetSheetName(string filePath){int sheetNumber = 0;var file = new FileStream(filePath, FileMode.Open, FileAccess.Read);if (filePath.IndexOf(".xlsx") > 0){//2007版本var xssfworkbook = new XSSFWorkbook(file);sheetNumber = xssfworkbook.NumberOfSheets;string[] sheetNames = new string[sheetNumber];for (int i = 0; i < sheetNumber; i++){sheetNames[i] = xssfworkbook.GetSheetName(i);}return sheetNames;}else if (filePath.IndexOf(".xls") > 0){//2003版本var hssfworkbook = new HSSFWorkbook(file);sheetNumber = hssfworkbook.NumberOfSheets;string[] sheetNames = new string[sheetNumber];for (int i = 0; i < sheetNumber; i++){sheetNames[i] = hssfworkbook.GetSheetName(i);}return sheetNames;}return null;}/// <summary>/// 根据表名获取表/// </summary>/// <param name="filePath"></param>/// <param name="sheetName"></param>/// <returns></returns>public static DataTable ExcelToDataTable(string filePath, string sheetName){string outMsg = "";var dt = new DataTable();string fileType = Path.GetExtension(filePath).ToLower();try{ISheet sheet = null;FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);if (fileType == ".xlsx"){//2007版XSSFWorkbook workbook = new XSSFWorkbook(fs);sheet = workbook.GetSheet(sheetName);if (sheet != null){dt = GetSheetDataTable(sheet, out outMsg);}}else if (fileType == ".xls"){//2003版HSSFWorkbook workbook = new HSSFWorkbook(fs);sheet = workbook.GetSheet(sheetName);if (sheet != null){dt = GetSheetDataTable(sheet, out outMsg);}}}catch (Exception e){Console.WriteLine(e.Message);}return dt;}private static int sheetCellNumMax = 12;/// <summary>/// 获取sheet表对应的DataTable/// </summary>/// <param name="sheet">Excel工作表</param>/// <param name="strMsg"></param>/// <returns></returns>private static DataTable GetSheetDataTable(ISheet sheet, out string strMsg){strMsg = "";DataTable dt = new DataTable();string sheetName = sheet.SheetName;int startIndex = 0;// sheet.FirstRowNum;int lastIndex = sheet.LastRowNum;//最大列数int cellCount = 0;IRow maxRow = sheet.GetRow(0);for (int i = startIndex; i <= lastIndex; i++){IRow row = sheet.GetRow(i);if (row != null && cellCount < row.LastCellNum){cellCount = row.LastCellNum;maxRow = row;}}//列名设置try{//maxRow.LastCellNum = 12 // Lfor (int i = 0; i < sheetCellNumMax; i++)//maxRow.FirstCellNum{dt.Columns.Add(Convert.ToChar(((int)'A') + i).ToString());//DataColumn column = new DataColumn("Column" + (i + 1).ToString());//dt.Columns.Add(column);}}catch{strMsg = "工作表" + sheetName + "中无数据";return null;}//数据填充for (int i = startIndex; i <= lastIndex; i++){IRow row = sheet.GetRow(i);DataRow drNew = dt.NewRow();if (row != null){for (int j = row.FirstCellNum; j < row.LastCellNum; ++j){if (row.GetCell(j) != null){ICell cell = row.GetCell(j);switch (cell.CellType){case CellType.Blank:drNew[j] = "";break;case CellType.Numeric:short format = cell.CellStyle.DataFormat;//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理if (format == 14 || format == 31 || format == 57 || format == 58)drNew[j] = cell.DateCellValue;elsedrNew[j] = cell.NumericCellValue;if (cell.CellStyle.DataFormat == 177 || cell.CellStyle.DataFormat == 178 || cell.CellStyle.DataFormat == 188)drNew[j] = cell.NumericCellValue.ToString("#0.00");break;case CellType.String:drNew[j] = cell.StringCellValue;break;case CellType.Formula:try{drNew[j] = cell.NumericCellValue;if (cell.CellStyle.DataFormat == 177 || cell.CellStyle.DataFormat == 178 || cell.CellStyle.DataFormat == 188)drNew[j] = cell.NumericCellValue.ToString("#0.00");}catch{try{drNew[j] = cell.StringCellValue;}catch { }}break;default:drNew[j] = cell.StringCellValue;break;}}}}dt.Rows.Add(drNew);}return dt;}/// <summary>/// 由DataTable导出Excel/// </summary>/// <param name="sourceTable">要导出数据的DataTable</param>/// <returns>Excel工作表</returns>public static string ExportToExcel(DataTable sourceTable, string sheetName = "result", string filePath = null){if (sourceTable.Rows.Count <= 0) return null;if (string.IsNullOrEmpty(filePath)){filePath = GetSaveFilePath();}if (string.IsNullOrEmpty(filePath)) return null;bool isCompatible = GetIsCompatible(filePath);IWorkbook workbook = CreateWorkbook(isCompatible);ICellStyle cellStyle = GetCellStyle(workbook);ISheet sheet = workbook.CreateSheet(sheetName);IRow headerRow = sheet.CreateRow(0);// handling header.foreach (DataColumn column in sourceTable.Columns){ICell headerCell = headerRow.CreateCell(column.Ordinal);headerCell.SetCellValue(column.ColumnName);headerCell.CellStyle = cellStyle;}// handling value.int rowIndex = 1;foreach (DataRow row in sourceTable.Rows){IRow dataRow = sheet.CreateRow(rowIndex);foreach (DataColumn column in sourceTable.Columns){dataRow.CreateCell(column.Ordinal).SetCellValue((row[column] ?? "").ToString());}rowIndex++;}FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);workbook.Write(fs);fs.Dispose();sheet = null;headerRow = null;workbook = null;return filePath;}/// <summary>/// 由List导出Excel/// </summary>/// <typeparam name="T">类型</typeparam>/// <param name="data">在导出的List</param>/// <param name="sheetName">sheet名称</param>/// <returns></returns>public static string ExportToExcel<T>(List<T> data, IList<KeyValuePair<string, string>> headerNameList, string sheetName = "result", string filePath = null) where T : class{if (data.Count <= 0) return null;if (string.IsNullOrEmpty(filePath)){filePath = GetSaveFilePath();}if (string.IsNullOrEmpty(filePath)) return null;bool isCompatible = GetIsCompatible(filePath);IWorkbook workbook = CreateWorkbook(isCompatible);ICellStyle cellStyle = GetCellStyle(workbook);ISheet sheet = workbook.CreateSheet(sheetName);IRow headerRow = sheet.CreateRow(0);for (int i = 0; i < headerNameList.Count; i++){ICell cell = headerRow.CreateCell(i);cell.SetCellValue(headerNameList[i].Value);cell.CellStyle = cellStyle;}Type t = typeof(T);int rowIndex = 1;foreach (T item in data){IRow dataRow = sheet.CreateRow(rowIndex);for (int n = 0; n < headerNameList.Count; n++){object pValue = t.GetProperty(headerNameList[n].Key).GetValue(item, null);dataRow.CreateCell(n).SetCellValue((pValue ?? "").ToString());}rowIndex++;}FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);workbook.Write(fs);fs.Dispose();sheet = null;headerRow = null;workbook = null;return filePath;}/// <summary>/// 由DataGridView导出Excel/// </summary>/// <param name="grid"></param>/// <param name="sheetName"></param>/// <param name="filePath"></param>/// <returns></returns>public static string ExportToExcel(DataGridView grid, string sheetName = "result", string filePath = null){if (grid.Rows.Count <= 0) return null;if (string.IsNullOrEmpty(filePath)){filePath = GetSaveFilePath();}if (string.IsNullOrEmpty(filePath)) return null;bool isCompatible = GetIsCompatible(filePath);IWorkbook workbook = CreateWorkbook(isCompatible);ICellStyle cellStyle = GetCellStyle(workbook);ISheet sheet = workbook.CreateSheet(sheetName);IRow headerRow = sheet.CreateRow(0);for (int i = 0; i < grid.Columns.Count; i++){ICell cell = headerRow.CreateCell(i);cell.SetCellValue(grid.Columns[i].HeaderText);cell.CellStyle = cellStyle;}int rowIndex = 1;foreach (DataGridViewRow row in grid.Rows){IRow dataRow = sheet.CreateRow(rowIndex);for (int n = 0; n < grid.Columns.Count; n++){dataRow.CreateCell(n).SetCellValue((row.Cells[n].Value ?? "").ToString());}rowIndex++;}AutoColumnWidth(sheet, headerRow.LastCellNum - 1);FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);workbook.Write(fs);fs.Dispose();sheet = null;headerRow = null;workbook = null;MessageBox.Show("文件: " + filePath + ".xls 保存成功", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);return filePath;}#endregion/// <summary>/// 自适应列宽/// </summary>/// <param name="sheet"></param>/// <param name="cols"></param>public static void AutoColumnWidth(ISheet sheet, int cols)//获取当前列的宽度,然后对比本列的长度,取最大值{for (int col = 0; col <= cols; col++){sheet.AutoSizeColumn(col);//自适应宽度,但是其实还是比实际文本要宽int columnWidth = sheet.GetColumnWidth(col) / 256;//获取当前列宽度for (int rowIndex = 1; rowIndex <= sheet.LastRowNum; rowIndex++){IRow row;//当前行未被使用过if (sheet.GetRow(rowIndex) == null){row = sheet.CreateRow(rowIndex);}else{row = sheet.GetRow(rowIndex);}if (row.GetCell(col) != null){ICell cell = row.GetCell(col);int contextLength = Encoding.UTF8.GetBytes(cell.ToString()).Length;//获取当前单元格的内容宽度columnWidth = columnWidth < contextLength ? contextLength : columnWidth;}}sheet.SetColumnWidth(col, columnWidth * 256);//需要注意的是列的宽度为 列宽*256,所以获得的宽度需要处以256得到真实的宽度,同样再设置的时候需要再乘上256才能得到正确的值}}#region 公共导入方法/// <summary>/// 由Excel导入DataTable/// </summary>/// <param name="excelFileStream">Excel文件流</param>/// <param name="sheetName">Excel工作表名称</param>/// <param name="headerRowIndex">Excel表头行索引</param>/// <param name="isCompatible">是否为兼容模式</param>/// <returns>DataTable</returns>public static DataTable ImportFromExcel(Stream excelFileStream, string sheetName, int headerRowIndex, bool isCompatible){IWorkbook workbook = CreateWorkbook(isCompatible, excelFileStream);ISheet sheet = null;int sheetIndex = -1;if (int.TryParse(sheetName, out sheetIndex)){sheet = workbook.GetSheetAt(sheetIndex);}else{sheet = workbook.GetSheet(sheetName);}DataTable table = GetDataTableFromSheet(sheet, headerRowIndex);excelFileStream.Close();workbook = null;sheet = null;return table;}/// <summary>/// 由Excel导入DataTable/// </summary>/// <param name="excelFilePath">Excel文件路径,为物理路径。</param>/// <param name="sheetName">Excel工作表名称</param>/// <param name="headerRowIndex">Excel表头行索引</param>/// <returns>DataTable</returns>public static DataTable ImportFromExcel(string excelFilePath, string sheetName, int headerRowIndex){using (FileStream stream = System.IO.File.OpenRead(excelFilePath)){bool isCompatible = GetIsCompatible(excelFilePath);return ImportFromExcel(stream, sheetName, headerRowIndex, isCompatible);}}/// <summary>/// 由Excel导入DataSet,如果有多个工作表,则导入多个DataTable/// </summary>/// <param name="excelFileStream">Excel文件流</param>/// <param name="headerRowIndex">Excel表头行索引</param>/// <param name="isCompatible">是否为兼容模式</param>/// <returns>DataSet</returns>public static DataSet ImportFromExcel(Stream excelFileStream, int headerRowIndex, bool isCompatible){DataSet ds = new DataSet();IWorkbook workbook = CreateWorkbook(isCompatible, excelFileStream);for (int i = 0; i < workbook.NumberOfSheets; i++){ISheet sheet = workbook.GetSheetAt(i);DataTable table = GetDataTableFromSheet(sheet, headerRowIndex);ds.Tables.Add(table);}excelFileStream.Close();workbook = null;return ds;}/// <summary>/// 由Excel导入DataSet,如果有多个工作表,则导入多个DataTable/// </summary>/// <param name="excelFilePath">Excel文件路径,为物理路径。</param>/// <param name="headerRowIndex">Excel表头行索引</param>/// <returns>DataSet</returns>public static DataSet ImportFromExcel(string excelFilePath, int headerRowIndex){using (FileStream stream = System.IO.File.OpenRead(excelFilePath)){bool isCompatible = GetIsCompatible(excelFilePath);return ImportFromExcel(stream, headerRowIndex, isCompatible);}}#endregion#region 公共转换方法/// <summary>/// 将Excel的列索引转换为列名,列索引从0开始,列名从A开始。如第0列为A,第1列为B.../// </summary>/// <param name="index">列索引</param>/// <returns>列名,如第0列为A,第1列为B...</returns>public static string ConvertColumnIndexToColumnName(int index){index = index + 1;int system = 26;char[] digArray = new char[100];int i = 0;while (index > 0){int mod = index % system;if (mod == 0) mod = system;digArray[i++] = (char)(mod - 1 + 'A');index = (index - 1) / 26;}StringBuilder sb = new StringBuilder(i);for (int j = i - 1; j >= 0; j--){sb.Append(digArray[j]);}return sb.ToString();}/// <summary>/// 转化日期/// </summary>/// <param name="date">日期</param>/// <returns></returns>public static DateTime ConvertDate(object date){string dtStr = (date ?? "").ToString();DateTime dt = new DateTime();if (DateTime.TryParse(dtStr, out dt)){return dt;}try{string spStr = "";if (dtStr.Contains("-")){spStr = "-";}else if (dtStr.Contains("/")){spStr = "/";}string[] time = dtStr.Split(spStr.ToCharArray());int year = Convert.ToInt32(time[2]);int month = Convert.ToInt32(time[0]);int day = Convert.ToInt32(time[1]);string years = Convert.ToString(year);string months = Convert.ToString(month);string days = Convert.ToString(day);if (months.Length == 4){dt = Convert.ToDateTime(date);}else{string rq = "";if (years.Length == 1){years = "0" + years;}if (months.Length == 1){months = "0" + months;}if (days.Length == 1){days = "0" + days;}rq = "20" + years + "-" + months + "-" + days;dt = Convert.ToDateTime(rq);}}catch{throw new Exception("日期格式不正确,转换日期失败!");}return dt;}/// <summary>/// 转化数字/// </summary>/// <param name="d">数字字符串</param>/// <returns></returns>public static decimal ConvertDecimal(object d){string dStr = (d ?? "").ToString();decimal result = 0;if (decimal.TryParse(dStr, out result)){return result;}else{throw new Exception("数字格式不正确,转换数字失败!");}}#endregion}
}

C# EXCEL的帮助类,仅使用NPOI,不用安装Office相关推荐

  1. .net excel导入mysql_.NET Core使用NPOI将Excel中的数据批量导入到MySQL - 追逐时光者 - 博客园...

    前言: 在之前的几篇博客中写过.NET Core使用NPOI导出Word和Excel的文章,今天把同样我们日常开发中比较常用的使用Excel导入数据到MySQL数据库中的文章给安排上.与此同时还把NP ...

  2. 一个Excel的帮助类——ExcelHelper

    近日突发奇想,封装一个Excel的帮助类,好让日后做一些Excel操作时方便一点,至少导入导出会方便点吧.不过在封装过程中发现自己太差劲了,问题多多,搞这么百来行代码花了很长时间,于是写篇日志,记录一 ...

  3. 服务器端打开excel 检索 COM 类工厂 错误: 80070005

    检索 COM 类工厂中 CLSID 为{00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005. 具体解决方法如下: 1:在服 ...

  4. DataGrid 导出到 Excel 的帮助类

    DataGrid 导出到 Excel 的帮助类 //========================================================================== ...

  5. asp.net 读取excel文件的一些方法,NPOI方法

    第一种:传统方法,采用OleDB读取EXCEL文件, 优点,写法简单,老式.缺点 :服务器必须有安装此组建,而且版本必须兼容,否则读取报错,不推荐使用. private DataSet GetConn ...

  6. java读写excel文件poi_Java利用POI读写Excel文件工具类

    本文实例为大家分享了Java读写Excel文件工具类的具体代码,供大家参考,具体内容如下 package com.test.app.utils; import java.io.File; import ...

  7. C#导入导出数据到Excel的通用类源码

    下面内容是关于C#导入导出数据到Excel的通用类的内容. public class ExcelIO { private int _ReturnStatus; private string _Retu ...

  8. php中访问excel文件,PHP中常用的Excel文件访问类及修改 | 学步园

    近日,由于手头项目需要解析web提交的excel文件,不得不看看这个在php中使用比较广泛的excel访问类了.之所以说它使用广泛,是后来在网上查找问题解决方法时才知道它的使用面的. 首先说遇到的问题 ...

  9. epplus word html,.Net开源Excel、Word操作组件-NPOI、EPPlus、DocX

    一.NPOI 简介: NPOI is the .NET version of POI Java project. With NPOI, you can read/write Office 2003/2 ...

  10. 解决导出Excel报COM类工厂错误的办法--修改版

    解决导出Excel报COM类工厂错误的办法 1.问题现象 (1)第一种:销售模板的一些报表(如日报.月报等)导出时提示如下信息 (2)第二种:有些模块的一些报表导出时,没有反应,前后台也没报错 如成本 ...

最新文章

  1. html-文本框和单选框
  2. 教你用Python制作一款自己的杀毒程序
  3. Linux Socket C语言网络编程:Select Socket
  4. Effective C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝
  5. (二)匈牙利算法简介
  6. 构建之法读书笔记05
  7. WordPress中文SEO优化建议
  8. 禁忌搜索算法c语言代码,禁忌搜索算法
  9. 模拟登陆115网盘(MFC版)
  10. 关于 Windows 设置tomcat开机自动启动
  11. HTML5学习01-基础讲解、新特性
  12. 在Python中使用HTML模版的教程
  13. 最适合程序猿的个性签名
  14. 画环形或者蚊香线圈的软件介绍以及使用笔记
  15. android 手机充电慢,导致手机充电太慢的四大原因及解决方法【图文教程】
  16. 事理图谱-下一代知识图谱
  17. 百度广告投放决定排名的因素!在百度推广广告有效果吗?
  18. 数据分析实战项目--天猫交易数据可视化分析
  19. 解密宜人贷:科技驱动金融创新
  20. 医疗条码打印机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)

热门文章

  1. 【Salesforce】地理位置情報項目を使って周辺検索 GMaps
  2. HTTP Security Header Not Detected
  3. NFT平台开发部署应该选择哪条区块链?
  4. Python Scrapy爬虫报错-Spider error processing
  5. TOEFL wordlist 24
  6. session的钝化和session的活化(序列化和反序列化)
  7. 计算机学院三行情书,【计算机·头条】“当你老了”三行情书颁奖晚会
  8. 获取驱动失败Java连接数据库,好哀伤,java连接sql数据库加载驱动就是失败了
  9. 二本学生四年的求职经历
  10. 2022茶艺师(中级)考题及模拟考试