最近工做須要一個讀取excel文件的工具,結合網絡資源寫了一個工具類,初步實現了功能。好,老樣子,先描述一下業務需求。(基於JFinal2.1版本)
java
讀取excel文件,雙方約定此文件模板內容,具體見下圖數據庫
後臺處理讀取數據並寫庫apache
分析了這個簡單的需求,其實要作的事情還不少,下面就分步驟動手開始作:數組
讀取excel數據網絡
由於要寫數據庫,因此要按map這種鍵值對來匹配讀取的數據xss
處理讀取的數據工具
寫庫spa
(看不明白不要緊,先往下看).net
/** * 讀取Excel2003-2007文件 .xls * @param path * @return * @throws Exception */ public List<Map<String,String>> readXls(String path) throws Exception{ InputStream is = new FileInputStream(path); //建立對象 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is); List<Map<String,String>> lists = new ArrayList<Map<String,String>>(); //獲取sheet工做表 for(int numSheet=0;numSheet<hssfWorkbook.getNumberOfSheets();numSheet++){ HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet); if(hssfSheet==null){ continue; } for(int rowNum=1;rowNum<=hssfSheet.getLastRowNum();rowNum++){ HSSFRow hssfRow = hssfSheet.getRow(rowNum); if(hssfRow == null){ throw new Exception("第"+ (rowNum+1) +"行有空行"); } int minColIndex = hssfRow.getFirstCellNum(); int maxColIndex = hssfRow.getLastCellNum(); getListMapBy2003(lists, hssfRow, minColIndex, maxColIndex); } System.out.println(JsonKit.toJson(lists)); } return lists; } /** * 按heads構建map * @param lists * @param hssfRow * @param minColIndex * @param maxColIndex */ private void getListMapBy2003(List<Map<String, String>> lists, HSSFRow hssfRow, int minColIndex, int maxColIndex) { Map<String, String> map = new HashMap<String, String>(); String[] heads = getHead(); for(int colIndex=minColIndex;colIndex<maxColIndex;colIndex++){ HSSFCell cell = hssfRow.getCell(colIndex+1); if(cell == null){//處理列爲空 if(colIndex<heads.length){ map.put(heads[colIndex], ""); } continue; } if(colIndex<heads.length){ map.put(heads[colIndex], getValue(cell));//構建map鍵值對 } lists.add(map); } System.out.println(JsonKit.toJson(map)); }
public String[] getHead(){ String[] heads = new String[]{"code","name","cate","price","hot","pop","remark"}; return heads; }
這裏有必要解釋一下爲啥這麼作excel
首先回頭看約定好的excel文件內容,在插入數據庫時第一列的【序號】是不須要寫庫的,只要將以後的每列數據匹配好就行,可是標題是中文不能直接用,所以咱們就寫上面這個方法來保存咱們要用到的key,基本上咱們須要拿到這樣的數據:
{"code":"0001","name":"牛排","cate":"招牌菜","price":"22.00","hot":"1","pop":"1","remark":"隆重推薦"};
key就是heads數組的值,value就是咱們讀取的每一列數據。
private String getValue(XSSFCell xssfRow) { if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) { return String.valueOf(xssfRow.getBooleanCellValue()); } else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) { return String.valueOf(xssfRow.getNumericCellValue()); } else { return String.valueOf(xssfRow.getStringCellValue()); } }
好,咱們先把所作代碼總體放出來
package com.feng.excel; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.jfinal.kit.JsonKit; public class ReadExcel3 { public static final String EXCEL2003 = "xls"; public static final String EXCEL2010 = "xlsx"; public static final String EMPTY = ""; public static String getFix(String path){ if(path.trim()!=null){ return path.substring(path.lastIndexOf(".")+1, path.length()); } return EMPTY; } public String[] getHead(){ String[] heads = new String[]{"code","name","cate","price","hot","pop","remark"}; return heads; } /** * 讀取Excel2010文件 .xlsx * @param path * @return * @throws Exception */ public List<Map<String,String>> readXlsx(String path) throws Exception{ InputStream is = new FileInputStream(path); //建立對象 XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is); List<Map<String,String>> lists = new ArrayList<Map<String,String>>(); //獲取sheet工做表 for(XSSFSheet xssfSheet : xssfWorkbook){ if(xssfSheet == null){ continue; } //遍歷除標題外全部的行 for(int rowNum=1;rowNum<=xssfSheet.getLastRowNum();rowNum++){ XSSFRow row = xssfSheet.getRow(rowNum); if(row == null){ throw new Exception("第"+ (rowNum+1) +"行有空行"); } int minColIndex = row.getFirstCellNum(); int maxColIndex = row.getLastCellNum(); getListMapBy2010(lists, row, minColIndex, maxColIndex); } System.out.println(JsonKit.toJson(lists)); } return lists; } /** * 讀取Excel2003-2007文件 .xls * @param path * @return * @throws Exception */ public List<Map<String,String>> readXls(String path) throws Exception{ InputStream is = new FileInputStream(path); //建立對象 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is); List<Map<String,String>> lists = new ArrayList<Map<String,String>>(); //獲取sheet工做表 for(int numSheet=0;numSheet<hssfWorkbook.getNumberOfSheets();numSheet++){ HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet); if(hssfSheet==null){ continue; } for(int rowNum=1;rowNum<=hssfSheet.getLastRowNum();rowNum++){ HSSFRow hssfRow = hssfSheet.getRow(rowNum); if(hssfRow == null){ throw new Exception("第"+ (rowNum+1) +"行有空行"); } int minColIndex = hssfRow.getFirstCellNum(); int maxColIndex = hssfRow.getLastCellNum(); getListMapBy2003(lists, hssfRow, minColIndex, maxColIndex); } System.out.println(JsonKit.toJson(lists)); } return lists; } /** * 按heads構建map * @param lists * @param hssfRow * @param minColIndex * @param maxColIndex */ private void getListMapBy2003(List<Map<String, String>> lists, HSSFRow hssfRow, int minColIndex, int maxColIndex) { Map<String, String> map = new HashMap<String, String>(); String[] heads = getHead(); for(int colIndex=minColIndex;colIndex<maxColIndex;colIndex++){ HSSFCell cell = hssfRow.getCell(colIndex+1); if(cell == null){//處理列爲空 if(colIndex<heads.length){ map.put(heads[colIndex], ""); } continue; } if(colIndex<heads.length){ map.put(heads[colIndex], getValue(cell));//構建map鍵值對 } lists.add(map); } System.out.println(JsonKit.toJson(map)); } /** * 按heads構建map * @param lists * @param row * @param minColIndex * @param maxColIndex */ private void getListMapBy2010(List<Map<String,String>> lists, XSSFRow xssfRow, int minColIndex, int maxColIndex){ Map<String, String> map = new HashMap<String, String>(); String[] heads = getHead(); for(int colIndex=minColIndex;colIndex<maxColIndex;colIndex++){ XSSFCell cell = xssfRow.getCell(colIndex+1); if(cell == null){//處理列爲空 if(colIndex<heads.length){ map.put(heads[colIndex], ""); } continue; } if(colIndex<heads.length){ map.put(heads[colIndex], getValue(cell));//構建map鍵值對 } lists.add(map); } System.out.println(JsonKit.toJson(map)); } @SuppressWarnings("static-access") private String getValue(XSSFCell xssfRow) { if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) { return String.valueOf(xssfRow.getBooleanCellValue()); } else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) { return String.valueOf(xssfRow.getNumericCellValue()); } else { return String.valueOf(xssfRow.getStringCellValue()); } } @SuppressWarnings("static-access") private String getValue(HSSFCell hssfCell) { if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) { return String.valueOf(hssfCell.getBooleanCellValue()); } else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) { return String.valueOf(hssfCell.getNumericCellValue()); } else { return String.valueOf(hssfCell.getStringCellValue()); } } public static void main(String[] args) { String path = "E:\\cai.xlsx"; try { if(getFix(path).equals(EXCEL2003)){ System.out.println("讀取2003Excel文件"); new ReadExcel3().readXls(path); }else if(getFix(path).equals(EXCEL2010)){ System.out.println("讀取2010Excel文件"); new ReadExcel3().readXlsx(path); }else{ System.out.println("讀取失敗:請上傳xls或xlsx文件!"); } System.out.println("讀取結束"); } catch (Exception e) { e.printStackTrace(); } } }
雖然以上代碼已經實現了讀取excel文件數據,可是看到一些重複的代碼,是否是很噁心?OK,那麼咱們就開始重構他,讓這些代碼更簡潔!