代碼實現
PropertyAnno.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)//規定用於全局變量
@Retention(RetentionPolicy.RUNTIME)//定義為運行時注解
/**
* excel讀取所用注解
* @author Administrator
*
*/
public @interface PropertyAnno {
String value() default "";
}
AnnoCreator.java
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* 注解解釋工具類
* @author Administrator
*
*/
public class AnnoCreator {
/**
* 注解解釋方法
* @return Map<屬性名(String), 注解名(String)>
*/
public static Map<String, String> annoCreator(Class<?> clazz) {
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
for (Field field : clazz.getDeclaredFields()) {
//獲取屬性上所有注解
Annotation[] annotations = field.getAnnotations();
//判斷屬性上是否存在注解
if(annotations.length < 1) {
continue;
}
//判斷屬性上是否存在需要注解
if(annotations[0] instanceof PropertyAnno) {
map.put(field.getName(), ((PropertyAnno)annotations[0]).value());
}
}
return map;
}
}
ReadExcel
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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.xssf.usermodel.XSSFWorkbook;
public class ReadExcel<T> {
/**
* 錯誤信息
*/
private String errorMsg;
/**
* 表格數據對象
*/
private Class<T> clazz;
/**
* 改寫初始化方法,將對象傳入T
*/
@SuppressWarnings("unchecked")
public ReadExcel() {
@SuppressWarnings("rawtypes")
Class clazz = getClass();
while (clazz != Object.class) {
Type t = clazz.getGenericSuperclass();
if (t instanceof ParameterizedType) {
Type[] args = ((ParameterizedType) t).getActualTypeArguments();
if (args[0] instanceof Class) {
this.clazz = (Class<T>) args[0];
break;
}
}
clazz = clazz.getSuperclass();
}
}
/**
* 根據文件名讀取Excel文件
*
* @param filePath 文件完整路徑
* @return Map<表名(sheet名,String), 表中的屬性(List<T>)>
*/
public Map<String, List<T>> read(String filePath) {
Map<String, List<T>> map = null;
InputStream is = null;
try {
// 驗證文件是否正確
if (!validateExcel(filePath)) {
System.out.println(errorMsg);
return null;
}
// 判斷文件的類型,是2003還是2007
boolean isExcel2003 = true;
if (isExcel2007(filePath)) {
isExcel2003 = false;
}
// 創建流進行讀取
File file = new File(filePath);
is = new FileInputStream(file);
// 根據版本選擇創建Workbook的方式
Workbook workbook = null;
if (isExcel2003) {
workbook = new HSSFWorkbook(is);
} else {
workbook = new XSSFWorkbook(is);
}
map = readExcel(workbook);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
// 關閉連接
is.close();
} catch (IOException e) {
is = null;
e.printStackTrace();
}
}
}
return map;
}
/**
* 讀取Excel表格
*/
@SuppressWarnings("deprecation")
private Map<String, List<T>> readExcel(Workbook workbook) {
Map<String, List<T>> map = Collections.synchronizedMap(new HashMap<>());
List<T> list = null;
// 獲取表格數量
int numberOfSheets = workbook.getNumberOfSheets();
for (int sheetNum = 0; sheetNum < numberOfSheets; sheetNum++) {
list = new ArrayList<>();
// 獲取注解
Map<String, String> creatorMap = AnnoCreator.annoCreator(clazz);
// 獲取指定的Excel
Sheet sheet = workbook.getSheetAt(sheetNum);
// 獲取Excel的行數
int totalRows = sheet.getPhysicalNumberOfRows();
// Excel的列數
int totalCells = 0;
if (totalRows >= 1 && sheet.getRow(0) != null) {
// 獲取Excel的列數
totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
List<String> li = new ArrayList<>();
// 循環Excel的行
for (int r = 0; r < totalRows; r++) {
// 獲取對象
T t = null;
try {
t = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
// 遍歷Excel的列
for (int c = 0; c < totalCells; c++) {
Cell cell = row.getCell(c);
String cellValue = "";
if (null != cell) {
// 判斷數據的類型
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC: // 數字
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING: // 字符串
cellValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = cell.getBooleanCellValue() + "";
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
cellValue = cell.getCellFormula() + "";
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
cellValue = "";
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知類型";
break;
}
}
//此處可修改為自己的表格樣式,例如打印第二行第二列的數據:
/* if(r == 1 && c == 1){
System.out.println(cellValue);
} */
if (r == 0) {
// 存儲第一行數據(列名)
li.add(cellValue);
} else {
// 存儲第一行后數據
fill(creatorMap, li.get(c), cellValue, t);
}
}
if (r != 0) {
list.add(t);
}
}
map.put(sheet.getSheetName(), list);
}
return map;
}
/**
* 判斷是否Excel格式是否為2003
*/
private static boolean isExcel2003(String filePath) {
return filePath.matches("^.+\\.(?i)(xls)$");
}
/**
* 判斷是否Excel格式是否為2007
*/
private static boolean isExcel2007(String filePath) {
return filePath.matches("^.+\\.(?i)(xlsx)$");
}
/**
* 驗證Excel文件
*/
private boolean validateExcel(String filePath) {
// 檢查文件名格式是否正確
if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
System.out.println("文件名不是Excel格式");
return false;
}
// 檢查文件是否存在
File file = new File(filePath);
if (file == null || !file.exists()) {
System.out.println("文件不存在");
return false;
}
return true;
}
/**
* 為對象進行賦值
*
* @param map 注解map(注解=屬性名)
* @param str 當前讀取到的列名
* @param obj 當前讀到的數據
* @param t 需要進行賦值的對象
*/
private void fill(Map<String, String> map, String str, String obj, T t) {
for (Entry<String, String> entry : map.entrySet()) {
try {
if (str.equals(entry.getValue())) {
// 為對象進行賦值
Field f = clazz.getDeclaredField(entry.getKey().trim());
f.setAccessible(true);
f.set(t, obj);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
BasicsEntity.java
/**
* excel內容實體類(示例)
* 注意:實體類屬性需定義為String類型
* @author Administrator
*
*/
public class BasicsEntity {
@PropertyAnno("列名")//被注解字段與excel中列名對應
private String name;//字段名
@PropertyAnno("類型")
private String type;//字段類型
@PropertyAnno("長度")
private String length;//字段長度
@PropertyAnno("小數點長度")
private String decimal;//小數點長度
@PropertyAnno("默認值")
private String defaults;//默認值
@PropertyAnno("備注")
private String annotation;//備注
@PropertyAnno("是否為非空(Y或N)")
private String isNull;//是否為非空(Y或N)
@PropertyAnno("是否為主鍵(Y或N)")
private String isPrincipal;//是否為主鍵(Y或N)
@PropertyAnno("是否啟用主鍵自增(Y或N)")
private String isProgressive;//是否啟用主鍵自增(Y或N)
@Override
public String toString() {
return "BasicsEntity [name=" + name + ", type=" + type + ", length=" + length + ", decimal=" + decimal
+ ", defaults=" + defaults + ", annotation=" + annotation + ", isNull=" + isNull + ", isPrincipal="
+ isPrincipal + ", isProgressive=" + isProgressive + "]";
}
}
ReadTest.java
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.myutils.entity.BasicsEntity;
/**
* 測試類
* @author Administrator
*/
public class ReadTest {
public static void main(String[] args) {
//調用方法時必須寫成以下格式,否則反射無法獲取到實體類
ReadExcel<BasicsEntity> util = new ReadExcel<BasicsEntity>(){};
//調用方法,返回實體類集合
Map<String, List<BasicsEntity>> map = util.read("D:數據庫文檔\\測試表格.xlsx");
for (Entry<String, List<BasicsEntity>> baMap : map.entrySet()) {
System.out.println("表名:" + baMap.getKey().split("\\|")[0]);
System.out.println("表備注:" + baMap.getKey().split("\\|")[1]);
for (BasicsEntity basicsEntity : baMap.getValue()) {
System.out.println(basicsEntity.toString());
}
}
}
}
pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cn</groupId>
<artifactId>myExcel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.codec</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
</dependencies>
</project>
測試使用表格:

