首页 > 代码库 > Poi实现Excel的导入

Poi实现Excel的导入

前面写过一篇HSSF(实际上就是Poi)实现Excel导出的随笔,正好最近也有做导入的需求,那么就索性再写一篇Poi导入Excel的随笔吧。

其实,poi导入Excel和Poi导出Excel在实现步骤上是大同小异的,但是做这个之前,有一个问题需要搞清楚,Excel文件的分类,Excel有2003板,后缀为.xls和2007板,后缀为.xlsx,而Poi解析这两种文件的时候,使用的类是不同的,前者使用的是HSSFWorkBook,后者是XSSFWorkBook;

搞清楚了这个,接下来就可以开始Excel的导入操作了

第一步,将这个Excel文件读取成为一份WorkBook(假使得到是一个文件)
  WorkBook mWorkBook = null;
  String fileName = file.getName();
  String type = fileName.split(fileName.lastIndexOf(".")+1,fileName.length);
  FileInputStream mStream = new FileInputStream(file);
  mWorkBook = "xls".equals(type) ? new HSSFWorkBook(mStream) : new XSSFWorkBook(mStream);

第二步,得到对应的sheet页,并得到行和列的数据

  Sheet sheet0 = mWorkBook.getSheetAt(0);
  Row row0 = sheet0.getRow(0);
  int rowNum = sheet0.getLastRowNum();
  int columeNum = row0.getPhysicalNumberOfCells();

得到了总的行数和列数,接下来就可使用 双重for循环对没个单元格的内容进行获取;
为了避免遗忘,还是举个例子吧,有一张记录人信息的Excel表格,表格有3列,分别是name,age,sex
那么你可以建立一个实体类Person,拥有name,age,sex三个属性

好了,接下来就进行数据的读取储存
  List<Person> list = new ArrayList<>();
  Person person;
  for(int i = 1 ; i<rowNum ; i++){
    Row row = sheet0.getRow(i);
    for(int j = 0; j<columeNum ; j++){
      Cell cell = row.getCell(j);
      person = new Person();
      swich(j){
        case 1 :
          person.setName(cell.getStringCellValue());
          break;
        case 2 :
          person.setAge(cell.getNumericCellValue());
          break;
        case 3 :
          person.setSex(cell.getStringCellValue());
        }
      list.add(person);
    }
  }

这样完成了对Excel的解析

在这里要说一个比较蛋疼的问题,那就是Excel单元格的格式,通过上面的例子看到了,不同格式的单元格的内容的获取,Poi提供的接口是不一样的,数字类型的getNumericCellValue,文本类型的getStringCellValue,当然还有boolean类型和Date类型等,这么多的类型,如果使用的API不对,那么就GG了。

对于一些可以有明确的格式的单元格还好,如姓名一看就是文本类型,年龄是数字类型,这些获取的时候可以明确的知道要用哪个,但是还有一些如日期,用起来就有点蛋疼了;

获取你会说,日期啊,当然是文本类型了,那么我只能说错,大错特错,虽然开始我也是这么以为的,但只要稍微的验证一下就会发现,在不对单元格格式作出规定时,合法的日期格式诸如: 1月1日,2017/1/1,2017-1-1 这些,单元格内容的获取要是用getNumericCellValue, 但是不合法的日期格式,如:13月1日,2017/13/1等,单元格内容的获取又变为了getStringCellValue,
当然在不需要对日期的格式进行校检的情况下,这也不是什么大问题,可以使用如下方法进行获取
try{
cell.getNumericCellValue();
}catchh(Exception e){
cell.getStringCellValue();
}

但是如果要对日期格式进行校验,如规定你输入的格式需要是2017/1/1、2017/01/01类似的,上面的方法就行不通了,你会发现,你写在Excel中的日期2017/01/01在通过getNumericCellValue之后变成了float类型的数据。这就很操蛋了,日期的格式丢失了,虽然可以使用SimpleDateFormat重新转化为日期格式,但是,显然这是一个新的格式,校检这个毫无意义啊。

这就尴尬了,我暂时没有发现什么办法可以进行校检,不过最后的解决办法就是,我来提供你填写Excel的模板,在模板中规定,你的这一列数据的数据格式为文本
CellStyle style = mWorkBook.createCellStyle();
HSSFDataFormat format = mWorkBook.createDataFormat();
style.setDataFormat(format.getFormat("@"));
sheet1.setDefaultColumeStyle(index,style);

好了,有了模板,日期的格式就被固定为了文本,这样获取的时候统一使用getStringCellValue(),这样日期的格式也不会丢失了,而且,导出的模板规定了文件的类型,也可以不为到底使用XSSFWorkBook还是HSSFWorkBook作区分了;

Poi实现Excel的导入