当前位置: 移动技术网 > IT编程>开发语言>Java > java如何读取Excel简单模板

java如何读取Excel简单模板

2019年07月19日  | 移动技术网IT编程  | 我要评论

场景:对于经常需要导入excel模板或数据来解析后加以应用的,使用频率非常之高,做了一个比较稳定的版本,体现在这些地方

工具:org.apache.poi

使用前必须了解这些:

1、要解析,那肯定先判断是不是excel

2、xls后缀的excel,是03版及以前的用hssfworkbook类
      xlsx后缀的excel,是07版及以后的用xssfworkbook解析

3、getworkbook这个方法是我自己乱造各种excel数据不断测试搜索修正得出的结果,其他的像简单的判断后缀xls还是xlsx来决定用hssh还是xssf是不保险的,比如你可能没遇过org.apache.poi.openxml4j.exceptions.invalidformatexception这样的异常,当然这个异常仍然是因为excel类型导致获取workbook时出错,然而我查到的结果是,excel最底层是xml实现的,类型问题出在这儿,看异常的描述也可以稍微看出来openxml4j.exceptions

4 、可能出现空行,空的单元格,或者单元格值为空的情况,这些情况,在我的readexcel()方法里都考虑到了,为什么我不用迭代器,或者加强的for each循环?就是因为这些坑爹的空单元格或者空行啊,迭代器内部在取cell单元格对象时跳过这些空的对象,who knows why?我也不知道,反正我测试过,跳过去了,本来5个单元格,一个空的,结果就只得到4个数据,即使用cell.isempty()和cell!=null来判断,也没卵用,因为遍历的时候直接跳过去了,都没有判断的机会

5、取单元格数据,这个就比较简单了,判断单元格类型,根据类型做相应的处理取出来,但是我觉得我这个getcellvalue()的方法应该有漏洞,先这么用着

下面上代码,简单描述下关键部位

import java.io.file;
import java.io.fileinputstream;
import java.io.filenotfoundexception;
import java.io.ioexception;
import java.io.inputstream;
import java.io.pushbackinputstream;
import java.util.arraylist;
import java.util.hashmap;
import java.util.map;
import java.util.list;
import org.apache.poi.poixmldocument;
import org.apache.poi.openxml4j.exceptions.invalidformatexception;
import org.apache.poi.openxml4j.opc.opcpackage;
import org.apache.poi.poifs.filesystem.poifsfilesystem;
import org.apache.poi.ss.usermodel.cell;
import org.apache.poi.ss.usermodel.row;
import org.apache.poi.ss.usermodel.sheet;
import org.apache.poi.ss.usermodel.workbook;
import org.apache.poi.xssf.usermodel.xssfworkbook;
import org.apache.poi.hssf.usermodel.hssfcell;
import org.apache.poi.hssf.usermodel.hssfworkbook;
import org.apache.xmlbeans.impl.piccolo.io.fileformatexception;
/**
 *yanbiao 2016.10.25 
 */
public class excelutil {
 
  private static final string extension_xls = "xls";
  private static final string extension_xlsx = "xlsx";

/**
* 文件检查
*/
private void prereadcheck(string filepath) throws filenotfoundexception, fileformatexception {

file file = new file(filepath);
if (!file.exists()) {
throw new filenotfoundexception("导入的文件不存在:" + filepath);
}
if (!(filepath.endswith(extension_xls) || filepath.endswith(extension_xlsx))) {
throw new fileformatexception("传入的文件不是excel");
}
} 
 /**
   * 取得workbook对象
   * xls:hssfworkbook,03版
   * xlsx:xssfworkbook,07版
  */
 private workbook getworkbook(string filepath) throws ioexception, invalidformatexception { 
    //直接判断后缀来返回相应的workbook对象多数情况没问题,但是这个更保险,第3条已经说明  
    workbook wb = null;
    inputstream is = new fileinputstream(filepath);
    if (!is.marksupported()) {
      is = new pushbackinputstream(is, 8);
    }
    if (poifsfilesystem.haspoifsheader(is)) {
       return new hssfworkbook(is);
    }
    if (poixmldocument.hasooxmlheader(is)) {
      return new xssfworkbook(opcpackage.open(is));
    }
    throw new illegalargumentexception("您的excel版本目前不支持poi解析");
  }
 
  /**
   * 读取excel文件内容
   */
  public map<integer, list<string>> readexcel(string filepath) throws filenotfoundexception, fileformatexception {
    // 检查和获取workbook对象
    this.prereadcheck(filepath);
    workbook wb = null;
    map<integer,list<string>> map = new hashmap<integer, list<string>>();
    try {
      wb = this.getworkbook(filepath);
      // 默认只读取第一个sheet 
      sheet sheet = wb.getsheetat(0);
      int rowcount = sheet.getlastrownum();//逻辑行,包括空行
      int cellcount = sheet.getrow(0).getlastcellnum();//第一行(将来作为字段的行)有多少个单元格
      for (int i=0;i<rowcount;i++) {          //这里用最原始的for循环来保证每行都会被读取
         list<string> list = new arraylist<string>();
         row row = sheet.getrow(i);
         if(null!=row){
            for (int j=0;j<cellcount;j++) {
             list.add(getcellvalue(row.getcell(j)));  //这里也是用for循环,用cell c:row这样的遍历,空单元格就被抛弃了  
            }
            system.out.println("第"+(row.getrownum()+1)+"行数据:"+list.tostring());
            map.put(row.getrownum(), list); 
          }else{
            for (int j=0;j<cellcount;j++) {
              list.add("无数据");   
            }
            system.out.println("第"+(i+1)+"行数据:"+list.tostring());
            map.put(i, list);
        }     
      }    
    } catch (exception e) {
        system.out.println("读取excel异常:"+e.getmessage());
        e.printstacktrace();
      } finally {
         if (wb != null) {
           try {
               wb.close();
            } catch (ioexception e) {
               e.printstacktrace();
             }
         }
       }
    return map;   
  }
  /**
   * 取单元格的值
   */
  private string getcellvalue(cell c) {
    if (c == null) {
      return "无数据";
    }
    string value = "";
    switch (c.getcelltype()){
    case hssfcell.cell_type_numeric://数字
       value = c.getnumericcellvalue()+"";
    break;
    case hssfcell.cell_type_string://字符串
      value = c.getstringcellvalue();
    break;
    case hssfcell.cell_type_boolean://boolean
      value = c.getbooleancellvalue()+"";
    break;
    case hssfcell.cell_type_formula://公式
      value = c.getcellformula()+"";
    break;
    case hssfcell.cell_type_blank://空值
      value= "无数据";
     break;
    case hssfcell.cell_type_error:
      value = "非法字符";
     break;
    default:
      value= "未知类型";
     break;    
    }
    return value;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网