描述:使用註解建立實體與excel之間的映射關係,反射設置實體屬性值
一、jar包
二、定義註解
三、定義測試實體
四、封裝excel工具類
一、jar包
poi-3.17.jar
poi-excelant-3.17.jar
poi-ooxml-3.17.jar
poi-ooxml-schemas-3.17.jar
maven導入
<!-- poi-ooxml自動引入操作xlsx文件所用到的其他包 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15-beta2</version>
</dependency>
二、定義註解
定義該註解作用:主要用來描述屬性存在excel中的第幾列,列名是什麼。目的是與excel建立關係。
/**
* 定義excel描述註解
* @author YZQ
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
/**
* 列索引
* @return
*/
public int columnIndex() default 0;
/**
* 列名
* @return
*/
public String columnName() default "";
}
三、定義測試實體
public class ExcelEntity {
public ExcelEntity() {
}
public ExcelEntity(int id, String name) {
this.id = id;
this.name = name;
}
//描述改屬性在excel中第0列,列名爲 序號
@MyAnnotation(columnIndex=0,columnName="序號")
private int id;
//描述改屬性在excel中第1列,列寧爲 名字
@MyAnnotation(columnIndex=1,columnName="名字")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "ExcelEntity [id=" + id + ", name=" + name + "]";
}
}
四、封裝excel工具類
excel導出(註釋很詳細,不解釋)
/**
* 輸出excel文件
* @param data 數據集合
* @param path 輸出路徑
*/
public static void outExcelFile(List<?> data, String path) {
File file = new File(path);
// 創建workbook
HSSFWorkbook wb = new HSSFWorkbook();
// 創建sheet
Sheet sheet = wb.createSheet("sheel");
// 創建表頭行
Row row = sheet.createRow(0);
// 創建單元格樣式
HSSFCellStyle style = wb.createCellStyle();
// 居中顯示
style.setAlignment(HorizontalAlignment.CENTER);
// 獲取實體所有屬性
Field[] fields = data.get(0).getClass().getDeclaredFields();
// 列索引
int index = 0;
// 列名稱
String name = "";
MyAnnotation myAnnotation;
// 創建表頭
for (Field f : fields) {
// 是否是註解
if (f.isAnnotationPresent(MyAnnotation.class)) {
// 獲取註解
myAnnotation = f.getAnnotation(MyAnnotation.class);
// 獲取列索引
index = myAnnotation.columnIndex();
// 列名稱
name = myAnnotation.columnName();
// 創建單元格
creCell(row, index, name, style);
}
}
// 行索引 因爲表頭已經設置,索引行索引從1開始
int rowIndex = 1;
for (Object obj : data) {
// 創建新行,索引加1,爲創建下一行做準備
row = sheet.createRow(rowIndex++);
for (Field f : fields) {
// 設置屬性可訪問
f.setAccessible(true);
// 判斷是否是註解
if (f.isAnnotationPresent(MyAnnotation.class)) {
// 獲取註解
myAnnotation = f.getAnnotation(MyAnnotation.class);
// 獲取列索引
index = myAnnotation.columnIndex();
try {
// 創建單元格 f.get(obj)從obj對象中獲取值設置到單元格中
creCell(row, index, String.valueOf(f.get(obj)), style);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
wb.write(outputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//釋放資源
try {
if (wb != null) {
try {
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
excel導入(註釋很詳細,不解釋)
/**
* 讀取excel文件,並把讀取到的數據封裝到clazz中
*
* @param path
* 文件路徑
* @param clazz
* 實體類
* @return 返回clazz集合
*/
public static <T extends Object> List<T> readExcelFile(String path, Class<T> clazz) {
// 存儲excel數據
List<T> list = new ArrayList<>();
FileInputStream is = null;
try {
is = new FileInputStream(new File(path));
} catch (FileNotFoundException e1) {
throw new RuntimeException("文件路徑異常");
}
Workbook wookbook = null;
// 根據excel文件版本獲取工作簿
if (path.endsWith(".xls")) {
wookbook = xls(is);
} else if (path.endsWith(".xlsx")) {
wookbook = xlsx(is);
} else {
throw new RuntimeException("文件出錯,非excel文件");
}
// 得到一個工作表
Sheet sheet = wookbook.getSheetAt(0);
// 獲取行總數
int rows = sheet.getLastRowNum() + 1;
Row row;
// 獲取類所有屬性
Field[] fields = clazz.getDeclaredFields();
T obj = null;
int coumnIndex = 0;
Cell cell = null;
MyAnnotation myAnnotation = null;
for (int i = 1; i < rows; i++) {
// 獲取excel行
row = sheet.getRow(i);
try {
// 創建實體
obj = clazz.newInstance();
for (Field f : fields) {
// 設置屬性可訪問
f.setAccessible(true);
// 判斷是否是註解
if (f.isAnnotationPresent(MyAnnotation.class)) {
// 獲取註解
myAnnotation = f.getAnnotation(MyAnnotation.class);
// 獲取列索引
coumnIndex = myAnnotation.columnIndex();
// 獲取單元格
cell = row.getCell(coumnIndex);
// 設置屬性
setFieldValue(obj, f, wookbook, cell);
}
}
// 添加到集合中
list.add(obj);
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
}
try {
//釋放資源
wookbook.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
設置屬性值
這裏只寫部分,按自己需要自行添加
/**
* 設置屬性值
*
* @param obj
* 操作對象
* @param f
* 對象屬性
* @param cell
* excel單元格
*/
private static void setFieldValue(Object obj, Field f, Workbook wookbook, Cell cell) {
try {
if (f.getType() == int.class || f.getType() == Integer.class) {
f.setInt(obj, getInt(cell));
} else if (f.getType() == Double.class || f.getType() == double.class) {
f.setDouble(obj, getDouble(null, cell));
} else {
f.set(obj, getString(cell));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
excel版本處理
/**
* 對excel 2003處理
*/
private static Workbook xls(InputStream is) {
try {
// 得到工作簿
return new HSSFWorkbook(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 對excel 2007處理
*/
private static Workbook xlsx(InputStream is) {
try {
// 得到工作簿
return new XSSFWorkbook(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
剩下的是一些單元格創建、獲取單元格值
/**
* 創建單元格
*
* @param row
* @param c
* @param cellValue
* @param style
*/
private static void creCell(Row row, int c, String cellValue, CellStyle style) {
Cell cell = row.createCell(c);
cell.setCellValue(cellValue);
cell.setCellStyle(style);
}
測試效果:
生成文件