首页 > 另一个ExcelHelper

另一个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         /// 
  8         /// 数据导出
  9         /// 
 10         /// 导出到的文件全名
 11         /// 数据表DataTable
 12         /// 是否生产表头
 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         /// 
 27         /// 数据导出(生产表头)
 28         /// 
 29         /// 导出到的文件全名
 30         /// 数据表DataTable
 31         public static void ExportExcel(string fileName, DataTable table)
 32         {
 33             ExportExcel(fileName, table, true);
 34         }
 35 
 36         #endregion
 37 
 38         #region 导入
 39 
 40         /// 
 41         /// 数据导入
 42         /// 
 43         /// 导入的文件全名
 44         /// 需要生产表头
 45         /// 导入结果
 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         /// 
 60         /// 数据导入(要生成表头)
 61         /// 
 62         /// 导入的文件全名
 63         /// 导入结果
 64         public static DataTable ImportExcel(string fileName)
 65         {
 66             return ImportExcel(fileName, true);
 67         }
 68 
 69         #endregion
 70 
 71         #region 通用编辑
 72 
 73         /// 
 74         /// 编辑Excel文档。检查不了文件则不保存,检查不了工作表则新建,覆盖编辑
 75         /// 
 76         /// 文件全名
 77         /// 工作表名
 78         /// 数据表DataTable
 79         /// 起始的单元格 如 "A1"
 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         /// 
132         /// 编辑Excel文档
133         /// 
134         /// 文件全名
135         /// 工作表名
136         /// 数据表DataTable
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         /// 
147         /// 读取Excel文档
148         /// 
149         /// 文件全名
150         /// 工作表名
151         /// 起始单元格 如 "A1",缺省填 ""或 null
152         /// 终止单元格 如 "A1",缺省填 ""或 null
153         /// 读取结果
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         /// 
195         /// 读取Excel文档
196         /// 
197         /// 文件全名
198         /// 工作表名
199         /// 读取结果
200         public static DataTable ReadExcel(string fileName, string sheetName)
201         {
202             return ReadExcel(fileName, sheetName, "", "",true);
203         }
204 
205         /// 
206         /// 读取Excel文档
207         /// 
208         /// 文件全名
209         /// 工作表索引
210         /// 起始单元格 如 "A1",缺省填 ""或 null
211         /// 终止单元格 如 "A1",缺省填 ""或 null
212         /// 读取结果
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         /// 
254         /// 读取Excel文档
255         /// 
256         /// 文件全名
257         /// 工作表索引
258         /// 读取结果
259         public static DataTable ReadExcel(string fileName, int sheetIndex)
260         {
261             return ReadExcel(fileName, sheetIndex,"","",true);
262         }
263 
264         /// 
265         /// 读取Excel文档
266         /// 
267         /// 文件全名
268         /// 读取结果
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         /// 
281         /// 检查文件是否存在,若不存在则会先确保文件所在的目录存在
282         /// 
283         /// 文件名
284         /// 检查结果
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         /// 
295         /// 转换单元格位置
296         /// 
297         /// 单元格位置
298         /// int二元组
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         /// 
320         /// 获取工作表指定区域最宽的列数
321         /// 
322         /// ISheet工作表对象
323         /// 开始行数
324         /// 终结行数
325         /// 工作表最宽的列数
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         /// 
341         /// 读取工作表指定区域的内容
342         /// 
343         /// ISheet工作表对象
344         /// 起始单元格 
345         /// 终止单元格
346         /// 读取结果
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
372             {
373                 if (row == null)continue; 
374                 List 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         /// 
418         /// 重计算工作表
419         /// 
420         /// 
421         /// 
422         private static void EvaluateSheet(IWorkbook workBook, ISheet sheet)
423         {
424             HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workBook);
425             IRow row;
426             List 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     }

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

