一、定义
apache poi是apache软件基金会的开放源码函式库,poi提供api给java程序对microsoft office格式档案读和写的功能。
二、所需jar包:
三、简单的一个读取excel的demo
1、读取文件方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/** * 读取出filepath中的所有数据信息 * @param filepath excel文件的绝对路径 * */ public static void getdatafromexcel(string filepath) { //string filepath = "e:\\123.xlsx"; //判断是否为excel类型文件 if (!filepath.endswith( ".xls" )&&!filepath.endswith( ".xlsx" )) { system.out.println( "文件不是excel类型" ); } fileinputstream fis = null ; workbook wookbook = null ; try { //获取一个绝对地址的流 fis = new fileinputstream(filepath); } catch (exception e) { e.printstacktrace(); } try { //2003版本的excel,用.xls结尾 wookbook = new hssfworkbook(fis); //得到工作簿 } catch (exception ex) { //ex.printstacktrace(); try { //2007版本的excel,用.xlsx结尾 wookbook = new xssfworkbook(fis); //得到工作簿 } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } //得到一个工作表 sheet sheet = wookbook.getsheetat( 0 ); //获得表头 row rowhead = sheet.getrow( 0 ); //判断表头是否正确 if (rowhead.getphysicalnumberofcells() != 3 ) { system.out.println( "表头的数量不对!" ); } //获得数据的总行数 int totalrownum = sheet.getlastrownum(); //要获得属性 string name = "" ; int latitude = 0 ; //获得所有数据 for ( int i = 1 ; i <= totalrownum ; i++) { //获得第i行对象 row row = sheet.getrow(i); //获得获得第i行第0列的 string类型对象 cell cell = row.getcell(( short ) 0 ); name = cell.getstringcellvalue().tostring(); //获得一个数字类型的数据 cell = row.getcell(( short ) 1 ); latitude = ( int ) cell.getnumericcellvalue(); system.out.println( "名字:" +name+ ",经纬度:" +latitude); } } |
2、测试
1
2
3
4
|
public static void main(string[] args) { getdatafromexcel( "e:" + file.separator + "123.xlsx" ); } |
3、原始数据
4、结果
1
2
3
4
5
6
7
8
9
10
11
|
名字:a1,经纬度: 1 名字:a2,经纬度: 2 名字:a3,经纬度: 3 名字:a4,经纬度: 4 名字:a5,经纬度: 5 名字:a6,经纬度: 6 名字:a7,经纬度: 7 名字:a8,经纬度: 8 名字:a9,经纬度: 9 名字:a10,经纬度: 10 名字:a11,经纬度: 11 |
四、注意事项
1、运用多态,excel主要有.xls结尾(2003版本)和. xlsx(2007版本)两种类型结尾的文件,分别需要用hssfworkbook对象对.xls文件进行读取,用xssfworkbook对象对.xlsx文件进行读取,直接使用他们共同的父类workbook进行初始化对象有利于代码的易用性。
2、通过流的方式初始化工作簿对象(workbook),可以通过new xssfworkbook(文件绝对路径)和new xssfworkbook(输入流)两种方式初始化对象,但是假如我们只是通过修改.xls文件的后缀名为.xlsx,这样子当我们用new xssfworkbook(文件绝对路径)来读取文件的时候就会报错,因为他本身就不是一个2007版本的excel类型的文件,读取会报错;假如我们是通过流的方式的话,可以避免这种情况,我们即使你修改了文件的后缀名,我们依然在初始化的时候能获取到该对象是.xls类型文件,使用hssfworkbook对象进行处理,即能得出正确的结果。
五、增强版
添加了判断表头是否符合规范,允许表头对象的位置不同。进行了一定的解耦合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/** * * @param cell 一个单元格的对象 * @return 返回该单元格相应的类型的值 */ public static object getrighttypecell(cell cell){ object object = null ; switch (cell.getcelltype()) { case cell.cell_type_string : { object=cell.getstringcellvalue(); break ; } case cell.cell_type_numeric : { cell.setcelltype(cell.cell_type_numeric); object=cell.getnumericcellvalue(); break ; } case cell.cell_type_formula : { cell.setcelltype(cell.cell_type_numeric); object=cell.getnumericcellvalue(); break ; } case cell.cell_type_blank : { cell.setcelltype(cell.cell_type_blank); object=cell.getstringcellvalue(); break ; } } return object; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/** * 读取出filepath中的所有数据信息 * @param filepath excel文件的绝对路径 * */ public static void getdatafromexcel2(string filepath) { list<map<string,integer>> list = new arraylist<map<string, integer>>(); //判断是否为excel类型文件 if (!filepath.endswith( ".xls" )&&!filepath.endswith( ".xlsx" )) { system.out.println( "文件不是excel类型" ); } fileinputstream fis = null ; workbook wookbook = null ; int flag = 0 ; try { //获取一个绝对地址的流 fis = new fileinputstream(filepath); } catch (exception e) { e.printstacktrace(); } try { //2003版本的excel,用.xls结尾 wookbook = new hssfworkbook(fis); //得到工作簿 } catch (exception ex) { //ex.printstacktrace(); try { //2007版本的excel,用.xlsx结尾 wookbook = new xssfworkbook(filepath); //得到工作簿 } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } //得到一个工作表 sheet sheet = wookbook.getsheetat( 0 ); //获得表头 row rowhead = sheet.getrow( 0 ); //根据不同的data放置不同的表头 map<object,integer> headmap = new hashmap<object, integer>(); //判断表头是否合格 ------------------------这里看你有多少列 if (rowhead.getphysicalnumberofcells() != 2 ) { system.out.println( "表头列数与要导入的数据库不对应" ); } try { //----------------这里根据你的表格有多少列 while (flag < 2 ) { cell cell = rowhead.getcell(flag); if (getrighttypecell(cell).tostring().equals( "基站名" )) { headmap.put( "jizhan" , flag); } if (getrighttypecell(cell).tostring().equals( "经纬度" )) { headmap.put( "jingweidu" , flag); } flag++; } } catch (exception e) { e.printstacktrace(); system.out.println( "表头不合规范,请修改后重新导入" ); } //获得数据的总行数 int totalrownum = sheet.getlastrownum(); //要获得属性 string name = "" ; double latitude = 0 ; if ( 0 == totalrownum) { system.out.println( "excel内没有数据!" ); } cell cell_1 = null ,cell_2 = null ; //获得所有数据 for ( int i = 1 ; i <= totalrownum ; i++) { //获得第i行对象 row row = sheet.getrow(i); try { cell_1 = row.getcell(headmap.get( "jizhan" )); cell_2 = row.getcell(headmap.get( "jingweidu" )); } catch (exception e) { e.printstacktrace(); system.out.println( "获取单元格错误" ); } try { //基站 name = (string) getrighttypecell(cell_1); //经纬度 latitude = ( double ) getrighttypecell(cell_2); } catch (classcastexception e) { e.printstacktrace(); system.out.println( "数据不全是数字或全部是文字!" ); } system.out.println( "名字:" +name+ ",经纬度:" +latitude); } } |
异常情况:
应将下面这段代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
try { //2003版本的excel,用.xls结尾 wookbook = new hssfworkbook(fis); //得到工作簿 } catch (exception ex) { //ex.printstacktrace(); try { //2007版本的excel,用.xlsx结尾 wookbook = new xssfworkbook(fis); //得到工作簿 } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } |
改为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
try { //2003版本的excel,用.xls结尾 wookbook = new hssfworkbook(fis); //得到工作簿 } catch (exception ex) { //ex.printstacktrace(); try { //这里需要重新获取流对象,因为前面的异常导致了流的关闭——加了这一行 fis = new fileinputstream(filepath); //2007版本的excel,用.xlsx结尾 wookbook = new xssfworkbook(filepath); //得到工作簿 } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } |
解析:因为前面异常导致了流的关闭,所以需要重新创建一个流对象。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。