POI封装一:导入 Import

已整理成完整项目,并进行了优化。看参考地址:

https://gitee.com/andy_longjie/exceltools   或者 https://github.com/youmulongjie/exceltools

POI 导入篇

1、maven jar 包依赖:
        <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<poi.version>3.12</poi.version>
		<dict>exceltools</dict><!-- 项目名称 -->
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

 

 

不用maven的可以自行下载这两个jar包,加入项目中。

2、项目目录树:

3、定义注解类:

(一):ExcelImportCol.java :
/**
 * @package :com.andy.demo.execltools.imports.annotation<br>
 * @author :wanglongjie<br>
 * @createDate :2015年12月2日上午10:44:28<br>
 */
package com.andy.demo.execltools.imports.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 描述:Excel 导入属性注解类 <br>
 * <br>
 * 1、导入的类必须添加注解类ExcelImportConfig<br>
 * 2、该注解类用在类属性上,获取Excel所在列的记录<br>
 * 
 * @package :com.andy.demo.execltools.imports.annotation<br>
 * @file :ExcelImportCol.java<br>
 * @author :wanglongjie<br>
 * @createDate :2015年12月2日上午10:44:28<br>
 * 
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface ExcelImportCol {
	/**
	 * 
	 * 描述:Excel 所在列 <br>
	 * 
	 * @method :col<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午10:44:59 <br>
	 * @return Excel 所在列
	 */
	int col();
} 

 

(二):ExcelImportConfig.java :
 
/**
 * @package :com.andy.demo.execltools.imports.annotation<br>
 * @author :wanglongjie<br>
 * @createDate :2015年12月2日上午10:21:11<br>
 */
package com.andy.demo.execltools.imports.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 描述:Excel 导入注解类: <br>
 * <br>
 * 1、导入的类必须添加该注解类 <br>
 * 2、默认从第1行导入 <br>
 * 3、如果 notNullCols 方法中每一列都为空,则系统认为该条数据不正确,需去除 <br>
 * 
 * @package :com.andy.demo.execltools.imports.annotation<br>
 * @file :ExcelImportConfig.java<br>
 * @author :wanglongjie<br>
 * @createDate :2015年12月2日上午10:21:11<br>
 * 
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ExcelImportConfig {
	/**
	 * 
	 * 描述:读取Excel数据记录的开始行,默认为1,即从第1行开始 <br>
	 * 
	 * @method :startLine<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午10:21:48 <br>
	 * @return 有效数据记录的开始行
	 */
	int startLine() default 1;

	/**
	 * 
	 * 描述:读取Excel数据记录非空列索引数组,默认为null,即每一列都可以为空;列索引从0开始<br>
	 * <br>
	 * 1、如果非空列数组为null,则读取每一行的数据作为一条记录<br>
	 * 2、如果非空列数组不为null,例如为[0],则若每行的第0列为空,则不读取该行记录;反之读取该行记录<br>
	 * 3、如果非空列数组不为null,例如为[0,1],则若每行的第0列、第1列同时都为空,则不读取该行记录;反之读取该行记录<br>
	 * 
	 * @method :notNullCols<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午10:28:57 <br>
	 * @return Excel数据记录非空列索引数组
	 */
	int[] notNullCols() default {};
}

3、导入工具类:

/**
 * @package :com.andy.demo.execltools.imports<br>
 * @author :wanglongjie<br>
 * @createDate :2015年12月2日上午10:18:29<br>
 */
package com.andy.demo.execltools.imports;

import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import com.andy.demo.execltools.imports.annotation.ExcelImportCol;
import com.andy.demo.execltools.imports.annotation.ExcelImportConfig;

/**
 * 描述: Excel 导入工具类<br>
 * <br>
 * 方法一:excelImport(InputStream, Class) : 将 文件流 转化为 List对象集合,sheet索引默认为0;<br>
 * 方法一:excelImport(InputStream, Class, int) : 将 文件流 转化为 List对象集合,可设置sheet索引位置<br>
 * 
 * @package :com.andy.demo.execltools.imports<br>
 * @file :ExcelToolsImport.java<br>
 * @author :wanglongjie<br>
 * @createDate :2015年12月2日上午10:18:29<br>
 */
