excel导出导入(poi+反射+注解)
程序员文章站
2022-06-10 14:38:13
...
描述:使用注解建立实体与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);
}
测试效果:
生成文件
上一篇: 探索类型萃取的必要性
下一篇: 初学Java之简易的“ 封装 ”