POI的名字来源于Poor Obfuscation Implementation (蹩脚的模糊实现),是说虽然特意对文件格式进行了模糊处理,但是仍然可以成功使用反向工程。
使用POI前,添加POI的MAVEN依赖,
< dependency > < groupId >org.apache.poi</ groupId > < artifactId >poi</ artifactId > < version >3.8</ version > </ dependency > |
也可以直接下载JAR包放入CLASSPATH.
读取 Excel 文件
如下列,从EXCEL的单元中读取内容:
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; //.. FileInputStream new FileInputStream( new File( "C:\\test.xls" )); //获取XLS文件的工作簿实例 HSSFWorkbook new HSSFWorkbook(file); //获取工作簿的第一张工作表 HSSFSheet 0 ); //获取当前工作表的行迭代器 Iterator<Row> //获取当前行所有单元的迭代器 Iterator<Cell> |
注意,必须使用HSSF开头的POI类库。
POI 处理文件的类库分为以下几类:
- HSSF– XLS文件
- XSSF– XLSX文件
- HWPF - Microsoft Word 97 (DOC) 文件
-
XWPF - DOCX文件
- HSLF– Microsoft PowerPoint 文件.
- HDGF– Microsoft Visio 二进制文件.
- HPBF – Microsoft Publisher 文件.
- HSMF– Microsoft Outlook MSG 文件
读写 .xlsx 文件
上面代码中的
HSSFWorkbook
和 HSSFSheet
用于 .xls 格式。对于.xlsx格式的文件,你需要使用更新的 POI 类:
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.xssf.usermodel.XSSFSheet; //.. FileInputStream new FileInputStream( new File( "C:\\test.xlsx" )); //获取XLS文件的工作簿实例 XSSFWorkbook new XSSFWorkbook (file); //获取工作簿的第一张工作表 XSSFSheet 0 ); //获取当前工作表的行迭代器 Iterator<Row> //获取当前行所有单元的迭代器 Iterator<Cell> |
使用 XSSFWorkbook
和 XSSFSheet
类读写 .xlsx 文件。
例如:
test.xls
现在,我们使用Apache POI 读取该XLS文件并打印数据。
try { FileInputStream file = new FileInputStream( new File( "C:\\test.xls" )); //获取XLS文件的工作簿实例 HSSFWorkbook workbook = new HSSFWorkbook(file); //获取工作簿的第一张工作表 HSSFSheet sheet = workbook.getSheetAt( 0 ); //从第一张工作表开始迭代每一行 Iterator<Row> rowIterator = sheet.iterator(); while (rowIterator.hasNext()) { Row row = rowIterator.next(); //迭代每一行的每一列 Iterator<Cell> cellIterator = row.cellIterator(); while (cellIterator.hasNext()) { Cell cell = cellIterator.next(); switch (cell.getCellType()) { case Cell.CELL_TYPE_BOOLEAN: System.out.print(cell.getBooleanCellValue() + "\t\t" ); break ; case Cell.CELL_TYPE_NUMERIC: System.out.print(cell.getNumericCellValue() + "\t\t" ); break ; case Cell.CELL_TYPE_STRING: System.out.print(cell.getStringCellValue() + "\t\t" ); break ; } } System.out.println( "" ); } file.close(); FileOutputStream out = new FileOutputStream( new File( "C:\\test.xls" )); workbook.write(out); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } |
在读单元的内容前,我们需要使用方法 cell.getCellType()
获取单元的类型,然后调用合适的方法读取内容。
输出:
Emp 1.0 2.0 3.0 4.0 |
3. 创建新的 Excel 文件
代码如下:
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; //.. HSSFWorkbook new HSSFWorkbook(); HSSFSheet "Sample sheet" ); //在当前工作表中创建新行 Row 0 ); //在当前行中创建一个单元 Cell 0 ); //设置单元格的值 cell.setCellValue( "Blahblah" ); |
下面的代码把虚构的数据写入一个新的EXCEL文件中。
HSSFWorkbook new HSSFWorkbook(); HSSFSheet "Sample sheet" ); Map<String, new HashMap<String, Object[]>(); data.put( "1" , new Object[] { "Emp No." , "Name" , "Salary" }); data.put( "2" , new Object[] {1d, "John" , 1500000d}); data.put( "3" , new Object[] {2d, "Sam" , 800000d}); data.put( "4" , new Object[] {3d, "Dean" , 700000d}); Set<String> int rownum = 0 ; for (String key : keyset) { Row row = sheet.createRow(rownum++); Object [] objArr = data.get(key); int cellnum = 0 ; for (Object obj : objArr) { Cell cell = row.createCell(cellnum++); if (obj instanceof Date) cell.setCellValue((Date)obj); else if (obj instanceof Boolean) cell.setCellValue((Boolean)obj); else if (obj instanceof String) cell.setCellValue((String)obj); else if (obj instanceof Double) cell.setCellValue((Double)obj); } } try { FileOutputStream out = new FileOutputStream( new File( "C:\\new.xls" )); workbook.write(out); out.close(); System.out.println( "Excel written successfully.." ); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } |
输出: new.xls
4. 修改Excel 文件的内容
修改EXCEL文件的内容简单直接。用前面讨论的API打开EXCEL,然后设置单元的值。请注意,只有在关闭EXCEL文件后,我们才能更新EXCEL的文件。
update.xls
下列代码读取单元里面的工资,然后把工资乘2
try { FileInputStream file = new FileInputStream( new File( "C:\\update.xls" )); HSSFWorkbook workbook = new HSSFWorkbook(file); HSSFSheet sheet = workbook.getSheetAt( 0 ); Cell cell = null ; //更新单元的值 cell = sheet.getRow( 1 ).getCell( 2 ); cell.setCellValue(cell.getNumericCellValue() * 2 ); cell = sheet.getRow( 2 ).getCell( 2 ); cell.setCellValue(cell.getNumericCellValue() * 2 ); cell = sheet.getRow( 3 ).getCell( 2 ); cell.setCellValue(cell.getNumericCellValue() * 2 ); //关闭文件 (很重要,别忘记) file.close(); FileOutputStream outFile = new FileOutputStream( new File( "C:\\update.xls" )); workbook.write(outFile); outFile.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } |
修改EXCEL文件的步骤是:
- 用读取(输入流)模式打开EXCEL文件 (inputstream)
- 使用POI API 读取excel 的内容
- 使用不同的
setCellValue
方法设置单元的值. - 关闭EXCEL的输入文件(inputstream)
- 用写模式(输入流)打开相同的 excel 文件 (outputstream)
- 把修改后的工作簿内容写出输出文件
- 关闭excel 输出文件流
输出: update.xls