有这么一个方法,用jxl包解析读取excel中值
public List getDataFromXLS(InputStream inputStream, boolean closeAFRead, String fileName, String dataClass, DictionaryBean dictBean) throws Exception { List list; Workbook workbook = null; try { IIntfConfigDAO intfConfigDAO = (IIntfConfigDAO) DAOFactory.getInstance().getDAO(IIntfConfigDAO.class); colMap = intfConfigDAO.getXLSConfig(fileName); workbook = Workbook.getWorkbook(inputStream); Sheet sheet = workbook.getSheet(0); int iCol = sheet.getColumns(); int i = 0; allWidth = 400; //得到所有列的名称及对应关系 for (i = 0; i < iCol; i++) { Cell cell = sheet.getCell(i, 0); if (cell == null) continue; String s = getCell(cell, ""); XLSConfig config = (XLSConfig) colMap.get(s); if (config == null) continue; config.setColNum(i); //config.setWidth(sheet.getColumnView(i).getSize()/256*10); allWidth += config.getWidth(); } //得到数据 i = 1; list = new ArrayList(); int iRow = sheet.getRows(); //修改 while (true) { if (i >= iRow) { //修改 break; } Cell cell1 = sheet.getCell(0, i); Cell cell2 = sheet.getCell(1, i); Cell cell3 = sheet.getCell(2, i); if (cell1 == null && cell2 == null && cell3 == null) break; if (StringUtils.isNULLString(getCell(cell1, "")) && StringUtils.isNULLString(getCell(cell2, "")) && StringUtils.isNULLString(getCell(cell3, ""))) { break; } Object obj = Class.forName(dataClass).newInstance(); XLSCommObj xlsCommObj = (XLSCommObj) obj; for (Iterator iter = colMap.values().iterator(); iter.hasNext();) { XLSConfig config = (XLSConfig) iter.next(); String xlsValue = null; if (config.getColNum() >= 0) { Cell cell = sheet.getCell(config.getColNum(), i); xlsValue = StringUtils.trim(getCell(cell, config.getMask())); BeanUtils.setProperty(obj, config.getFieldName(), xlsValue); } //取Key String key = xlsValue; String value = null; if(config.getColNum() == -1){ xlsCommObj.addErrorMsg(config.getFieldName(), config.getColName() + " 列不存在"); continue; } validateObj(xlsCommObj, config, key); if (StringUtils.isNULLString(xlsValue)) continue; if ("1".equals(config.getFillWithCode())) { if (xlsValue.indexOf(BizConstants.XLS_FILED_SELECT_COMMA) < 0) { xlsCommObj.addinvalidErrorMsg(config.getFieldName(), config.getColName()); } String[] keyValue = StringUtils.split(xlsValue, BizConstants.XLS_FILED_SELECT_COMMA); key = keyValue[0]; value = keyValue[1]; } if ("3".equals(config.getColType())) { //选择项自填 boolean isFindKey = false; String[] dicKeyValue = StringUtils.split(config.getValueBound(), ";"); if (!StringUtils.isNULLStringArray(dicKeyValue)) { for (int j = 0; j < dicKeyValue.length; j++) { String[] keyValue = StringUtils.split(dicKeyValue[j], BizConstants.XLS_FILED_SELECT_COMMA); if (StringUtils.equals(key, keyValue[0])) { isFindKey = true; value = keyValue[1]; break; } } } if (!isFindKey) { xlsCommObj.addNoExistsErrorMsg(config.getFieldName(), config.getColName()); } } else if ("4".equals(config.getColType())) { //选择项来自Dictionary value = dictBean.getLemmaValue(config.getValueBound(), key); if (StringUtils.isNULLString(value)) { xlsCommObj.addNoExistsErrorMsg(config.getFieldName(), config.getColName()); } } else if ("5".equals(config.getColType())) { //选择项来自定义SQL语句 value = intfConfigDAO.getCommSQLValue(config.getValueBound(), key); if (StringUtils.isNULLString(value)) { xlsCommObj.addNoExistsErrorMsg(config.getFieldName(), config.getColName()); } } if (!StringUtils.isNULLString(config.getCodeField())) { BeanUtils.setProperty(obj, config.getCodeField(), key); } if (!StringUtils.isNULLString(config.getCospField())) { BeanUtils.setProperty(obj, config.getCospField(), value); } } validateObjOther(xlsCommObj); list.add(obj); i++; } return list; } catch (Exception e) { throw e; } finally { if (workbook != null) workbook.close(); if (closeAFRead) StreamUtils.closeInputStream(inputStream); } }
注释“//修改”是后来补充上去的值。如果没有这些判断,在读取excel对与某些模板会报错。
报错的模板统一特征就是没有限定记录数。也就是说,模板中定义了一些列,可能还为每列定义了格式,但是行数默认是65535(单个sheet最大记录数)。
对于jxl来说,对于不限定列数的情况下,它会自动筛选掉空的记录。也就是比如有一个上述的模板,含标题一共60行,则sheet.getRows()为40。当你getCell时,jxl会判断你的行列值是否在【sheet.getRows(), sheet.getColumns()】范围内,若大于它,则抛出数组下标越界异常。
所以在调用getCell(x,y)时,一定要注意取值范围。