NPOI 1.2.4/1.2.5 官方教程 http://tonyqus.sinaapp.com/tutorial
解压开 BinaryRelease.zip,并在项目中引用
丢一个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”,这样的该如何解决呢?(后面有解决方法,就是把他当做算式给计算出来)
2:HSSFCell.CELL_TYPE_FORMULA 公式。例如下面的
值是 SUM(B2:C2)
3:HSSFCell.CELL_TYPE_BLANK 空白或者为空
在通过NPOI组件读取excel的过程中,发现,如果你在Excel里面是
但是读取出来之后,是这个样子,金额120,分别变成了 40+40+40,汇总(我使用的是公式),变成了Sum··,而更离谱的是时间,居然变成了 科学计数法,而且NPOI判断是不是bool类型,不是看是1还是0,而是看True和False
我们可以在代码里面,对公式进行 try catch一下,如果公式能转变成数字,就获取数字
然后我们的公式,就都变成了数字,
但是很奇怪,里面的时间,还是用的科学计数法,既然是个数字类型,我们能不能把数字类型,变成时间呢?是可以的,看下面的图,我们就能看到这个列,用数字值表示就是 41067.····,但是用时间值表示就是 2012/6/7 7:33:15
然后我们对所有的数字,进行了try catch来转换,结果出糗了,很多数字都变成了时间了,如下图。
到目前为止的代码如下,这个是不太正确的代码,虽然他把公式算成了数字(用的是
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(一行中最后一个有数据列的列号)。