您的位置:首页 > 编程语言 > Java开发

java操作execl—poi:基于反射加注解方式实现对execl进行读取封装

2020-03-05 04:36 411 查看

java操作EXECL2007-poi

本次记录java操作poi

本次主要是利用反射加注解方式实现对execl的读取封装操作。

execl图片

图片:

代码片

依赖
.
先自定义注解:代码如下

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>

注解代码片
.
先自定义注解:代码如下

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAttribute {
/** 对应的列名称 */
String name() default "";

/** 列序号 对应你execl中的列的列号*/
int sort();

/** 字段类型对应的格式 */
String format() default "";

}

工具类代码片
.
先自定义注解:代码如下

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.xssf.usermodel.XSSFWorkbook;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ExcelImportUtil<T> {

private Class clazz;
//获取该类的所有属性
private  Field fields[];

public ExcelImportUtil(Class clazz) {
this.clazz = clazz;
fields = clazz.getDeclaredFields();
}

/**
* 基于注解读取excel
*/
public List<T> readExcel(InputStream is, int rowIndex,int cellIndex) {
List<T> list = new ArrayList<T>();
T entity = null;
try {
XSSFWorkbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
// 不准确
int rowLength = sheet.getLastRowNum();
System.out.println(sheet.getLastRowNum());
//遍历到最后一行
for (int rowNum = rowIndex; rowNum <= sheet.getLastRowNum(); rowNum++) {
//读取一行
Row row = sheet.getRow(rowNum);
//反射创建对象
entity = (T) clazz.newInstance();
System.out.println(row.getLastCellNum());
//读取到每行得最后一列
for (int j = cellIndex; j < row.getLastCellNum(); j++) {
//读取一列
Cell cell = row.getCell(j);
//遍历对象中的属性
for (Field field : fields) {
//判断哪些属性上有这个注解
if(field.isAnnotationPresent(ExcelAttribute.class)){
//暴力反射
field.setAccessible(true);
//获取每个属性上的注解
ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class);
//判断每列与注解上的列是否对应
if(j == ea.sort()) {
//向属性赋值
field.set(entity, covertAttrType(field, cell));
}
}
}
}
list.add(entity);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}

/**
* 类型转换 将cell 单元格格式转为 字段类型
*/
private Object covertAttrType(Field field, Cell cell) throws Exception {
String fieldType = field.getType().getSimpleName();
if ("String".equals(fieldType)) {
return getValue(cell);
}else if ("Date".equals(fieldType)) {
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(getValue(cell)) ;
}else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
return Integer.parseInt(getValue(cell));
}else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
return Double.parseDouble(getValue(cell));
}else if ("long".equals(fieldType) || "Long".equals(fieldType)){
return Long.parseLong(getValue(cell));
}else if ("BigDecimal".equals(fieldType)){
return BigDecimal.valueOf(new Double(getValue(cell)));
}else {
return null;
}
}

/**
* 格式转为String
* @param cell
* @return
*/
public String getValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getRichStringCellValue().getString().trim();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date dt = DateUtil.getJavaDate(cell.getNumericCellValue());
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(dt);
} else {
// 防止数值变成科学计数法
String strCell = "";
Double num = cell.getNumericCellValue();
BigDecimal bd = new BigDecimal(num.toString());
if (bd != null) {
strCell = bd.toPlainString();
}
// 去除 浮点型 自动加的 .0
if (strCell.endsWith(".0")) {
strCell = strCell.substring(0, strCell.indexOf("."));
}
return strCell;
}
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return "";
}
}
}


参数字段说明:反射时你需要创建的类的class字节码,

第一个参数:你要传入的文件输入流,第二个参数:你需要从execl的哪个起始行读取,第二个cellIndex表示你需求从哪个的起始列读取。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
qq_40353040 发布了2 篇原创文章 · 获赞 0 · 访问量 42 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: