评论

收藏

[Java] java如何读取Excel简单模板

编程语言 编程语言 发布于:2021-10-08 11:06 | 阅读数:227 | 评论:0

这篇文章主要为大家详细介绍了java如何读取Excel简单模板,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
场景:对于经常需要导入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;
  }
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CodeAE代码之家
原文链接:https://www.cnblogs.com/yb38156/p/9821804.html

关注下面的标签,发现更多相似文章