初衷:项目中一直没有一个好用的Excel导入导出功能。所以简单实现了导入导出功能分享大家一起讨论和学习
关于本项目说明
- 导入:基于poi导入做了一层封装、支持注解方式标识属性对应Excel列、并支持简单规则校验、提供校验规则自定义
- 两种导出:一种基于poi的导出,一种基于jxls模板导出。jxls模板导出可参考:jxls说明
- 别的就不多BB了,直接上代码。源码包可直接下载使用:点我取源码 没有过多的文字说明,全是代码下载看源码便知
1、基于maven项目的添加依赖,POM依赖如下
<!-- Excel poi文件处理 -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!-- Excel模板导出依赖 -->
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-core</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-reader</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.4</version>
</dependency>
2、Excle导入类ExcelException.java,ExcelFieldMeta.java,ExcelUtil.java。入口类为ExcelUtil.java提供各种静态方法
ExcelUtil.java
/**
* Excel导入
*
* @author http://blog.csdn.net/make_a_difference
*/
@SuppressWarnings("unchecked")
public class ExcelUtil {
private static Log logger = LogFactory.getLog(ExcelUtil.class);
// 换行标识
private final static String ENTER_STR = "\n";
/**
* 默认解析Excel第一个sheet页
*
* @param is
* 输入流
* @param startRow
* 开始解析行
* @param clazz
* 实体类
* @return
* @throws ExcelException
*/
public static <T> List<T> excelParsing(InputStream is, Integer startRow, Class<T> clazz) throws ExcelException {
return excelParsing(is, 1, startRow, clazz);
}
/**
* 默认解析Excel第一个sheet页
*
* @param is
* 输入流
* @param startRow
* 开始解析行
* @param clazz
* 实体类
* @return
* @throws ExcelException
* @throws FileNotFoundException
*/
public static <T> List<T> excelParsing(File file, Integer startRow, Class<T> clazz) throws ExcelException {
FileInputStream is;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
logger.error("Excel文件异常", e);
throw new ExcelException("Excel文件异常");
}
return excelParsing(is, 1, startRow, clazz);
}
/**
* 解析Excel
*
* @param is
* 输入流
* @param sheetIndex
* sheet页数
* @param startRow
* 开始解析行
* @param clazz
* 实体类
* @return
* @throws ExcelException
*/
public static <T> List<T> excelParsing(InputStream is, Integer sheetIndex, Integer startRow, Class<T> clazz)
throws ExcelException {
// 1: 获取工作簿
Workbook wb = null;
try {
wb = ExcelUtil.getWorkbook(is);
} catch (Exception e) {
logger.error("系统解析Excel获取WorkBook错误", e);
throw new ExcelException("系统解析Excel错误");
}
// 2:获取第一个sheet页码
Sheet sheet = wb.getSheetAt(sheetIndex - 1);
return doParsing(sheet, startRow, clazz);
}
@SuppressWarnings("rawtypes")
private static <T> List<T> doParsing(Sheet sheet, Integer startRow, Class<T> clazz) throws ExcelException {
StringBuffer errorMessage = new StringBuffer("");
// 1:获取sheet页的总行数
int lastRow = sheet.getLastRowNum();
// 2: 行解析,默认从0开始,startRow属性定义了数据从该行开始解析,程序中定义的行数从1开始算,所以此处要-1
List resultList = new ArrayList(3);
try {
for (int rowIndex = startRow - 1; rowIndex <= lastRow; rowIndex++) {
Row row = sheet.getRow(rowIndex); // 得到 第 n 行
// 2.1获取的列为空则跳出循环
if (row == null) {
continue;
}
// 2.2 解析对象
Object rowBean = clazz.newInstance();
String rowErrorMessage = check(row, rowIndex, rowBean);
// 2.3 如果返回的不是null,则存在错误信息则记录错误信息
if (rowErrorMessage != null) {
errorMessage.append(rowErrorMessage + ENTER_STR);
continue;
}