一次代码重构之旅(二)

开始重构

首先,经过上面的代码以后我们初步了解到在读取Excel文件时是根据文件的后缀来决定使用哪个方法,因此可采用类似工厂模式来实现。其次,在读取到数据后最终是要写库然后读库再返回,这一系列的操作与文件类型无关。

1.定义一个父类,抽象的

package com.feng.excel;

import java.util.List;

import com.feng.model.BsMenu;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

/**
 * 
 * @author zhulinfeng
 * @时间 2016年1月28日下午3:47:17
 *
 */
public abstract class ReadFile{

	/**
	 * 批量插入读取的数据
	 * @param path
	 * @return
	 * @throws Exception
	 */
	public List<Record> getMenuRecord(String path) throws Exception{
		BsMenu.deleteMenu();
		List<Record> list = readExcel(path);
		Db.batchSave("bs_menu", list, 100);
		return BsMenu.getMenu();
	}
	
	/**
	 * 子类重写
	 * @param path
	 * @return
	 * @throws Exception
	 */
	protected abstract List<Record> readExcel(String path) throws Exception;
	
	/**
	 * 数据库字段
	 * @return
	 */
	public String[] getHead(){
		String[] heads = new String[]{"code","name","cate","price","hot","pop","remark"};
		return heads;
	}
	
}

2.子类

package com.feng.excel;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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.feng.util.ExcelUtil;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Record;

public class Read2010Excel extends ReadFile {

	@Override
	protected List<Record> readExcel(String path) throws Exception {
		InputStream is = new FileInputStream(path);
		// 创建对象
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
		List<Record> lists = new ArrayList<Record>();
		// 获取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();
				getListRecordBy2010(lists, row, minColIndex, maxColIndex);
			}
			System.out.println(JsonKit.toJson(lists));
		}
		return lists;
	}

	/**
	 * 按heads构建map 
	 * @param lists
	 * @param xssfRow
	 * @param minColIndex
	 * @param maxColIndex
	 */
	private void getListRecordBy2010(List<Record> lists, XSSFRow xssfRow, int minColIndex, int maxColIndex) {
		Record record = new Record();
		String[] heads = getHead();
		for (int colIndex = minColIndex; colIndex < maxColIndex; colIndex++) {
			XSSFCell cell = xssfRow.getCell(colIndex + 1);
			if (cell == null) {// 处理列为空
				if (colIndex < heads.length) {
					record.set(heads[colIndex], "");
				}
				continue;
			}
			if (colIndex < heads.length) {
				record.set(heads[colIndex], ExcelUtil.getValue(cell));
			}
		}
		lists.add(record);
	}

}

3.工厂方法

package com.feng.excel;

/**
 * 工厂方法
 * 按照文件类型读取
 * @author zhulinfeng
 * @时间 2016年1月28日下午3:45:41
 *
 */
public class ReadExcelFactory {
	
	public static final String EXCEL2003 = "xls";
	public static final String EXCEL2010 = "xlsx";
	public static final String EMPTY = "";

	public static ReadFile getReadExcelFile(String path){
		String fileFix = getFix(path);
		if(null==path){
			return null;
		}
		if(fileFix.equals(EXCEL2003)){
			return new Read2003Excel();
		}
		if(fileFix.equals(EXCEL2010)){
			return new Read2010Excel();
		}
		return null;
	}
	
	/**
	 * 获取文件后缀
	 * @param path
	 * @return
	 */
	private static String getFix(String path) {
		if (path.trim() != null) {
			return path.substring(path.lastIndexOf(".") + 1, path.length());
		}
		return EMPTY;
	}
}

4.测试

注意:在不启动项目时如果想使用单元测试JFinal必须要加载数据库插件,因此我们在测试类中使用@BeforeCLass字样加载相关插件。否则无法操作数据库!

package com.test;

import org.junit.Test;

import com.feng.excel.ReadExcelFactory;
import com.feng.excel.ReadFile;
import com.jfinal.kit.JsonKit;

public class ExcelTest{

	@BeforeClass
	public static void Before(){
		PropKit.use("config.txt");
		C3p0Plugin c3p0Plugin = ExcelConfig.createC3p0Plugin();
		c3p0Plugin.start();

		ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin);
		arp.setShowSql(true);
		// 所有配置在 MappingKit 中搞定
		_MappingKit.mapping(arp);
		arp.start();
	}
	
	@Test
	public void test(){
		String path = "E:\\cai.xls";
		try {
			ReadFile readFile = ReadExcelFactory.getReadExcelFile(path);
			System.out.println(JsonKit.toJson(readFile.getMenuRecord(path)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


其中model相关的内容:

package com.feng.model;

import java.util.List;

import com.feng.model.base.BaseBsMenu;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

/**
 * Generated by JFinal.
 */
@SuppressWarnings("serial")
public class BsMenu extends BaseBsMenu<BsMenu> {
	public static final BsMenu dao = new BsMenu();
	
	public static List<Record> getMenu(){
		String sql = "SELECT * FROM bs_menu WHERE `code` in (SELECT DISTINCT(code) FROM bs_menu ) GROUP BY `code`";
		List<Record> menu = Db.find(sql);
		return menu;
	}
	
	public static void deleteMenu(){
		Db.update("DELETE FROM bs_menu");
	}
}

工具类相关内容:

package com.feng.util;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCell;

public class ExcelUtil {
	
    @SuppressWarnings("static-access")
	public static 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")
    public static 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());
        }
    }
}


完整项目请移步我的仓库:http://git.oschina.net/zhulf/ReadExcelProject

初次尝试请大家多多指教


你可能感兴趣的:(一次代码重构之旅(二))