如下excel表格,按照表頭名字讀取數據,允許表頭增加無意義空格,允許表頭順序交換。
序號 | 隧道左公里標 | 隧道右公里標 | 是否隧道 |
1 | DK2291.416 | DK0 | 是 |
2 | DK7389.65 | DK2291.416 | 否 |
3 | ZK2277 | ZK0 | 是 |
4 | ZK5235.68 | ZK2277 | 否 |
/** * * 讀取指定sheet 頁指定行<T>數據 * * @param sheetIx 指定 sheet 頁,從 0 開始 * @param start 指定開始行,從 0 開始 * @param end 指定結束行,從 0 開始 * @return * @throws Exception */ @SuppressWarnings({ "rawtypes", "unchecked" }) public List<List<T>> readGeneric(int sheetIx, int start, int end, T t) throws Exception { Sheet sheet = workbook.getSheetAt(sheetIx); List<List<T>> list = new ArrayList<List<T>>(); if (end > getRowCount(sheetIx)) { end = getRowCount(sheetIx); } List<Integer> colNums = new ArrayList<Integer>(); for (int i = start; i <= end; i++) { List<T> rowList = new ArrayList<T>(); Row row = sheet.getRow(i); List rowdata = getRowdata(row); Class clazz = t.getClass(); Object fa= clazz.newInstance(); Method method = t.getClass().getMethod("getLdcode", new Class[]{}); String[] ldcode = (String[])method.invoke(fa, new Object[]{}); //處理從0行開始取得請求 if(0 == start) { //處理請求的第0行,即表頭 if(i == 0) { //通過反射獲取模板類的實例 try { String simpleName = t.getClass().getSimpleName(); String StrEnumClass = simpleName.substring(0, simpleName.length()-5) + "Enum"; Class EnumClass = Class.forName("com.crscd.config.service.cbtc2.atp.excel.enums."+StrEnumClass); //Object enumInstance = EnumClass.newInstance(); for(int j = 0; j < rowdata.size(); j++) { //去除表頭上空格、回車、換行符、製表符 if(null != rowdata.get(j) && !"".equals(rowdata.get(j))) { Pattern p = Pattern.compile("\\s*|\t|\r|\n"); String str = (String)rowdata.get(j); Matcher m = p.matcher(str); String excelData = m.replaceAll(""); //獲取表頭對應的工具類中ldcode位置 Method met = EnumClass.getMethod("getStatus", String.class); int col = (int) met.invoke(Object.class, excelData); colNums.add(col); }else { colNums.add(-1); } } }catch(ClassNotFoundException e) { //e.printStackTrace(); } } } for(int j = 0; j < colNums.size(); j++) { int k = j; //如果映射表頭列和數據列不匹配,當數據列小於映射表頭列時,說明excel有無效列,則不足的列用空串補足 if (colNums.size() > rowdata.size() ) { rowdata.add(""); } if(0 == start && !colNums.isEmpty()) { k = colNums.get(j); } if(k == -1) { continue; }else { try { method = t.getClass().getMethod("set"+ldcode[k], String.class); method.invoke(fa, rowdata.get(j)); //如果映射表頭列和數據列不匹配,是excel多餘無效行列,則越界,仍保留未越界之前的全部數據。 }catch(IndexOutOfBoundsException e) { continue; } } } rowList.add((T) fa); list.add(rowList); } return list; }
package com.crscd.config.service.cbtc2.atp.excel; public class TunnelUtils<T> implements Comparable<TunnelUtils<T>>,Cloneable{ private String[] ldcode = { "Id", "TunnelLeftKilo", "TunnelRightKilo", "IsTunnel" }; private String id; private String tunnelLeftKilo; private String tunnelRightKilo; private String isTunnel; public String[] getLdcode() { return ldcode; } public void setLdcode(String[] ldcode) { this.ldcode = ldcode; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTunnelLeftKilo() { return tunnelLeftKilo; } public void setTunnelLeftKilo(String tunnelLeftKilo) { this.tunnelLeftKilo = tunnelLeftKilo; } public String getTunnelRightKilo() { return tunnelRightKilo; } public void setTunnelRightKilo(String tunnelRightKilo) { this.tunnelRightKilo = tunnelRightKilo; } public String getIsTunnel() { return isTunnel; } public void setIsTunnel(String isTunnel) { this.isTunnel = isTunnel; } @Override public int compareTo(TunnelUtils<T> o) { if(Double.parseDouble(stringGetNum(tunnelLeftKilo))<Double.parseDouble(stringGetNum(o.getTunnelLeftKilo()))) { return -1; } if(Double.parseDouble(stringGetNum(tunnelLeftKilo))>Double.parseDouble(stringGetNum(o.getTunnelLeftKilo()))) { return 1; } return 0; } //字符串取數 public String stringGetNum(String str) { String str2 = ""; if(str != null && !"".equals(str)){ for(int i=0;i<str.length();i++){ if((str.charAt(i)>=48 && str.charAt(i)<=57) || str.charAt(i)==46){ str2+=str.charAt(i); } } return str2; } return str; } @Override public Object clone() { TunnelUtils<T> stu = null; try{ stu = (TunnelUtils<T>)super.clone(); }catch(CloneNotSupportedException e) { e.printStackTrace(); } return stu; } }
package com.crscd.config.service.cbtc2.atp.excel.enums; import java.util.regex.Pattern; public enum TunnelEnum { id("序號",0), tunnelLeftKilo("隧道左公里標",1), tunnelRightKilo("隧道右公里標",2), isTunnel("是否隧道",3); private final String msg; private final int status; TunnelEnum(String msg,int status) { this.msg = msg; this.status = status; } //動態匹配表頭名字,允許加空,加無意義字符 public static int getStatus(String str) { str = str.replaceAll("\\(", "\\\\("); str = str.replaceAll("\\)", "\\\\)"); String pattern = "^"+str+".*"; for(TunnelEnum e : TunnelEnum.values()) { if(Pattern.matches(pattern, e.msg)) { return e.status; } } return -1; } }
excel的數據如下:
序號 | 隧道左公里標 | 隧道右公里標 | 是否隧道 |
1 | DK2291.416 | DK0 | 是 |
2 | DK7389.65 | DK2291.416 | 否 |
3 | ZK2277 | ZK0 | 是 |
4 | ZK5235.68 | ZK2277 | 否 |