一次代碼重構之旅---Java讀取Excel(一)

最近工做須要一個讀取excel文件的工具,結合網絡資源寫了一個工具類,初步實現了功能。好,老樣子,先描述一下業務需求。(基於JFinal2.1版本)
java

  1. 讀取excel文件,雙方約定此文件模板內容,具體見下圖數據庫

  2. 後臺處理讀取數據並寫庫apache


分析了這個簡單的需求,其實要作的事情還不少,下面就分步驟動手開始作:數組

  1. 讀取excel數據網絡

  2. 由於要寫數據庫,因此要按map這種鍵值對來匹配讀取的數據xss

  3. 處理讀取的數據工具

  4. 寫庫spa

讀取excel文件數據

(看不明白不要緊,先往下看).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));
	}

設置key

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,那麼咱們就開始重構他,讓這些代碼更簡潔!

移步:一次代碼重構之旅(二 )

相關文章
相關標籤/搜索