zoukankan      html  css  js  c++  java
  • 另一个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 3624 Charm Bracelet (01背包)
    51Nod 1085 背包问题 (01背包)
    POJ 1789 Truck History (Kruskal 最小生成树)
    HDU 1996 汉诺塔VI
    HDU 2511 汉诺塔X
    HDU 2175 汉诺塔IX (递推)
    HDU 2077 汉诺塔IV (递推)
    HDU 2064 汉诺塔III (递推)
  • 原文地址:https://www.cnblogs.com/HopeGi/p/2969751.html
Copyright © 2011-2022 走看看