依赖于POI的Excel读取封装

本文中的代码依赖于对Apache项目POI(POI的项目主页:http://poi.apache.org/)。

 

Excel.java (载入Excel文件,提供了获取表列表、通过表索引取得表和通过表名取得表3个方法)

  1 package com.magbt.io.office.excel;
2
3 import java.io.FileInputStream;
4 import java.io.FileNotFoundException;
5 import java.io.IOException;
6 import java.util.ArrayList;
7
8 import org.apache.poi.hssf.usermodel.HSSFSheet;
9 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
10
11 public class Excel {
12 private HSSFWorkbook wb = null;
13 private String name;
14
15 /**
16 * 通过一个Microsoft Office Excel文件构建一个Excel对象
17 *
18 * @param filename
19 * Microsoft Office Excel 文件名(包含完整路径)
20 */
21 public Excel(String filename) {
22 name = filename;
23 try {
24 wb = new HSSFWorkbook(new FileInputStream(filename));
25 } catch (FileNotFoundException e) {
26 // TODO Auto-generated catch block
27 e.printStackTrace();
28 } catch (IOException e) {
29 // TODO Auto-generated catch block
30 e.printStackTrace();
31 }
32 }
33
34 /**
35 * 返回当前Excel文件名
36 *
37 * @return 打开的文件名
38 */
39 public String getName() {
40 return name;
41 }
42
43 /**
44 * 以列表方式返回一个Microsoft office excel 文件内的所有表对象
45 *
46 * @return 表对象列表
47 * @see HSSFSheet
48 */
49 public ArrayList<Sheet> getSheetList() {
50 if (wb == null) {
51 return null;
52 }
53
54 ArrayList<Sheet> list = new ArrayList<Sheet>();
55 int i = 0;
56 while (i < this.length()) {
57 list.add(new Sheet(wb.getSheetAt(i++)));
58 }
59 return list;
60 }
61
62 /**
63 * 获取当前打开excel文件中的表数量
64 *
65 * @return 表数量
66 */
67 public int length() {
68 return wb.getNumberOfSheets();
69 }
70
71 /**
72 * 返回索引为{@code index}的表,若未找到则抛出异常IllegalArgumentException
73 *
74 * @param index
75 * 表的索引下标,以0开始
76 * @return 索引下标为{@code index}的表对象
77 * @throws IllegalArgumentException
78 */
79 public Sheet getSheet(int index) throws IndexOutOfBoundsException {
80 try {
81 return new Sheet(wb.getSheetAt(index));
82 } catch (IllegalArgumentException e) {
83 throw new IndexOutOfBoundsException("在文件[" + name + "]中未找到索引为["
84 + index + "]的表");
85 }
86 }
87
88 /**
89 * 返回表名为为{@code name}的表,若未找到则抛出异常IllegalArgumentException
90 *
91 * @param name
92 * 表的名字
93 * @return 表为为{@code name}的表对象
94 * @throws IllegalArgumentException
95 */
96 public Sheet getSheet(String name) throws IllegalArgumentException {
97 try {
98 return new Sheet(wb.getSheet(name));
99 } catch (IllegalArgumentException e) {
100 throw new IllegalArgumentException("在文件[" + name + "]中未找到名为["
101 + name + "]的表");
102 }
103 }
104 }
 

 

Sheet.java(这里面才真正开始读取Excel的表信息,具体方法参见注释)

  1 package com.magbt.io.office.excel;
2
3 import java.util.ArrayList;
4
5 import org.apache.poi.hssf.usermodel.HSSFCell;
6 import org.apache.poi.hssf.usermodel.HSSFRow;
7 import org.apache.poi.hssf.usermodel.HSSFSheet;
8 import org.apache.poi.ss.usermodel.Cell;
9
10 /**
11 * Excel中的一个Workbook对象,依赖于 Apache POI包
12 *
13 * @author hyjiacan
14 *
15 */
16 public class Sheet {
17 HSSFSheet sheet = null;
18 private int firstRowNum;// 第一行号
19 private int lastRowNum;// 最后行号
20
21 /**
22 * 由一个HSSFSheet构建一个Sheet对象
23 *
24 * @param sheet
25 */
26 public Sheet(HSSFSheet sheet) {
27 this.sheet = sheet;
28 this.firstRowNum = sheet.getFirstRowNum();
29 this.lastRowNum = sheet.getLastRowNum();
30 }
31
32 /**
33 * 返回表的第一个非空行行号
34 *
35 * @return 第一个非空行的行号
36 */
37 public int getFirstRowNum() {
38 return firstRowNum;
39 }
40
41 /**
42 * 返回表的最后一个非空行行号
43 *
44 * @return 最后一个非空行行号
45 */
46 public int getLastRowNum() {
47 return lastRowNum;
48 }
49
50 /**
51 * 当前打开的表名字
52 *
53 * @return 表名字
54 */
55 public String getName() {
56 return sheet.getSheetName();
57 }
58
59 /**
60 * 获取表数据行数
61 *
62 * @return 行数
63 * @see HSSFSheet
64 */
65 public int getRowSize() {
66 return sheet.getLastRowNum() - sheet.getFirstRowNum();
67 }
68
69 /**
70 * 获取表数据列数
71 *
72 * @return 列数
73 * @see HSSFSheet
74 */
75 public int getColumnSize() {
76 HSSFRow row = sheet.getRow(this.getFirstRowNum());
77 return row.getLastCellNum() - row.getFirstCellNum();
78 }
79
80 /**
81 * 返回当前表的列名数组
82 *
83 * @return 列名数组
84 */
85 public String[] getColumnNames() {
86 ArrayList<String> h = getRowAt(this.firstRowNum);
87 String[] head = new String[h.size()];
88 int i = 0;
89 for (String o : h) {
90 head[i++] = String.valueOf(o);
91 }
92 return head;
93 }
94
95 /**
96 * 获取指定行的数据
97 *
98 * @param index
99 * 指定行号
100 * @return 指定行数据
101 * @see HSSFRow
102 * @see HSSFCell
103 */
104 public ArrayList<String> getRowAt(int index) {
105 HSSFRow row = sheet.getRow(index);
106 ArrayList<String> cells = new ArrayList<String>();
107 int i = row.getFirstCellNum();
108 while (i < this.getColumnSize()) {
109 HSSFCell cell = row.getCell(i++);
110 if (cell == null)
111 cells.add("");
112 else {
113 Object val = null;
114 switch (cell.getCellType()) {
115 case Cell.CELL_TYPE_BOOLEAN:
116 val = cell.getBooleanCellValue();
117 break;
118 case Cell.CELL_TYPE_FORMULA:
119 val = cell.getCellFormula();
120 break;
121 case Cell.CELL_TYPE_NUMERIC:
122 val = cell.getNumericCellValue();
123 break;
124 case Cell.CELL_TYPE_STRING:
125 val = cell.getStringCellValue();
126 default:
127 val = cell.getRichStringCellValue();
128 }
129
130 cells.add(String.valueOf(val));
131 }
132 }
133 return cells;
134 }
135
136 /**
137 * 返回表的Table视图
138 *
139 * @return 表的table视图
140 * @see Table
141 */
142 public Table getAsTable() {
143 Table table = Table.build(this.getRowSize(), this.getColumnSize());
144 table.setHeader(getColumnNames());
145 table.setName(sheet.getSheetName());
146
147 for (int i = this.getFirstRowNum() + 1; i <= this.getRowSize(); i++) {
148 table.addRow(this.getRowAt(i));
149 }
150
151 return table;
152 }
153 }
 


Table.java(使用前面的Sheet类,将一个表以Table的方式读取到内存中。Table提供了简单的查找功能,可以通过行列号或者某个单元格的值来进行查找,然后再返回一张表;查找可以使用选项:完全相等、包含、以。。。开始、以。。。结束。)

  1 package com.magbt.io.office.excel;
2
3 import java.util.ArrayList;
4
5 /**
6 * excel表的Table二维结构,所有数据均以字符串({@link String})类型存储
7 *
8 * @author hyjiacan
9 * @see Sheet
10 */
11 public class Table {
12 private ArrayList<ArrayList<String>> table = null;
13 private String[] header = null;// 表头信息
14 private int colSize; // 表列数
15 private int rowSize; // 表行数
16 private String name;// 表名称
17
18 /**
19 * 单元格中的数据和要查找的串完全相同
20 */
21 public static final int FIND_EQUALS = 0;
22 /**
23 * 单元格中的数据包含要查找的串
24 */
25 public static final int FIND_CONTAINS = 1;
26 /**
27 * 单元格中的数据以要查找的串开头
28 */
29 public static final int FIND_STARTS_WITH = 2;
30 /**
31 * 单元格中的数据以要查找的串结尾
32 */
33 public static final int FIND_ENDS_WITH = 3;
34
35 private Table() {
36 table = new ArrayList<ArrayList<String>>();
37 }
38
39 /**
40 * 通过一个{@link Sheet}对象构建一个Table对象
41 *
42 * @param s
43 * Sheet对象
44 * @see Sheet
45 */
46 public Table(Sheet s) {
47 this.setHeader(s.getColumnNames());
48 this.setName(s.sheet.getSheetName());
49 this.setColSize(s.getColumnSize());
50 this.setRowSize(s.getRowSize());
51 for (int i = s.getFirstRowNum() + 1; i <= this.getRowSize(); i++) {
52 this.addRow(s.getRowAt(i));
53 }
54 }
55
56 /**
57 * 返回当前表的名字
58 *
59 * @return 表名字
60 */
61 public String getName() {
62 return name;
63 }
64
65 /**
66 * 设置表名字
67 *
68 * @param name
69 * 表名字
70 */
71 void setName(String name) {
72 this.name = name;
73 }
74
75 /**
76 * 返回表列数
77 *
78 * @return 表列数
79 */
80 public int getColSize() {
81 return colSize;
82 }
83
84 /**
85 * 用于构建表的时候设置表列数,若所给列数小于0则抛出 IllegalArgumentException 异常
86 *
87 * @param colSize
88 * 表要设置为多少列
89 * @see IllegalArgumentException
90 */
91 private void setColSize(int colSize) {
92 if (colSize < 0)
93 throw new IllegalArgumentException("Wrong column size");
94 this.colSize = colSize;
95 }
96
97 /**
98 * 返回表行数
99 *
100 * @return 表行数
101 */
102 public int getRowSize() {
103 return rowSize;
104 }
105
106 /**
107 * 用于构建表的时候设置表行数,若所给行数小于0则抛出 IllegalArgumentException异常
108 *
109 * @param colSize
110 * 表要设置为多少行
111 * @throws IllegalArgumentException
112 * @see IllegalArgumentException
113 */
114 private void setRowSize(int rowSize) {
115 if (rowSize < 0) {
116 throw new IllegalArgumentException("Wrong row size");
117 }
118 this.rowSize = rowSize;
119 }
120
121 /**
122 * 返回表头(列名称)
123 *
124 * @return 表头{@code String[]}
125 */
126 public String[] getHeader() {
127 return header;
128 }
129
130 /**
131 * 设置表的列名称
132 *
133 * @param header
134 * 表列名称数组
135 */
136 void setHeader(String[] header) {
137 this.header = header;
138 }
139
140 /**
141 * 构建一张表,里面存放规范的excel表信息
142 *
143 * @param rows
144 * 表行数
145 * @param cols
146 * 表列数
147 * @return 新{@code Table}实例
148 */
149 public static Table build(int rows, int cols) {
150 Table t = new Table();
151 t.setColSize(cols);
152 t.setRowSize(rows);
153 return t;
154 }
155
156 /**
157 * 通过索引获取表内某一行的数据,若指定索引行不存在,抛出 IndexOutOfBoundsException 异常
158 *
159 * @param index
160 * 行索引
161 * @return 指定行数据
162 * @throws IndexOutOfBoundsException
163 *
164 * @see IndexOutOfBoundsException
165 */
166 public ArrayList<String> getRowAt(int index) {
167 if (index < 0 && index > this.rowSize)
168 throw new IndexOutOfBoundsException("指定行不存在");
169 return new ArrayList<String>(table.get(index));
170 }
171
172 /**
173 * 通过索引获取表内某一列的数据,若指定索引列不存在,抛出 IndexOutOfBoundsException 异常
174 *
175 * @param index
176 * 列索引
177 * @return 指定列数据
178 * @throws IndexOutOfBoundsException
179 *
180 * @see IndexOutOfBoundsException
181 */
182 public ArrayList<String> getColumn(int index) {
183 if (index < 0 && index > this.colSize)
184 throw new IndexOutOfBoundsException("指定列不存在");
185 ArrayList<String> cols = new ArrayList<String>();
186 for (ArrayList<String> a : table) {
187 cols.add(a.get(index));
188 }
189
190 return cols;
191 }
192
193 /**
194 * 获取某个指定单元格的数据,若指定索引单元格不存在,抛出 IndexOutOfBoundsException 异常
195 *
196 * @param row
197 * 指定行索引
198 * @param col
199 * 指定列索引
200 * @return 指定索引的单元格数据
201 * @throws IndexOutOfBoundsException
202 *
203 * @see IndexOutOfBoundsException
204 */
205 public String getCell(int row, int col) {
206 if (row < 0 && row > this.rowSize)
207 throw new IndexOutOfBoundsException("指定行不存在");
208 if (col < 0 && col > this.colSize)
209 throw new IndexOutOfBoundsException("指定列不存在");
210 return table.get(row).get(col);
211 }
212
213 /**
214 * 添加 新行到表中
215 *
216 * @param row
217 * 要添加的新行
218 */
219 void addRow(ArrayList<String> row) {
220 table.add(row);
221 }
222
223 /**
224 * 通过某个列的值value找到所在的行集合(Table),若指定列不存在,抛出 IllegalArgumentException 异常
225 *
226 * @param columnIndex
227 * 指定要查找的列索引,以0开始
228 * @param value
229 * 要查找的单元格的值
230 * @return 找到的行的集合
231 * @see Table
232 * @throws IllegalArgumentException
233 */
234 public Table findRowByCellValue(int columnIndex, String value) {
235 return findRowByCellValue(columnIndex, value, FIND_EQUALS);
236 }
237
238 /**
239 * 通过某个列的值value找到所在的行集合(Table),若指定列不存在,抛出 IllegalArgumentException 异常
240 *
241 * @param columnName
242 * 指定要查找的列名称
243 * @param value
244 * 要查找的单元格的值
245 * @return 找到的行的集合
246 * @see Table
247 * @throws IllegalArgumentException
248 */
249 public Table findRowByCellValue(String columnName, String value) {
250 return findRowByCellValue(columnName, value, FIND_EQUALS);
251 }
252
253 /**
254 * 通过某个列的值value找到所在的行集合(Table),若指定列不存在,抛出 IllegalArgumentException 异常
255 *
256 * @param columnIndex
257 * 指定要查找的列索引,以0开始
258 * @param value
259 * 要查找的单元格的值
260 * @param option
261 * 查找方式:
262 * <p>
263 * 完全匹配 <b>FIND_EQUALS</b><br/>
264 * 包含 <b>FIND_CONTAINS</b><br/>
265 * 以....开头 <b>FIND_STARTS_WITH</b><br />
266 * 以....结尾 <b>FIND_ENDS_WITH</b>
267 * </p>
268 * 默认为 <b>FIND_EQUALS</b>
269 * @return 找到的行的集合
270 * @see Table
271 * @throws IllegalArgumentException
272 */
273 public Table findRowByCellValue(int columnIndex, String value, int option) {
274 value = value.toLowerCase();
275
276 Table t = new Table();
277 t.setColSize(this.colSize);
278 t.setHeader(header);
279 t.setName("搜索[" + this.getName() + ">>" + header[columnIndex] + ">>"
280 + value + "]的结果");
281 switch (option) {
282 case FIND_EQUALS:
283 for (ArrayList<String> al : table) {
284 if (al.get(columnIndex).equalsIgnoreCase(value))
285 t.addRow(al);
286 }
287 break;
288 case FIND_CONTAINS:
289 for (ArrayList<String> al : table) {
290 if (al.get(columnIndex).toLowerCase().contains(value))
291 t.addRow(al);
292 }
293 break;
294 case FIND_STARTS_WITH:
295 for (ArrayList<String> al : table) {
296 if (al.get(columnIndex).toLowerCase().startsWith(value))
297 t.addRow(al);
298 }
299 break;
300 case FIND_ENDS_WITH:
301 for (ArrayList<String> al : table) {
302 if (al.get(columnIndex).toLowerCase().endsWith(value))
303 t.addRow(al);
304 }
305 break;
306 default:
307 throw new IllegalArgumentException("非法的\"option\"值");
308 }
309 t.setRowSize(t.table.size());
310
311 return t;
312 }
313
314 /**
315 * 通过某个列的值value找到所在的行集合(Table),若指定列不存在,抛出 IllegalArgumentException 异常
316 *
317 * @param columnName
318 * 指定要查找的列名称
319 * @param value
320 * 要查找的单元格的值
321 * @param option
322 * 查找方式:
323 * <p>
324 * 完全匹配 <b>FIND_EQUALS</b><br/>
325 * 包含 <b>FIND_CONTAINS</b><br/>
326 * 以....开头 <b>FIND_STARTS_WITH</b><br />
327 * 以....结尾 <b>FIND_ENDS_WITH</b><br />
328 * </p>
329 * 默认为 <b>FIND_EQUALS</b>
330 * @return 找到的行的集合
331 * @see Table
332 * @throws IllegalArgumentException
333 */
334 public Table findRowByCellValue(String columnName, String value, int option) {
335 int index = -1;
336 for (int i = 0; i < header.length; i++) {
337 if (header[i].equalsIgnoreCase(columnName)) {
338 index = i;
339 break;
340 }
341 }
342 if (index == -1)
343 throw new IllegalArgumentException("指定列\"" + columnName + "\"不存在");
344
345 return findRowByCellValue(index, value, option);
346 }
347 }
 


ExcelTest.java (使用示例)

 1 import com.magbt.io.office.excel.Excel;
2 import com.magbt.io.office.excel.Table;
3
4 public class ExcelTest {
5
6 public static void main(String[] args) {
7 // 打开Excel文件
8 Excel e = new Excel("Z:\\开发部图像信息采集核对表.xls");
9 // 选择文件中的第一张表并且返回Table视图
10 // 查找所有性别为男的行,并返回Table视图
11 // 在上次查找结果中查找所有工号以3结束的行,并返回Table视图
12 Table t = e.getSheet(0).getAsTable().findRowByCellValue("性别", "男", Table.FIND_EQUALS)
13 .findRowByCellValue("工号", "3", Table.FIND_ENDS_WITH);
14 // 打印出表的表头信息
15 for(String s:t.getHeader()){
16 System.out.print(s+"\t");
17 }
18 System.out.println();
19 for(int i=0;i<t.getRowSize();i++){
20 System.out.println(t.getRowAt(i));
21 }
22 }
23 }
 

注:此代码仅能正确读取第一个包含数据的行为表头的表(并不要求是第一行,但要求是第一个存在数据的行);读取出的数据均以String类型存在,若有其它需要,请自行转换。

posted @ 2012-02-21 22:20  永远学不会屈服的男人  阅读(319)  评论(0编辑  收藏  举报