Java 解析Excel(兼容03和07) 附带将excel数据封装成指定对象
对象(- -~!懒,所以直接用项目的,字段比较多,省略get set)
public class TravelerInfo { private Long id;// private Long flight_id;//航班ID private String airline_code;//航空公司 private String flight_num;//航班号 private String flight_suffix;//航班后缀 private Date sto;//最新的航班时刻,根据出入港类别,可能和起飞到达时间重合 private String movement_indicator;//A,D,C(原系统0为进港,1为出港) private String surname;//姓 private String given_nm;//名 private String nationality;//国籍 private String gender;//性别(F|M|U) private Date bday;//出生日期 private String offl_td_type;//有效旅行证件类别 private String offl_td_nbr;//有效旅行证件号码 private Date offl_td_exp_date;//有效旅行证件失效日期 private Long offl_td_exp_ind;//有效旅行证件失效标识(0|1) private String offl_td_cntry;//有效旅行证件签发国或组织 private String traveler_type;//人员类别(FL|FM|DDT|DDU) private String dept_arpt;//最初登机机场 private String arrv_arpt;//最后下机机场 private String dest_addr;//目的地地址 private String clearance_arpt;//清关机场 private String res_cntry;//主要居住国 private String birth_cntry;//出生国 private String pnr;//PNR参考信息 private String othr_td_type;//第二证件类别 private String othr_td_nbr;//第二证件号码 private Date othr_td_exp_date;//第二证件失效日期 private Long othr_td_exp_ind;//第二证件失效标识(0|1) private Date othr_td_iss;//第二证件签发日期 private String othr_td_cntry;//第二证件签发国或组织 private String memo;//备注 private String age_nbr;//年龄 private String age_cls;//成人儿童标识(I|C|A|S)I:婴儿 C:儿童 A:成人 private String iti_type;//行程类别(E|F|L|S) //省略 get set }
Excel 辅助类
package com.travelsky.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; 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.struts2.ServletActionContext; import com.travelsky.airlinemanage.model.TravelerInfo; import com.travelsky.util.DateUtil; public class ExcelHand { /** 总行数 */ private int totalRows = 0; /** 总列数 */ private int totalCells = 0; /** 错误信息 */ private String errorInfo; /** 构造方法 */ public ExcelHand() { } /** * * @描述:得到总行数 * @参数:@return * * @返回值:int */ public int getTotalRows() { return totalRows; } /** * * @描述:得到总列数 * @参数:@return * * @返回值:int */ public int getTotalCells() { return totalCells; } /** * * @描述:得到错误信息 * * @参数:@return * * @返回值:String */ public String getErrorInfo() { return errorInfo; } /** * * @描述:验证excel文件 * * @参数:@param filePath 文件完整路径 * * @参数:@return * * @返回值:boolean */ public boolean validateExcel(String filePath) { /** 检查文件名是否为空或者是否是Excel格式的文件 */ if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath))) { errorInfo = "文件名不是excel格式"; return false; } System.out.println(filePath); /** 检查文件是否存在 */ File file = new File(filePath); if (file == null || !file.exists()) { errorInfo = "文件不存在"; return false; } return true; } /** * * @描述:根据文件名读取excel文件 * * @参数:@param filePath 文件完整路径 * * @参数:@return * * @返回值:List */ public List<List<String>> read(String filePath) { //String filePath = ServletActionContext.getServletContext().getRealPath(path); List<List<String>> dataLst = new ArrayList<List<String>>(); InputStream is = null; try { /** 验证文件是否合法 */ if (!validateExcel(filePath)) { System.out.println(errorInfo); return null; } /** 判断文件的类型,是2003还是2007 */ boolean isExcel2003 = true; if (WDWUtil.isExcel2007(filePath)) { isExcel2003 = false; } /** 调用本类提供的根据流读取的方法 */ File file = new File(filePath); is = new FileInputStream(file); dataLst = read(is, isExcel2003); is.close(); } catch (Exception ex) { ex.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { is = null; e.printStackTrace(); } } } /** 返回最后读取的结果 */ return dataLst; } /** * * @描述:根据流读取Excel文件 * * @参数:@param inputStream * * @参数:@param isExcel2003 * * @参数:@return * * @返回值:List */ public List<List<String>> read(InputStream inputStream, boolean isExcel2003) { List<List<String>> dataLst = null; try { /** 根据版本选择创建Workbook的方式 */ Workbook wb = null; if (isExcel2003) { wb = new HSSFWorkbook(inputStream); } else { wb = new XSSFWorkbook(inputStream); } dataLst = read(wb); } catch (IOException e) { e.printStackTrace(); } return dataLst; } /** * * @描述:读取数据 * * @参数:@param Workbook * * @参数:@return * * @返回值:List<List<String>> */ private List<List<String>> read(Workbook wb) { List<List<String>> dataLst = new ArrayList<List<String>>(); /** 得到第一个shell */ Sheet sheet = wb.getSheetAt(0); /** 得到Excel的行数 */ this.totalRows = sheet.getPhysicalNumberOfRows(); /** 得到Excel的列数 */ if (this.totalRows >= 1 && sheet.getRow(0) != null) { this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells(); } /** 循环Excel的行 */ for (int r = 0; r < this.totalRows; r++) { Row row = sheet.getRow(r); if (row == null) { continue; } List<String> rowLst = new ArrayList<String>(); /** 循环Excel的列 */ for (int c = 0; c < this.getTotalCells(); c++) { Cell cell = row.getCell(c); //String key=row.getCell(0).getStringCellValue(); String cellValue = ""; if (null != cell) { //cellValue=cell.getStringCellValue(); // 以下是判断数据的类型 switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC: // 数字 //cellValue = cell.getNumericCellValue() + ""; if (HSSFDateUtil.isCellDateFormatted(cell)) { // 如果是Date类型则,取得该Cell的Date值 Date date = cell.getDateCellValue(); // 把Date转换成本地格式的字符串 cellValue = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"); System.out.println(cellValue); } // 如果是纯数字 else { // 取得当前Cell的数值 Integer num = new Integer((int) cell.getNumericCellValue()); cellValue = String.valueOf(num); } break; case HSSFCell.CELL_TYPE_STRING: // 字符串 cellValue = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean cellValue = cell.getBooleanCellValue() + ""; break; case HSSFCell.CELL_TYPE_FORMULA: // 公式 cellValue = cell.getCellFormula() + ""; break; case HSSFCell.CELL_TYPE_BLANK: // 空值 cellValue = ""; break; case HSSFCell.CELL_TYPE_ERROR: // 故障 cellValue = "非法字符"; break; default: cellValue = "未知类型"; break; } } // System.out.print(cellValue+" "); rowLst.add(cellValue); } // System.out.println(); /** 保存第r行的第c列 */ dataLst.add(rowLst); } return dataLst; } /** * 将excel解析后的集合封装成Map形式,在这我没有直接在excel解析的时候就封装,看个人需求 * @param list * @return */ public static List<Map<String,String>> reflectMapList(List<List<String>> list){ ExcelHand poi = new ExcelHand(); List<Map<String, String>> mlist=new ArrayList<Map<String,String>>(); Map<String, String> map = new HashMap<String, String>(); if (list != null) { for (int i = 1; i < list.size(); i++) { map = new HashMap<String, String>(); // System.out.print("第" + (i) + "行"); List<String> cellList = list.get(i); for (int j = 0; j < cellList.size(); j++) { map.put(list.get(0).get(j), cellList.get(j)); // System.out.print(" 第" + (j + 1) + "列值:"); // System.out.print(list.get(0).get(j)+"--" + cellList.get(j)+" "); } //System.out.println(); //System.out.println(map); mlist.add(map); } } return mlist; } } /** * * @描述:工具类 */ class WDWUtil { /** * * @描述:是否是2003的excel,返回true是2003 * * @参数:@param filePath 文件完整路径 * * @参数:@return * * @返回值:boolean */ public static boolean isExcel2003(String filePath) { return filePath.matches("^.+\\.(?i)(xls)$"); } /** * * @描述:是否是2007的excel,返回true是2007 * * @参数:@param filePath 文件完整路径 * * @参数:@return * * @返回值:boolean */ public static boolean isExcel2007(String filePath) { return filePath.matches("^.+\\.(?i)(xlsx)$"); } }
excel 里有个日期的处理
cellValue = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
public class DateUtil { public static Date date = null; public static DateFormat dateFormat = null; public static Calendar calendar = null; /** * 功能描述:格式化日期 * * @param dateStr * String 字符型日期 * @param format * String 格式 * @return Date 日期 */ public static Date parseDate(String dateStr, String format) { try { dateFormat = new SimpleDateFormat(format); String dt = dateStr.replaceAll("-", "/"); if ((!dt.equals("")) && (dt.length() < format.length())) { dt += format.substring(dt.length()).replaceAll("[YyMmDdHhSs]", "0"); } date = (Date) dateFormat.parse(dt); } catch (Exception e) { } return date; } }
Tool 工具类
Tool
package com.travelsky.util; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; public class Tool { /** * 反射实体类 并匹配字段 * * @param <E> * @param c * @param list * @return * @throws Exception */ public static <E> List reflectObj(Class<E> c, List<Map<String,String>> list) { SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat formatDate2 = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); try { // Object object = Class.forName(c.getName()).newInstance(); Method methodArray[] = Class.forName(c.getName()) .getDeclaredMethods(); // Class<?> obj = object.getClass(); // Field[] fields = obj.getDeclaredFields(); E entity = c.newInstance(); List newlist = new ArrayList(); boolean fla = false; for (int j = 0; j < list.size(); j++) { entity = c.newInstance(); for (int m = 0; m < methodArray.length; m++) { fla = true; try { String key = methodArray[m].getName().substring(3) .toUpperCase(); if(!list.get(j).containsKey(key)){ //fla = false; continue; } if ((methodArray[m].getName().substring(0, 3) .equalsIgnoreCase("set"))) { // System.out.print(key+"--"+list.get(j).containsKey(key)+"--"+list.get(j).get(key)+" "); Class[] type = methodArray[m].getParameterTypes(); // System.out.print(type[0].getName()); String value = list.get(j).get(key).toString(); //类型匹配并强转 if (type[0].getName().equals("java.lang.String")) { methodArray[m].invoke(entity, list.get(j).get(key)); } if (type[0].getName().equals("java.lang.Integer")) { methodArray[m].invoke(entity, Integer.parseInt(value)); } if (type[0].getName().equals("java.lang.Double")) { methodArray[m].invoke(entity, Double.parseDouble(value)); } if (type[0].getName().equals("java.lang.Long")) { methodArray[m].invoke(entity, Long.parseLong(value)); } if (type[0].getName().equals("java.lang.Boolean")) { methodArray[m].invoke(entity, Boolean.parseBoolean(value)); } if (type[0].getName().equals("java.util.Date")) { try { methodArray[m].invoke(entity, formatDate2.parse(value)); } catch (Exception e1) { // TODO Auto-generated catch block methodArray[m].invoke(entity, formatDate.parse(value)); } } // System.out.println(list.get(j).get(key).toString()); } } catch (Exception e1) { // TODO Auto-generated catch block System.out.println(e1); fla = false; } } if (fla) { System.out.println("反射第" + (j + 1) + "个对象结束~!"+entity.toString()); newlist.add(entity); fla = false; } ; } return newlist; } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return null; } }
测试方法:
/** * * @描述:main测试方法 * * @参数:@param args * * @参数:@throws Exception * * @返回值:void */ public static void main(String[] args) throws Exception { ExcelHand poi = new ExcelHand(); //获取解析后的集合 List<List<String>> lists = poi.read("d:/test.xlsx"); System.out.println(lists.size()); //对集合进行重新组装 Map<字段,值> List<Map<String,String>> list= ExcelHand.reflectMapList(lists); //调用工具类,组成对象集合 List<TravelerInfo> ts=Tool.reflectObj(TravelerInfo.class, list); //遍历 for (TravelerInfo t : ts) { System.out.println(t.getAirline_code()+" | "+ t.getFlight_num()+" | "+t.getSto()+" | "+t.getNationality()+"| ………………"); } }
效果图:
测试使 用Excel(只复制了几个字段上来……比对下效果)
AIRLINE_CODE | FLIGHT_NUM | FLIGHT_SUFFIX | STO | MOVEMENT_INDICATOR | SURNAME | GIVEN_NM | NATIONALITY |
ET | 1 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 2 | 2012-03-14 15:45:00 | A | NYD | EBBA INGA | SWE | |
ET | 3 | 2012-03-14 15:45:00 | A | NYD | PER HAAKAN | SWE | |
ET | 4 | 2012-03-14 15:45:00 | A | ODELBERG | DAN INGEMAR MALTE | SWE | |
ET | 5 | 2012-03-14 15:45:00 | A | LARBI AISSA | LATIFA | FRA | |
ET | 6 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 7 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 8 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 9 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 10 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 11 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 12 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 13 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA | |
ET | 14 | 2012-03-14 15:45:00 | A | NUNAN | RONALD CORYELL | USA |
不足之处请指正……
部分jar:
poi-3.8-20120326.jar
poi-ooxml-3.8-20120326.jar
xmlbeans-2.3.0.jar
poi-ooxml-schemas-3.8-20120326.jar
dom4j-1.6.1.jar
log4j-1.2.13.jar