在美团实习的过程中,马上要做的功能有一项是前台上传文件后台获取文件对excel文件进行解析。之前做过后台从DB获取数据按照模板将查询的数据填入xls并返回给前台提供下载的功能,最后会给出一个工具类,里面包含这个功能的实现。
实现对excel文件的读写,比较主流的做法是使用Apache POI提供的各种类和方法,对Apache POI的理解可以参照这篇文章:POI基础
在对POI有足够的认识和理解后,可以预想对前台上传的文件进行解析,实际上就是在服务器端打开该文件,遍历里面的数据,将Excel里面存储的数据按照合适的对应关系存入正确的data object的field。接下来想做什么都可以了,不管是存储数据到DB或者进行相应的计算的都可以。感觉其实excel文件的结构通过POI提供的类来组织的话还比较简单,宏观的看其实一个Excel文件就是一个HSSFWorkbook类的实例,文件里的多个sheet各自对应HSSFSheet实例,每个sheet里面的一行行记录对应HSSFRow,一个个单元格就是一个个HSSFCell。
那么下面我将自己认为最主要的代码实现,在网上看到的,我做了一些修改。粘贴如下:
public class PoiExcelParser { private Sheet sheet; LinkedList[] result; private void loadExcel(String filePath) { FileInputStream inStream = null ; try { inStream = new FileInputStream( new File(filePath)); Workbook workBook = WorkbookFactory.create(inStream); sheet = workBook.getSheetAt( 0 ); } catch (Exception e) { e.printStackTrace(); } finally { try { if (inStream!= null ){ inStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } private String getCellValue(Cell cell) { String cellValue = "" ; DataFormatter formatter = new DataFormatter(); if (cell != null ) { switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { cellValue = formatter.formatCellValue(cell); } else { double value = cell.getNumericCellValue(); int intValue = ( int ) value; cellValue = value - intValue == 0 ? String.valueOf(intValue) : String.valueOf(value); } break ; case Cell.CELL_TYPE_STRING: cellValue = cell.getStringCellValue(); break ; case Cell.CELL_TYPE_BOOLEAN: cellValue = String.valueOf(cell.getBooleanCellValue()); break ; case Cell.CELL_TYPE_FORMULA: try { cellValue = String.valueOf(cell.getNumericCellValue()); } catch (IllegalStateException e){ cellValue = String.valueOf(cell.getRichStringCellValue()); } break ; case Cell.CELL_TYPE_BLANK: cellValue = "" ; break ; case Cell.CELL_TYPE_ERROR: cellValue = "" ; break ; default : cellValue = cell.toString().trim(); break ; } } return cellValue.trim(); } public void getData(){ int rowNum = sheet.getLastRowNum() + 1 ; result = new LinkedList[rowNum]; for ( int i= 0 ;i<rowNum;i++){ Row row = sheet.getRow(i); result[i] = new LinkedList(); for ( int j= 0 ;j<row.getLastCellNum();j++){ Cell cell = row.getCell(j); String str = getCellValue(cell); result[i].add(str); } } } } |
这段代码在实际工程中使用需谨慎,确保可用性,可能会做出相应的修改以适应工程的实际需要。
Update:
1.发现一个问题,就是作为解析前台上传的文件,控制用户上传的文件格式有一定难度,而前面用hssf实现的功能只对xls格式支持,如果万一用户上传的是xlsx就有问题。。。而这个问题,在很久之前就被很好的利用多态解决了,帖子链接如下:通过POI统一读取Excel文件(兼容97-2003和2007+两种格式)