NPOI操作 EXCEL文件

NPOI 1.2.4/1.2.5 官方教程 http://tonyqus.sinaapp.com/tutorial

解压开 BinaryRelease.zip,并在项目中引用

image

image

丢一个excel文档在项目里面,我们读取试试

 

GetCell(i).CellType的数字值所代表的含义

CELL_TYPE_NUMERIC = 0;    CELL_TYPE_STRING = 1     CELL_TYPE_FORMULA = 2

CELL_TYPE_BLANK = 3         CELL_TYPE_BOOLEAN = 4      CELL_TYPE_ERROR = 5

 

0:HSSFCell.CELL_TYPE_NUMERIC 数字  例如 0

1:HSSFCell.CELL_TYPE_STRING  字符串  例如 “hellow”,但是例如下面的第二行第二列,看起来是120是个数字,但是NPOI判断出来,还是一个字符串,值是 “40+40+40”,这样的该如何解决呢?(后面有解决方法,就是把他当做算式给计算出来)

image

2:HSSFCell.CELL_TYPE_FORMULA  公式。例如下面的

image

值是 SUM(B2:C2)

 

3:HSSFCell.CELL_TYPE_BLANK  空白或者为空

 

在通过NPOI组件读取excel的过程中,发现,如果你在Excel里面是

image

但是读取出来之后,是这个样子,金额120,分别变成了 40+40+40,汇总(我使用的是公式),变成了Sum··,而更离谱的是时间,居然变成了 科学计数法,而且NPOI判断是不是bool类型,不是看是1还是0,而是看True和False

image 

我们可以在代码里面,对公式进行 try catch一下,如果公式能转变成数字,就获取数字

然后我们的公式,就都变成了数字,

 image

但是很奇怪,里面的时间,还是用的科学计数法,既然是个数字类型,我们能不能把数字类型,变成时间呢?是可以的,看下面的图,我们就能看到这个列,用数字值表示就是 41067.····,但是用时间值表示就是 2012/6/7 7:33:15

37%9%Y0KO99PNJO%IWI`XJA

然后我们对所有的数字,进行了try catch来转换,结果出糗了,很多数字都变成了时间了,如下图。

image

 

到目前为止的代码如下,这个是不太正确的代码,虽然他把公式算成了数字(用的是

 1:  case HSSFCell.CELL_TYPE_FORMULA:    //2代表 公式   
 2:                                  try
 3:                                  {
 4:                                      cellvalue = cell.NumericCellValue;
 5:                                  }
 6:                                  catch (Exception)
 7:                                  {
 8:                                      cellvalue = cell.CellFormula;
 9:                                  }
10:   
11:                                  break;
12:   

 

  但是后面把数字变成了时间还是有错误的,

 1:  case HSSFCell.CELL_TYPE_NUMERIC:    //0代表数字
 2:                                  try//数字的可能是日期的
 3:                                  {
 4:                                      cellvalue = cell.DateCellValue;
 5:                                  }
 6:                                  catch (Exception)
 7:                                  {
 8:   
 9:                                      cellvalue = cell.NumericCellValue;
10:                                  }
11:   
12:                                  break;
13:   

 

到目前为止,还有些错误的代码,如下

 1:  using (Stream stream = File.Open(Server.MapPath(@"upload\jiaban.xls"), FileMode.Open))
 2:              {
 3:                  HSSFWorkbook book = new HSSFWorkbook(stream);
 4:   
 5:                  HSSFSheet sheet = book.GetSheet("加班第一天");
 6:                  HSSFRow row = sheet.GetRow(1);
 7:                  //List<string> rowTitle =new List<string>();
 8:                  ArrayList rowTitle = new ArrayList();
 9:                  object cellvalue = null;
10:                  for (int i = 0; i < row.LastCellNum; i++)
11:                  {
12:                      if (row.GetCell(i)!=null)
13:                      {
14:                          HSSFCell cell = row.GetCell(i);
15:   
16:                          switch (cell.CellType)
17:                          {
18:                              case HSSFCell.CELL_TYPE_NUMERIC:    //0代表数字
19:                                  try//数字的可能是日期的
20:                                  {
21:                                      cellvalue = cell.DateCellValue;
22:                                  }
23:                                  catch (Exception)
24:                                  {
25:   
26:                                      cellvalue = cell.NumericCellValue;
27:                                  }
28:   
29:                                  break;
30:                              case HSSFCell.CELL_TYPE_STRING:     //1代表字符串
31:                                  try
32:                                  {
33:                                      cellvalue = cell.NumericCellValue;
34:                                  }
35:                                  catch (Exception)
36:                                  {
37:                                      cellvalue = cell.StringCellValue;
38:                                  }
39:   
40:                                  break;
41:                              case HSSFCell.CELL_TYPE_FORMULA:    //2代表 公式   
42:                                  try
43:                                  {
44:                                      cellvalue = cell.NumericCellValue;
45:                                  }
46:                                  catch (Exception)
47:                                  {
48:                                      cellvalue = cell.CellFormula;
49:                                  }
50:   
51:                                  break;
52:                              case HSSFCell.CELL_TYPE_BLANK:      //3代表 空白
53:                                  cellvalue = cell.StringCellValue;
54:                                  break;
55:                              case HSSFCell.CELL_TYPE_BOOLEAN:    //4代表 bool值
56:                                  cellvalue = cell.BooleanCellValue;
57:                                  break;
58:   
59:   
60:                              default:    //如果上面都捕抓不到,那么我们就捕获所代表的数字
61:                                  cellvalue = cell.CellType;
62:                                  break;
63:                          }
64:                          rowTitle.Add(cellvalue);
65:                      }
66:   
67:                  }
68:                  GridView1.DataSource = rowTitle;
69:                  //GridView1.DataSource = book.GetSheetName(0); //获得Excel的第一个表单的名字
70:                  GridView1.DataBind();
71:              }
72:   

 

那么我们到底要怎么来判断呢?

我暂时的想法就是,规定好客户上传的数据。或者我们自己先做一个 excel的模板,可以在office里面做,也可以在NPOI里面做,主要就是要规定行里面男的列的属性值。

 

每一个xls都对应一个唯一的HSSFWorkbook,每一个HSSFWorkbook会有若干个HSSFSheet,而每一个HSSFSheet包含若干HSSFRow(Excel 2003中不得超过65535行),每一个HSSFRow又包含若干个HSSFCell(Excel 2003中不得超过256列)。

为了遍历所有的单元格,我们就得获得某一个HSSFSheet的所有HSSFRow,通常可以用HSSFSheet.GetRowEnumerator()。如果要获得某一特定行,可以直接用HSSFSheet.GetRow(rowIndex)。另外要遍历我们就必须知道边界,有一些属性我们是可以用的,比如

HSSFSheet.FirstRowNum(工作表中第一个有数据行的行号)、HSSFSheet.LastRowNum(工作表中最后一个有数据行的行号)、HSSFRow.FirstCellNum(一行中第一个有数据列的列号)、HSSFRow.LastCellNum(一行中最后一个有数据列的列号)。

posted @ 2012-12-21 17:45  梨花驿路  阅读(800)  评论(0编辑  收藏  举报