public class ExcelToolsImport {
	/**
	 * 
	 * 描述:获取Excel的载体实体类集合,默认导入Excel的sheet索引值为0 <br>
	 * 
	 * @method :excelImport<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午11:14:59 <br>
	 * @param fileInputStream
	 *            :导入Excel生成的文件流
	 * @param cla
	 *            :导入Excel的载体实体类
	 * @return
	 * @throws Exception
	 */
	public static <T> List<T> excelImport(InputStream fileInputStream,
			Class<T> cla) throws Exception {
		return excelImport(fileInputStream, cla, 0);
	}

	/**
	 * 
	 * 描述:获取Excel的载体实体类集合 <br>
	 * 
	 * @method :excelImport<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午11:08:17 <br>
	 * @param fileInputStream
	 *            :导入Excel生成的文件流
	 * @param cla
	 *            :导入Excel的载体实体类
	 * @param sheetIndex
	 *            :导入Excel的sheet索引值
	 * @return
	 * @throws Exception
	 */
	public static <T> List<T> excelImport(InputStream fileInputStream,
			Class<T> cla, int sheetIndex) throws Exception {
		checkValidate(fileInputStream, cla);
		Workbook workbook = WorkbookFactory.create(fileInputStream);
		Sheet sheet = workbook.getSheetAt(sheetIndex);

		// 获取最大行和开始行
		int rows = sheet.getLastRowNum();
		int startLine = getStartLine(cla);

		List<T> list = new ArrayList<T>();
		Row row = null;
		T t = null;
		for (int i = startLine; i <= rows; i++) {
			row = sheet.getRow(i);
			t = addLine2List(row, cla);
			if (validateNotNull(t)) {
				list.add(t);
			}
		}

		return list;
	}

	/**
	 * 
	 * 描述:读取行,转化为指定的对象 <br>
	 * 
	 * @method :addLine2List<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午11:27:04 <br>
	 * @param row
	 *            : Excel Row行对象
	 * @param cla
	 *            :导入Excel的载体实体类
	 * @return
	 * @throws Exception
	 */
	private static <T> T addLine2List(Row row, Class<T> cla) throws Exception {
		T t = cla.newInstance();
		List<Field> list = getExcelImportColAnnoFields(cla);
		for (Field field : list) {
			setCell2Obj(field, row, t);
		}
		return t;
	}

	/**
	 * 
	 * 描述:读取单元格,设置实体属性值 <br>
	 * 
	 * @method :setCell2Obj<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日下午12:47:32 <br>
	 * @param field
	 *            :实体对象中带有ExcelImportCol注解的属性
	 * @param row
	 *            :Excel Row 行对象
	 * @param t
	 *            :封装的实体对象
	 * @return
	 * @throws Exception
	 */
	private static <T> T setCell2Obj(Field field, Row row, T t)
			throws Exception {
		// 获取列索引、单元格
		int col = field.getAnnotation(ExcelImportCol.class).col();
		Cell cell = row.getCell(col);
		if (null != cell) {
			String typeName = field.getType().getSimpleName();
			// 获取属性的写入方法
			String propertyName = field.getName();
			PropertyDescriptor pd = new PropertyDescriptor(propertyName,
					t.getClass());
			Method m = pd.getWriteMethod();

			switch (cell.getCellType()) {
			case Cell.CELL_TYPE_STRING:
				// 字符串
				String value = cell.getRichStringCellValue().getString();
				m.invoke(t, value);
				break;
			case Cell.CELL_TYPE_NUMERIC:
				// 数字 | 日期
				if (DateUtil.isCellDateFormatted(cell)) {
					Date date = cell.getDateCellValue();
					m.invoke(t, date);
				} else {
					double d = cell.getNumericCellValue();
					if (BigDecimal.class.getSimpleName().equals(typeName)) {
						BigDecimal bigDecimal = new BigDecimal(d);
						m.invoke(t, bigDecimal);
					}
					if (Double.class.getSimpleName().equals(typeName)
							|| "double".equals(typeName)) {
						Double d1 = new Double(d);
						m.invoke(t, d1);
					}
					if (Float.class.getSimpleName().equals(typeName)
							|| "float".equals(typeName)) {
						Float f = new Float(d);
						m.invoke(t, f);
					}
					if (Integer.class.getSimpleName().equals(typeName)
							|| "int".equals(typeName)) {
						Integer i = new BigDecimal(d).intValue();
						m.invoke(t, i);
					}
					if (Long.class.getSimpleName().equals(typeName)
							|| "long".equals(typeName)) {
						Long l = new BigDecimal(d).longValue();
						m.invoke(t, l);
					}
				}
				break;
			case Cell.CELL_TYPE_BOOLEAN:
				// boolean 类型
				boolean b = cell.getBooleanCellValue();
				m.invoke(t, b);
				break;
			default:
				break;
			}
		}
		return t;
	}

