POIPOI操作Excel文件进行读写使用步骤
一、maven坐标:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14</version> </dependency>
二、POI支持的文件格式
HSSF - 提供读写Microsoft Excel XLS格式档案的功能
XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能(我们使用)
HWPF - 提供读写Microsoft Word DOC格式档案的功能
HSLF - 提供读写Microsoft PowerPoint格式档案的功能
HDGF - 提供读Microsoft Visio格式档案的功能
HPBF - 提供读Microsoft Publisher格式档案的功能
HSMF - 提供读Microsoft Outlook格式档案的功能
三、入门案例-步骤
2:获得工作表对象
3:遍历工作表对象 获得行对象
4:遍历行对象 获得单元格(列)对象
5:获得数据
6:关闭
代码实现:
// 获取excel,获取最后一行 @Test public void readExcel2() throws IOException { //创建工作簿 XSSFWorkbook workbook = new XSSFWorkbook("D:\\read.xlsx"); //获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取 XSSFSheet sheet = workbook.getSheetAt(0); //获取当前工作表最后一行的行号,行号从0开始 int lastRowNum = sheet.getLastRowNum(); for(int i=0;i<=lastRowNum;i++){ //根据行号获取行对象 XSSFRow row = sheet.getRow(i); short lastCellNum = row.getLastCellNum(); for(short j=0;j<lastCellNum;j++){ String value = row.getCell(j).getStringCellValue(); System.out.println(value); } } workbook.close(); }
四、
1.创建工作簿对象
2.创建工作表对象
3.创建行对象
4.创建列(单元格)对象, 设置内容
5.通过输出流将workbook对象下载到磁盘
代码实现:
// 创建excel @Test public void createExcel() throws IOException { //在内存中创建一个Excel文件 XSSFWorkbook workbook = new XSSFWorkbook(); //创建工作表,指定工作表名称 XSSFSheet sheet = workbook.createSheet("传智播客"); //创建行,0表示第一行 XSSFRow row = sheet.createRow(0); //创建单元格,0表示第一个单元格 row.createCell(0).setCellValue("编号"); row.createCell(1).setCellValue("姓名"); row.createCell(2).setCellValue("年龄"); XSSFRow row1 = sheet.createRow(1); row1.createCell(0).setCellValue("1"); row1.createCell(1).setCellValue("小明"); row1.createCell(2).setCellValue("10"); XSSFRow row2 = sheet.createRow(2); row2.createCell(0).setCellValue("2"); row2.createCell(1).setCellValue("小王"); row2.createCell(2).setCellValue("20"); //通过输出流将workbook对象下载到磁盘 FileOutputStream out = new FileOutputStream("D:\\itcast.xlsx"); workbook.write(out); out.flush();//刷新 out.close();//关闭 workbook.close(); }
五、如果你觉得太麻烦,一不小心还会错,那么可以根据需求整理工具类
代码实现如下,可参考:
介绍:
1、readExcel方法:将文件内容解析出来存到list集合中
1.1、需要的参数:传入需要解析的文件,这里指定了文件格式为“xls”和“xlsx”
1.2、返回值:List<String[]>,就是一个list集合,这个集合里面存的是String类型的数组,数组中存的是解析出来的每个单元格内容,List中存的就是解析
出来的 每行的数据内容
1.3、另外这里面还指定了日期格式,以yyyy/MM/dd的格式解析出来
2、checkFile方法:readExcel方法需要用到的,用来判断文件格式,如果不是指定的文件格式将抛异常
3、getWorkBook方法:也是readExcel方法需要用到的,用来获取工作薄对象,会根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
4、getCellValue方法:能解析成日期对象
public class POIUtils { private final static String xls = "xls"; private final static String xlsx = "xlsx"; private final static String DATE_FORMAT = "yyyy/MM/dd"; /** * 读入excel文件,解析后返回 * @param file * @throws IOException */ public static List<String[]> readExcel(MultipartFile file) throws IOException { //检查文件 checkFile(file); //获得Workbook工作薄对象 Workbook workbook = getWorkBook(file); //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回 List<String[]> list = new ArrayList<String[]>(); if(workbook != null){ //遍历工作薄中的每一个工作表,从第一个开始,一直到工作薄的最后一张表 for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){ //获得当前sheet工作表 Sheet sheet = workbook.getSheetAt(sheetNum); if(sheet == null){ //如果工作薄中没有工作表,则跳出 continue; } //获得当前sheet的开始行 int firstRowNum = sheet.getFirstRowNum(); //获得当前sheet的结束行 int lastRowNum = sheet.getLastRowNum(); //循环除了第一行的所有行,第一行不是数据,只是表头信息,所以不遍历。 //另外遍历工作表中的最后一个工作行,可以用<=,遍历工作行中的最后一个单元格只能用<,具体自己可以去获取测试一下原因 for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){ //获得当前行 Row row = sheet.getRow(rowNum); if(row == null){ //如果该工作表中没有遍历出工作行,则跳出 continue; } //获得当前行的开始列 int firstCellNum = row.getFirstCellNum(); //获得当前行的列数 int lastCellNum = row.getPhysicalNumberOfCells(); String[] cells = new String[row.getPhysicalNumberOfCells()]; //循环当前行 for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){ //获取当前单元格对象 Cell cell = row.getCell(cellNum); //[cellNum]:因为是一个个遍历添加的数据,所以每添加一个数据要指定角标 //getCellValue(cell):获取单元格对象里面的内容,并赋值给指定的数组角标中 //整行代码表示将当前行的每个单元格存入一个数组中 cells[cellNum] = getCellValue(cell); } //将循环出来保存到数组中的每行数据存到集合中 list.add(cells); } } //释放资源 workbook.close(); } //返回保存数据后的集合 return list; } //校验文件是否合法 public static void checkFile(MultipartFile file) throws IOException{ //判断文件是否存在 if(null == file){ throw new FileNotFoundException("文件不存在!"); } //获得文件名 String fileName = file.getOriginalFilename(); //判断文件是否是excel文件 if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){ throw new IOException(fileName + "不是excel文件"); } } public static Workbook getWorkBook(MultipartFile file) { //获得文件名 String fileName = file.getOriginalFilename(); //创建Workbook工作薄对象,表示整个excel Workbook workbook = null; try { //获取excel文件的io流 InputStream is = file.getInputStream(); //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象 if(fileName.endsWith(xls)){ //2003 workbook = new HSSFWorkbook(is); }else if(fileName.endsWith(xlsx)){ //2007 workbook = new XSSFWorkbook(is); } } catch (IOException e) { e.printStackTrace(); } return workbook; } public static String getCellValue(Cell cell){ String cellValue = ""; if(cell == null){ return cellValue; } //如果当前单元格内容为日期类型,需要特殊处理 String dataFormatString = cell.getCellStyle().getDataFormatString(); if(dataFormatString.equals("m/d/yy")){ cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue()); return cellValue; } //把数字当成String来读,避免出现1读成1.0的情况 if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){ cell.setCellType(Cell.CELL_TYPE_STRING); } //判断数据的类型 switch (cell.getCellType()){ case Cell.CELL_TYPE_NUMERIC: //数字 cellValue = String.valueOf(cell.getNumericCellValue()); break; case Cell.CELL_TYPE_STRING: //字符串 cellValue = String.valueOf(cell.getStringCellValue()); break; case Cell.CELL_TYPE_BOOLEAN: //Boolean cellValue = String.valueOf(cell.getBooleanCellValue()); break; case Cell.CELL_TYPE_FORMULA: //公式 cellValue = String.valueOf(cell.getCellFormula()); break; case Cell.CELL_TYPE_BLANK: //空值 cellValue = ""; break; case Cell.CELL_TYPE_ERROR: //故障 cellValue = "非法字符"; break; default: cellValue = "未知类型"; break; } return cellValue; } }