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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。