更多相关:

  • 有时候我们项目,在执行某个操作后,会生成一些数据结果,如报表一类的东西,我们需要对结果进行保存,甚至是生成word文档。 那么首先获取到控件快照就最基本的条件。 生成快照的静态方法类 using System; using System.Collections.Generic; using System.Drawing; using...

  • 作用批量执行sql语句 表达式.RunSQL(SQLStatement,UseTransaction) 表达式.一个代表DoCmd对象的变量。 注释:sqlstatement参数的最大长度为 32,768 个字符(而"宏"窗口中的 SQL 语句操作参数的最大长度为 256 个字符)。      官方说仅能用于Microsoft Acc...

  • 前戏:针对上一篇列出来的功能点,今天和大家分享下这个自定义的公式是怎么设计的,由于我的第一篇博客在首页被管理员移走了,大家可以点击这里来跳转,看下第一篇的目录结构。本人作为老菜鸟,和大家分享的也是一些老菜鸟的想法,大神千万别喷我.   设计背景:当初为什么要设计这个自定义的计算公式呢,原因就是,这个价格是不确定的,计算方式也是不确定的...

  • 背景 搭建一个适合公司erp业务的开发平台。 架构概要图:    流程引擎开发平台:  包含流程引擎设计器,流程管理平台,流程引擎服务。目前只使用单个数据库进行管理。  流程引擎设计器    采用silverlight进行开发,本质是对流程模型进行设计,并生成xml。包含:人工节点,自动节点,并行开始节点,并行结束节点,消息节点,文...

  • using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml;using System.Web; namespace BLL{    public  class XmlDoc    {       ...

  • head 看文件的前100行head -100  filename   tail/tailf查看文件的后100行tail -100  filename 或 tail -n 100  filename tailf filename == tail -f filename   sed sed -n '100,200p' filename...

  • public static void down(HttpServletRequest request,    HttpServletResponse response) throws Exception {         String name="aaa.*";//文件名   String uploadPath = UploadF...

  • 1.Scatter  从一个Channel读取的信息分散到N个缓冲区中(Buufer). 2.Gather  将N个Buffer里面内容按照顺序发送到一个Channel.       Scatter/Gather功能是通道(Channel)提供的  并不是Buffer, Scatter/Gather相关接口 类图     Re...

  • 你可能看到了表的前缀非常奇怪。Joomla将替换这个前缀,用安装时候指定的内容。对于通常的安装,这个表名将是jos_hello,这样可以多个安装使用一个数据库,并且能够避免表名冲突。 表中有两个字段,一是id,是主键,一是greeting. 以上内容保存在 install.utf.sql. 创建卸载sql文件 尽管我们希望永远不必...

  • 引言 在这个-SLAM建图和导航仿真实例-项目中,主要分为三个部分,分别是 (一)模型构建(二)根据已知地图进行定位和导航(三)使用RTAB-MAP进行建图和导航 该项目的slam_bot已经上传我的Github。 这是第三部分,完成效果如下 图1 建图和导航 三、使用RTAB-Map进行建图和导航 1. rtab...

  • 引言 在这个-SLAM建图和导航仿真实例-项目中,主要分为三个部分,分别是 (一)模型构建(二)根据已知地图进行定位和导航(三)使用RTAB-MAP进行建图和导航 该项目的slam_bot已经上传我的Github。 由于之前的虚拟机性能限制,我在这个项目中使用了新的ubantu 16.04环境,虚拟机配置 内存 8GCPU...

  • [{name:1},{name:2}].forEach((v,i,ar) => {console.log(v,i,ar)});//基础遍历[{name:1},{name:2}].map((v) => v.name);//[1,2]返回对象数组中指定字段值的一位数组(不改变原始数组)[{name:1},{name:2},{name:3}...

  • 体验内容 使用gmapping方法利用turtlebot底盘移动信息和激光雷达数据进行建图。 1. 安装一些依赖包 sudo apt-get install ros-melodic-move-base* sudo apt-get install ros-melodic-map-server* sudo apt-get insta...

  • 前言 我们知道Java/Python这种语言能够很好得 支持反射。反射机制 就是一种用户输入的字符串到对应实现方法的映射,比如http接口中 用户传入了url,我们需要调用该url对应的方法/函数对象 从而做出对应的操作。 而C++ 并没有友好得支持这样的操作,而最近工作中需要通过C++实现http接口,这个过程想要代码实现得优雅...