1. 程式人生 > >POI解析Excel之應用反射等技術實現動態讀取

POI解析Excel之應用反射等技術實現動態讀取

  1 package com.hdbs.resolver;
  2 
  3 import com.hdbs.common.Common;
  4 import com.hdbs.exceptions.ResolveFileException;
  5 import org.apache.commons.lang3.StringUtils;
  6 import org.apache.poi.hssf.usermodel.HSSFCell;
  7 import org.apache.poi.hssf.usermodel.HSSFRow;
  8 import org.apache.poi.hssf.usermodel.HSSFSheet;
9 import org.apache.poi.hssf.usermodel.HSSFWorkbook; 10 import org.apache.poi.xssf.usermodel.XSSFCell; 11 import org.apache.poi.xssf.usermodel.XSSFRow; 12 import org.apache.poi.xssf.usermodel.XSSFSheet; 13 import org.apache.poi.xssf.usermodel.XSSFWorkbook; 14 import org.slf4j.Logger; 15 import
org.slf4j.LoggerFactory; 16 17 import java.io.File; 18 import java.io.FileInputStream; 19 import java.io.IOException; 20 import java.io.InputStream; 21 import java.lang.reflect.InvocationTargetException; 22 import java.util.ArrayList; 23 import java.util.HashMap; 24 import java.util.List;
25 import java.util.Map; 26 27 /** 28 * @author :cnblogs-WindsJune 29 * @version :1.1.0 30 * @date :2018年9月20日 下午6:13:43 31 * @comments : 32 */ 33 34 public class ReadExcelUtil { 35 36 private static final Logger LOGGER = LoggerFactory.getLogger(ReadExcelUtil.class); 37 38 private Map<Integer,String []> fieldsMap=new HashMap<>(); 39 40 private List<Object> objectsList = new ArrayList<>(); 41 42 private Object object=null; 43 44 private String path =null; 45 46 public List<Object> getObjectsList() { 47 return this.objectsList; 48 } 49 50 public ReadExcelUtil(Object object,String path) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException { 51 this.object=object; 52 this.path=path; 53 readExcel(); 54 } 55 56 /** 57 * 新增Object到List中 58 * @param object 59 * @return 60 */ 61 public boolean addListObject(Object object){ 62 boolean isSucceed=this.objectsList.add(object); 63 return isSucceed; 64 } 65 66 /** 67 * 讀取excel,判斷是xls結尾(2010之前);還是xlsx結尾(2010以後)的Excel 68 * 69 * @return 70 * @throws IOException 71 */ 72 public boolean readExcel() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { 73 if (StringUtils.isEmpty(path)) { 74 return false; 75 } else { 76 // 擷取字尾名,判斷是xls還是xlsx 77 String postfix = path.substring(path.lastIndexOf(".") + 1); 78 if (!StringUtils.isEmpty(postfix)) { 79 if (Common.OFFICE_EXCEL_2003_POSTFIX_xls.equals(postfix)) { 80 return readXls(); 81 } else if (Common.OFFICE_EXCEL_2010_POSTFIX_xlsx.equals(postfix)) { 82 return readXlsx(); 83 } 84 } else { 85 LOGGER.error("檔案字尾名有誤!"); 86 throw new ResolveFileException("檔案字尾名有誤!" + "[" + path + "]"); 87 } 88 } 89 return false; 90 } 91 92 /** 93 * 讀取xls(2010)之後的Excel 94 * 95 * @return 96 * @throws IOException 97 */ 98 public boolean readXlsx() throws IOException{ 99 File file = new File(path); 100 InputStream is = new FileInputStream(file); 101 XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is); 102 // 遍歷sheet頁 103 for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) { 104 XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet); 105 String [] fields=null; 106 if (xssfSheet == null) { 107 continue; 108 } 109 // 迴圈行 110 for (int rowNum = 0; rowNum <= xssfSheet.getLastRowNum(); rowNum++) { 111 XSSFRow xssfRow = xssfSheet.getRow(rowNum); 112 int cloumns=xssfRow.getLastCellNum(); 113 int i=0; 114 //獲取第一行的所有屬性 115 if (rowNum == 0){ 116 fields=getFields(xssfRow,cloumns); 117 fieldsMap.put(numSheet,fields); 118 continue; 119 } 120 //遍歷資料,反射set值 121 while (i<cloumns){ 122 XSSFCell field=xssfRow.getCell(i); 123 String value=getValue(field); 124 try { 125 ReflectionInitValue.setValue(object,fields[i],value); 126 }catch ( Exception e ){ 127 throw new ResolveFileException(e.getMessage()); 128 } 129 i++; 130 } 131 //通過反射執行clone複製物件 132 Object result=ReflectionInitValue.invokeClone(object,"clone"); 133 this.addListObject(result); 134 // System.out.println(object.toString()); 135 } 136 } 137 return true; 138 } 139 140 /** 141 * 讀取xls(2010)之前的Excel 142 * 143 * @return 144 * @throws IOException 145 */ 146 public boolean readXls() throws IOException, ResolveFileException { 147 InputStream is = new FileInputStream(path); 148 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is); 149 // 遍歷sheet頁 150 for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) { 151 HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet); 152 String[] fields = null; 153 if (hssfSheet == null) { 154 continue; 155 } 156 // 迴圈行Row 157 for (int rowNum = 0; rowNum <= hssfSheet.getLastRowNum(); rowNum++) { 158 HSSFRow hssfRow = hssfSheet.getRow(rowNum); 159 int cloumns=hssfRow.getLastCellNum(); 160 int i=0; 161 //獲取第一行的所有屬性 162 if (rowNum == 0){ 163 //獲取屬性欄位 164 fields=getFields(hssfRow,cloumns); 165 fieldsMap.put(numSheet,fields); 166 continue; 167 } 168 //遍歷資料,反射set值 169 while (i<cloumns){ 170 HSSFCell field=hssfRow.getCell(i); 171 String value=getValue(field); 172 try { 173 ReflectionInitValue.setValue(object,fields[i],value); 174 }catch ( Exception e ){ 175 throw new ResolveFileException(e.getMessage()); 176 } 177 i++; 178 } 179 //通過反射執行clone複製物件 180 Object result=ReflectionInitValue.invokeClone(object,"clone"); 181 this.addListObject(result); 182 } 183 } 184 return true; 185 } 186 187 /** 188 * xlsx -根據資料型別,獲取單元格的值 189 * @param xssfRow 190 * @return 191 */ 192 @SuppressWarnings({ "static-access" }) 193 private static String getValue(XSSFCell xssfRow) { 194 String value=null; 195 try { 196 if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) { 197 // 返回布林型別的值 198 value=String.valueOf(xssfRow.getBooleanCellValue()).replace(" ",""); 199 } else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) { 200 // 返回數值型別的值 201 value= String.valueOf(xssfRow.getNumericCellValue()).replace(" ",""); 202 } else { 203 // 返回字串型別的值 204 value= String.valueOf(xssfRow.getStringCellValue()).replace(" ",""); 205 } 206 } catch (Exception e) { 207 //單元格為空,不處理 208 value=null; 209 LOGGER.error("單元格為空!"); 210 } 211 return value; 212 } 213 214 /** 215 * xls-根據資料型別,獲取單元格的值 216 * @param hssfCell 217 * @return 218 */ 219 @SuppressWarnings({ "static-access" }) 220 private static String getValue(HSSFCell hssfCell) { 221 String value=null; 222 try { 223 if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) { 224 // 返回布林型別的值 225 value=String.valueOf(hssfCell.getBooleanCellValue()).replaceAll(" ",""); 226 } else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) { 227 // 返回數值型別的值 228 value=String.valueOf(hssfCell.getNumericCellValue()).replaceAll(" ",""); 229 } else { 230 // 返回字串型別的值 231 value=String.valueOf(hssfCell.getStringCellValue()).replaceAll(" ",""); 232 } 233 } catch (Exception e) { 234 //單元格為空,不處理 235 value=null; 236 LOGGER.error("單元格為空!"); 237 } 238 return value; 239 } 240 241 /** 242 * xls Excel檔案型別獲取屬性(2010之前) 243 * @param cloumns 244 * @return String[] 245 */ 246 private static String[] getFields (HSSFRow hssfRow,int cloumns){ 247 String [] fields=new String[cloumns]; 248 int i=0; 249 try { 250 while (i<cloumns){ 251 HSSFCell field=hssfRow.getCell(i); 252 String value=getValue(field); 253 fields[i]=value.trim(); 254 i++; 255 } 256 }catch ( Exception e){ 257 throw new ResolveFileException("獲取屬性集失敗!"); 258 } 259 return fields; 260 } 261 262 /** 263 * xlsx Excel檔案型別獲取屬性(2010之後) 264 * @param cloumns 265 * @return String[] 266 */ 267 private static String[] getFields(XSSFRow xssfRow,int cloumns){ 268 String [] fields=new String[cloumns]; 269 int i=0; 270 try { 271 while (i<cloumns){ 272 XSSFCell field=xssfRow.getCell(i); 273 String value=getValue(field); 274 fields[i]=value.trim(); 275 i++; 276 } 277 }catch ( Exception e ){ 278 throw new ResolveFileException("獲取屬性集失敗!"); 279 } 280 return fields; 281 } 282 283 }