基于Apache poi hssf对xls(excel)文件进行解析

时间:2021-07-28 20:22:49

在美团实习的过程中,马上要做的功能有一项是前台上传文件后台获取文件对excel文件进行解析。之前做过后台从DB获取数据按照模板将查询的数据填入xls并返回给前台提供下载的功能,最后会给出一个工具类,里面包含这个功能的实现。

实现对excel文件的读写,比较主流的做法是使用Apache POI提供的各种类和方法,对Apache POI的理解可以参照这篇文章:POI基础

在对POI有足够的认识和理解后,可以预想对前台上传的文件进行解析,实际上就是在服务器端打开该文件,遍历里面的数据,将Excel里面存储的数据按照合适的对应关系存入正确的data object的field。接下来想做什么都可以了,不管是存储数据到DB或者进行相应的计算的都可以。感觉其实excel文件的结构通过POI提供的类来组织的话还比较简单,宏观的看其实一个Excel文件就是一个HSSFWorkbook类的实例,文件里的多个sheet各自对应HSSFSheet实例,每个sheet里面的一行行记录对应HSSFRow,一个个单元格就是一个个HSSFCell。

那么下面我将自己认为最主要的代码实现,在网上看到的,我做了一些修改。粘贴如下:

解析excel文件核心代码
public class PoiExcelParser {     private Sheet sheet;    //表格类实例     LinkedList[] result;    //保存每个单元格的数据 ,是容器就好,看需求吧        //读取excel文件,创建表格实例     private void loadExcel(String filePath) {         FileInputStream inStream = null        try             inStream = new FileInputStream(new File(filePath));             Workbook workBook = WorkbookFactory.create(inStream);             sheet = workBook.getSheetAt(0);     //注意sheet以0开始计数                  catch (Exception e) {             e.printStackTrace();         }finally            try                 if(inStream!=null){                     inStream.close();   //关闭stream                }                             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);             //每有新的一行,创建一个新的LinkedList对象             result[i] = new LinkedList();             for(int j=0;j<row.getLastCellNum();j++){                 Cell cell = row.getCell(j);                 //获取单元格的值                 String str = getCellValue(cell);                 //将得到的值放入链表中,实际的使用过程中,也可以保存在dataobject里                 result[i].add(str);                         }     

这段代码在实际工程中使用需谨慎,确保可用性,可能会做出相应的修改以适应工程的实际需要。

Update:

1.发现一个问题,就是作为解析前台上传的文件,控制用户上传的文件格式有一定难度,而前面用hssf实现的功能只对xls格式支持,如果万一用户上传的是xlsx就有问题。。。而这个问题,在很久之前就被很好的利用多态解决了,帖子链接如下:通过POI统一读取Excel文件(兼容97-2003和2007+两种格式)