	/**
	 * 
	 * 描述:获取开始行
	 * 
	 * <br>
	 * 
	 * @method :getStartLine<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午10:54:34 <br>
	 * @param cla
	 *            :导入Excel的载体实体类
	 * @return 获取开始行
	 */
	private static <T> int getStartLine(Class<T> cla) {
		return cla.getAnnotation(ExcelImportConfig.class).startLine();
	}

	/**
	 * 
	 * 描述:获取Excel的载体实体类中添加ExcelImportCol注解的属性集合 <br>
	 * 
	 * @method :getExcelImportColAnnoFields<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午10:59:24 <br>
	 * @param cla
	 *            :导入Excel的载体实体类
	 * @return
	 * @throws Exception
	 */
	private static <T> List<Field> getExcelImportColAnnoFields(Class<T> cla)
			throws Exception {
		List<Field> fieldList = new ArrayList<Field>();
		Field[] fields = cla.getDeclaredFields();
		for (Field f : fields) {
			if (f.isAnnotationPresent(ExcelImportCol.class)) {
				fieldList.add(f);
			}
		}
		return fieldList;
	}

	/**
	 * 
	 * 描述:验证导入Excel的载体实体类是否合法
	 * 
	 * <br>
	 * 
	 * @method :checkValidate<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日上午11:01:59 <br>
	 * @param fileInputStream
	 *            : 导入Excel生成的文件流
	 * @param cla
	 *            :导入Excel的载体实体类
	 * @return 验证通过返回 true;验证失败返回 false
	 * @throws Exception
	 */
	private static <T> boolean checkValidate(InputStream fileInputStream,
			Class<T> cla) throws Exception {
		if (null == fileInputStream) {
			throw new Exception("导入Excel生成的文件流为空!");
		}

		if (!cla.isAnnotationPresent(ExcelImportConfig.class)) {
			throw new Exception("指定的实体类" + cla.getName()
					+ " 缺少ExcelImportConfig注解!");
		}
		
		if (getExcelImportColAnnoFields(cla).size() == 0) {
			throw new Exception("指定的实体类" + cla.getName()
					+ " 属性缺少ExcelImportCol注解!");
		}

		return true;
	}

	/**
	 * 
	 * 描述:判断实体对象是否为空(通过 notNullCols() 判断) <br>
	 * 
	 * @method :validateNotNull<br>
	 * @author :wanglongjie<br>
	 * @createDate :2015年12月2日下午12:50:25 <br>
	 * @param t
	 *            : 实体对象
	 * @return
	 * @throws Exception
	 */
	private static <T> boolean validateNotNull(T t) throws Exception {
		boolean validate = false;
		int[] notNullCols = t.getClass().getAnnotation(ExcelImportConfig.class)
				.notNullCols();
		if (null == notNullCols || notNullCols.length == 0) {
			validate = true;
		} else {
			boolean[] b = new boolean[notNullCols.length];
			List<Field> list = getExcelImportColAnnoFields(t.getClass());
			PropertyDescriptor pd = null;
			Method m = null;
			Object fieldValue = null;
			int col = 0;
			for (int i = 0; i < notNullCols.length; i++) {
				for (Field f : list) {
					col = f.getAnnotation(ExcelImportCol.class).col();
					// 判断 该列值是否为空
					if (notNullCols[i] == col) {
						pd = new PropertyDescriptor(f.getName(), t.getClass());
						m = pd.getReadMethod();
						fieldValue = m.invoke(t);
						if (null == fieldValue) {
							b[i] = false;
						} else {
							b[i] = true;
						}
						break;
					}
				}
			}

			for (int i = 0; i < b.length; i++) {
				validate = validate || b[i];
			}
		}
		return validate;
	}
}

 

已整理成完整项目,并进行了优化。看参考地址:

https://gitee.com/andy_longjie/exceltools   或者 https://github.com/youmulongjie/exceltools

 

 

转载于:https://my.oschina.net/andy1989/blog/540354

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值