• 另一个ExcelHelper


    有不少园友指点,用NPOI操作Excel会比用ADO.NET 和COM 要好,于是尝试一下用NPOI封装一个ExcelHelper,在使用本类之前,要添加NPOI.dll引用。要添加两个个命名空间   

    using NPOI.SS.UserModel;

    using NPOI.HSSF.UserModel;

    类代码如下:

      1     public class NPOIExcelHelper
      2     {
      3         #region 公共方法
      4 
      5         #region 导出
      6 
      7         /// <summary>
      8         /// 数据导出
      9         /// </summary>
     10         /// <param name="fileName">导出到的文件全名</param>
     11         /// <param name="table">数据表DataTable</param>
     12         /// <param name="addHeader">是否生产表头</param>
     13         public static void ExportExcel(string fileName, DataTable table,bool addHeader)
     14         {
     15             if (addHeader)
     16             {
     17                 DataRow row = table.Rows.Add();
     18                 foreach (DataColumn col in table.Columns)
     19                     row[col] = col.ColumnName;
     20                 table.Rows.Remove(row);
     21                 table.Rows.InsertAt(row, 0);
     22             }
     23             EditExcel(fileName, "Sheet1", table, "A1");
     24         }
     25 
     26         /// <summary>
     27         /// 数据导出(生产表头)
     28         /// </summary>
     29         /// <param name="fileName">导出到的文件全名</param>
     30         /// <param name="table">数据表DataTable</param>
     31         public static void ExportExcel(string fileName, DataTable table)
     32         {
     33             ExportExcel(fileName, table, true);
     34         }
     35 
     36         #endregion
     37 
     38         #region 导入
     39 
     40         /// <summary>
     41         /// 数据导入
     42         /// </summary>
     43         /// <param name="fileName">导入的文件全名</param>
     44         /// <param name="hasHeader">需要生产表头</param>
     45         /// <returns>导入结果</returns>
     46         public static DataTable ImportExcel(string fileName,bool hasHeader)
     47         {
     48             DataTable table = ReadExcel(fileName, 0);
     49             if (hasHeader&&table.Rows.Count>0)
     50             {
     51                 DataRow row = table.Rows[0];
     52                 for (int i = 0; i < table.Columns.Count; i++)
     53                     table.Columns[i].ColumnName = table.Rows[0][i].ToString();
     54                 table.Rows.Remove(row);
     55             }
     56             return table;
     57         }
     58 
     59         /// <summary>
     60         /// 数据导入(要生成表头)
     61         /// </summary>
     62         /// <param name="fileName">导入的文件全名</param>
     63         /// <returns>导入结果</returns>
     64         public static DataTable ImportExcel(string fileName)
     65         {
     66             return ImportExcel(fileName, true);
     67         }
     68 
     69         #endregion
     70 
     71         #region 通用编辑
     72 
     73         /// <summary>
     74         /// 编辑Excel文档。检查不了文件则不保存,检查不了工作表则新建,覆盖编辑
     75         /// </summary>
     76         /// <param name="fileName">文件全名</param>
     77         /// <param name="sheetName">工作表名</param>
     78         /// <param name="table">数据表DataTable</param>
     79         /// <param name="cell">起始的单元格 如 "A1"</param>
     80         public static void EditExcel(string fileName, string sheetName, DataTable table, string cell)
     81         {
     82             IWorkbook workBook = null;
     83             ISheet sheet = null;
     84             FileStream fs = null;
     85             bool exist=false;
     86 
     87             try
     88             {
     89                 if (IsExistFile(fileName))
     90                 {
     91                     exist=true;
     92                     fs = File.Open(fileName, FileMode.Open);
     93                     workBook = new HSSFWorkbook(fs);
     94                 }
     95                 else
     96                 {
     97                     exist=false;
     98                     fs = File.Create(fileName);
     99                     fs.Close();//2013-10-6创建文件后关闭流,防止占用(有网友指出)
    100                     fs.Dispose();//2013-10-6创建文件后关闭流,防止占用(有网友指出)
    101                     workBook = new HSSFWorkbook();
    102                 }
    103                 sheet = workBook.GetSheet(sheetName);
    104                 if (sheet == null)
    105                     sheet = workBook.CreateSheet(sheetName);
    106 
    107                 Tuple<int, int> cellIndex = ConvertCell(cell);
    108 
    109                 IRow eRow = null;
    110                 foreach (DataRow row in table.Rows)
    111                 {
    112                     eRow = sheet.CreateRow(table.Rows.IndexOf(row) + cellIndex.Item1);
    113                     for (int c = 0; c < table.Columns.Count; c++)
    114                         eRow.CreateCell(c).SetCellValue(row[c].ToString());
    115                 }
    116 
    117                 fs = File.OpenWrite(fileName);
    118                 workBook.Write(fs);
    119             }
    120             catch (Exception e)
    121             {
    122 
    123                 throw e;
    124             }
    125             finally
    126             {
    127                 if (fs != null) fs.Close();
    128             }
    129         }
    130 
    131         /// <summary>
    132         /// 编辑Excel文档
    133         /// </summary>
    134         /// <param name="fileName">文件全名</param>
    135         /// <param name="sheetName">工作表名</param>
    136         /// <param name="table">数据表DataTable</param>
    137         public static void EditExcel(string fileName, string sheetName, DataTable table)
    138         {
    139             EditExcel(fileName, sheetName, table, "A1");
    140         }
    141 
    142         #endregion
    143 
    144         #region 通用读取
    145 
    146         /// <summary>
    147         /// 读取Excel文档
    148         /// </summary>
    149         /// <param name="fileName">文件全名</param>
    150         /// <param name="sheetName">工作表名</param>
    151         /// <param name="startCell">起始单元格 如 "A1",缺省填 ""或 null</param>
    152         /// <param name="endCell">终止单元格 如 "A1",缺省填 ""或 null</param>
    153         /// <returns>读取结果</returns>
    154         public static DataTable ReadExcel(string fileName, string sheetName, string startCell,string endCell,bool evaluateAll)
    155         {
    156             DataTable table = null;
    157 
    158             if (!File.Exists(fileName))
    159                 throw new Exception("文件不存在");
    160 
    161             IWorkbook workBook = null;
    162             ISheet sheet = null;
    163             FileStream fs = null;
    164 
    165             try
    166             {
    167                 fs=File.OpenRead(fileName);
    168                 workBook = new HSSFWorkbook(fs);
    169                 sheet = workBook.GetSheet(sheetName);
    170 
    171                 if (sheet == null)
    172                     throw new Exception("工作表不存在");
    173                 if (evaluateAll)//2013-9-6 重计算
    174                 {
    175                     //HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workBook);
    176                     //eva.EvaluateAll();
    177                     EvaluateSheet(workBook, sheet);//2013-10-14 逐个重计算
    178                 }
    179                 table = ReadSheet(sheet, startCell, endCell);
    180             }
    181             catch (Exception e)
    182             {
    183 
    184                 throw e;
    185             }
    186             finally
    187             {
    188                 if (fs != null) fs.Close();
    189             }
    190 
    191             return table;
    192         }
    193 
    194         /// <summary>
    195         /// 读取Excel文档
    196         /// </summary>
    197         /// <param name="fileName">文件全名</param>
    198         /// <param name="sheetName">工作表名</param>
    199         /// <returns>读取结果</returns>
    200         public static DataTable ReadExcel(string fileName, string sheetName)
    201         {
    202             return ReadExcel(fileName, sheetName, "", "",true);
    203         }
    204 
    205         /// <summary>
    206         /// 读取Excel文档
    207         /// </summary>
    208         /// <param name="fileName">文件全名</param>
    209         /// <param name="sheetIndex">工作表索引</param>
    210         /// <param name="startCell">起始单元格 如 "A1",缺省填 ""或 null</param>
    211         /// <param name="endCell">终止单元格 如 "A1",缺省填 ""或 null</param>
    212         /// <returns>读取结果</returns>
    213         public static DataTable ReadExcel(string fileName, int sheetIndex, string startCell, string endCell, bool evaluateAll)
    214         {
    215             DataTable table = null;
    216 
    217             if (!File.Exists(fileName))
    218                 throw new Exception("文件不存在");
    219 
    220             IWorkbook workBook = null;
    221             ISheet sheet = null;
    222             FileStream fs = null;
    223 
    224             try
    225             {
    226                 fs = File.OpenRead(fileName);
    227                 workBook = new HSSFWorkbook(fs);
    228                 sheet = workBook.GetSheetAt(sheetIndex);
    229 
    230                 if (sheet == null)
    231                     throw new Exception("工作表不存在");
    232                 if (evaluateAll)//2013-9-6 重计算
    233                 {
    234                     //HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workBook);
    235                     //eva.EvaluateAll();
    236                     EvaluateSheet(workBook, sheet);//2013-10-14 逐个重计算
    237                 }
    238                 table = ReadSheet(sheet, startCell, endCell);
    239             }
    240             catch (Exception e)
    241             {
    242 
    243                 throw e;
    244             }
    245             finally
    246             {
    247                 if (fs != null) fs.Close();
    248             }
    249 
    250             return table;
    251         }
    252 
    253         /// <summary>
    254         /// 读取Excel文档
    255         /// </summary>
    256         /// <param name="fileName">文件全名</param>
    257         /// <param name="sheetIndex">工作表索引</param>
    258         /// <returns>读取结果</returns>
    259         public static DataTable ReadExcel(string fileName, int sheetIndex)
    260         {
    261             return ReadExcel(fileName, sheetIndex,"","",true);
    262         }
    263 
    264         /// <summary>
    265         /// 读取Excel文档
    266         /// </summary>
    267         /// <param name="fileName">文件全名</param>
    268         /// <returns>读取结果</returns>
    269         public static DataTable ReadExcel(string fileName)
    270         {
    271             return ReadExcel(fileName, 0);
    272         }
    273 
    274         #endregion
    275 
    276         #endregion
    277 
    278         #region 内部辅助方法
    279 
    280         /// <summary>
    281         /// 检查文件是否存在,若不存在则会先确保文件所在的目录存在
    282         /// </summary>
    283         /// <param name="fileName">文件名</param>
    284         /// <returns>检查结果</returns>
    285         private static bool IsExistFile(string fileName)
    286         {
    287             if (File.Exists(fileName)) return true;
    288             string path = fileName.Substring(0, fileName.LastIndexOf('\\') + 1).Trim('\\');
    289             if (!Directory.Exists(path))
    290                 Directory.CreateDirectory(path);
    291             return false;
    292         }
    293 
    294         /// <summary>
    295         /// 转换单元格位置
    296         /// </summary>
    297         /// <param name="cell">单元格位置</param>
    298         /// <returns>int二元组</returns>
    299         private static Tuple<int, int> ConvertCell(string cell)
    300         {
    301             Match colM = Regex.Match(cell, @"[a-zA-Z]+");
    302             if (string.IsNullOrEmpty(colM.Value))
    303                 throw new Exception("单元格格式有误!");
    304             string colStr = colM.Value.ToUpper();
    305             int colIndex = 0;
    306             foreach (char ci in colStr)
    307                 colIndex += ci - 'A';
    308             //colIndex += 1 + (ci - 'A');
    309 
    310             Match rowM = Regex.Match(cell, @"\d+");
    311             if (string.IsNullOrEmpty(rowM.Value))
    312                 throw new Exception("单元格格式有误!");
    313             int rowIndex = Convert.ToInt32(rowM.Value)-1;
    314 
    315             Tuple<int, int> result = new Tuple<int, int>(rowIndex, colIndex);
    316             return result;
    317         }
    318 
    319         /// <summary>
    320         /// 获取工作表指定区域最宽的列数
    321         /// </summary>
    322         /// <param name="sheet">ISheet工作表对象</param>
    323         /// <param name="startRowIndex">开始行数</param>
    324         /// <param name="toRowIndex">终结行数</param>
    325         /// <returns>工作表最宽的列数</returns>
    326         private static int GetLastCell(ISheet sheet, int startRowIndex,int toRowIndex)
    327         {
    328             int result = 0;
    329             for (int i = startRowIndex; i < toRowIndex; i++)
    330             {
    331                 IRow row = sheet.GetRow(i);
    332                 if (row == null) continue; //2013-9-5防止空引用异常
    333                 int temp = row.Cells.Count;
    334                 if (temp > result) result = temp;
    335             }
    336 
    337             return result;
    338         }
    339 
    340         /// <summary>
    341         /// 读取工作表指定区域的内容
    342         /// </summary>
    343         /// <param name="sheet">ISheet工作表对象</param>
    344         /// <param name="startCell">起始单元格 </param>
    345         /// <param name="endCell">终止单元格</param>
    346         /// <returns>读取结果</returns>
    347         private static DataTable ReadSheet(ISheet sheet, string startCell, string endCell)
    348         {
    349             DataTable table = new DataTable();
    350 
    351             Tuple<int, int> sCellIndex;
    352             if (!string.IsNullOrEmpty(startCell))
    353                 sCellIndex = ConvertCell(startCell);
    354             else
    355                 sCellIndex = new Tuple<int, int>(0, 0);
    356 
    357             Tuple<int, int> eCellIndex;
    358             if (!string.IsNullOrEmpty(endCell))
    359                 eCellIndex = ConvertCell(endCell);
    360             else
    361             {
    362                 int lastIndex = sheet.LastRowNum;
    363                 eCellIndex = new Tuple<int, int>(lastIndex, GetLastCell(sheet, sCellIndex.Item1, lastIndex));
    364             }
    365 
    366             IRow row = sheet.GetRow(sCellIndex.Item1);
    367             int rowIndex = 0;
    368             //sheet.ForceFormulaRecalculation = true;
    369             //while (row != null )
    370 
    371             for (; rowIndex <= sheet.LastRowNum;  row = sheet.GetRow(sCellIndex.Item1 + rowIndex+1),rowIndex++) //2013-9-5 rowIndex<sheet.LastRowNum 使其有效范围扩大
    372             {
    373                 if (row == null)continue; 
    374                 List<ICell> cellList = row.Cells;
    375                 DataRow dtRow = table.Rows.Add();
    376                 for (int i = 0; i < cellList.Count; i++)
    377                 {
    378                     while (table.Columns.Count < i + 1) //2013-9-6 加一列5够的,要加到够为止
    379                         table.Columns.Add();
    380 
    381                     dtRow[cellList[ i].ColumnIndex] = TryGetCellValue(cellList[i]);//2013-9-5 获得正确的数据类型的数值
    382                     //2013-10-6 填到正确的列里面
    383                 }
    384                 //row = sheet.GetRow(sCellIndex.Item1 + rowIndex);
    385                 //rowIndex++;
    386             }
    387 
    388             return table;
    389         }
    390 
    391 
    392         private static object TryGetCellValue(ICell cell)
    393         {
    394             try
    395             {
    396                 return cell.StringCellValue;
    397             }
    398             catch { }
    399             try
    400             {
    401                 return cell.RichStringCellValue;
    402             }
    403             catch { }
    404             try
    405             {
    406                 return cell.NumericCellValue;
    407             }
    408             catch { }
    409             try
    410             {
    411                 return cell.DateCellValue;
    412             }
    413             catch { }
    414             return cell;
    415         }
    416 
    417         /// <summary>
    418         /// 重计算工作表
    419         /// </summary>
    420         /// <param name="workBook"></param>
    421         /// <param name="sheet"></param>
    422         private static void EvaluateSheet(IWorkbook workBook, ISheet sheet)
    423         {
    424             HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workBook);
    425             IRow row;
    426             List<ICell> cellList;
    427             for (int i = 0; i < sheet.LastRowNum; i++)
    428             {
    429                 row = sheet.GetRow(i);
    430                 if (row == null) continue;
    431                 cellList = row.Cells;
    432                 foreach (ICell cell in cellList)
    433                 {
    434                     try
    435                     {
    436                         eva.EvaluateInCell(cell);
    437                     }
    438                     catch { }
    439                 }
    440             }
    441         }
    442 
    443         #endregion
    444     }

    上述代码在经网友指出错误后更改,还有本人在使用过程对功能欠缺的作了一些补充

  • 相关阅读:
    poj 1014||hdu 1059 dividing(多重背包 二进制优化)
    Java多线程循环打印ABC的5种实现方法
    java资料搜索网站
    idea 离线安装 lombok插件
    解决TIME_WAIT过多造成的问题
    JAVA线程池详解
    linux vmstat命令
    Mysql慢查询
    sql中强制使用索引
    JAVA 利用 jmc或jvisualvm 监控 本地或者远程JVM
  • 原文地址:https://www.cnblogs.com/HopeGi/p/2969751.html
Copyright © 2020-2023  润新知