通过注解实现导出并抽取方法
注意:
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
package com.ws.demo.Export.ReflectionExport;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ReflectionExport {
public static void main(String[] args) {
//制造测试数据
List<User> exportInfo = new ArrayList<>();
User user = new User();
user.setId(111);
user.setName("zhangsan");
user.setAge(111);
exportInfo.add(user);
User user1 = new User();
user1.setAge(222);
user1.setId(222);
user1.setName("lisi");
exportInfo.add(user1);
exportExcel(exportInfo);
}
/**
* 导出方法,从最开始创建开始,到写完数据结束。
* @param exportInfo 测试数据
*/
private static void exportExcel(List<User> exportInfo) {
//创建Excel
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
//创建sheet页码
HSSFSheet hssfSheet = hssfWorkbook.createSheet();
//创建标题行
HSSFRow row = hssfSheet.createRow(0);
//获取User实体类的字段属性
Field[] fields = User.class.getDeclaredFields();
//用来存放哪些属性需要被导出,并且记录是第几列
Map<String,Integer> map = new HashMap<>();
//写标题
for (int i = 0; i < fields.length; i++) {
//扫描注解
ExportAnnotation annotation = fields[i].getAnnotation(ExportAnnotation.class);
if (annotation != null){
row.createCell(i).setCellValue(annotation.title());
map.put(fields[i].getName(),annotation.column());
}
}
//将数据写到Excel
for (int j = 0; j < exportInfo.size(); j++) {
//创建导出数据的行,第一行是标题,从 j+1 行开始
HSSFRow row1 = hssfSheet.createRow(j + 1);
if (map.get("name") != null){
row1.createCell(map.get("name")).setCellValue(exportInfo.get(j).getName());
}
if (map.get("age") != null){
row1.createCell(map.get("age")).setCellValue(exportInfo.get(j).getAge());
}
if (map.get("id") != null){
row1.createCell(map.get("id")).setCellValue(exportInfo.get(j).getId());
}
}
//通过流输出
String fileName = "D:\\reflectionExport.xlsx";
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(fileName);
hssfWorkbook.write(fileOutputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 导出注解,一定要加上@Retention和@Target
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface ExportAnnotation {
//标题
String title();
//Excel中的第几列
int column();
}
/**
* 实体类
*/
class User {
@ExportAnnotation(title = "编号",column = 0)
private int id;
@ExportAnnotation(title = "姓名",column = 1)
private String name;
private int age;
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
抽取公共方法和部分优化
将 exportExcel封装。可以对注解进行进一步扩展,自定义导出开始行、导出单元格格式等;
package com.ws.demo.Export.ReflectionExport;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public class Encapsulation {
public static void main(String[] args) {
//制造测试数据
ArrayList<UserInfo> exportInfo = new ArrayList<>();
UserInfo userInfo = new UserInfo();
userInfo.setId(333);
userInfo.setAge(333);
userInfo.setName("333");
exportInfo.add(userInfo);
UserInfo userInfo1 = new UserInfo();
userInfo1.setId(333);
userInfo1.setAge(444111);
userInfo1.setName("444");
exportInfo.add(userInfo1);
ExportUtils<UserInfo> userInfoExportUtils = new ExportUtils<>(UserInfo.class);
userInfoExportUtils.exportExcel(exportInfo,"D:\\reflectionExport01.xlsx");
}
}
class ExportUtils<T>{
//实体类对象
private Class<T> tClass;
//导出的数据
private List<T> list;
//文件名
private String filePath;
//存放注解列表
private ArrayList<Object[]> fieldsList;
//创建的sheet
private HSSFSheet sheet;
//创建的工作簿
private HSSFWorkbook workbook;
//当前被创建使用的行
private HSSFRow row;
//导出所用的输出流
private OutputStream outputStream;
public ExportUtils(Class<T> tClass) {
this.tClass = tClass;
}
public void exportExcel(List<T> list,String filePath){
//初始化,做导出准备工作
this.init(list,filePath);
//导出
exportExcel();
}
private void exportExcel() {
//创建sheet页
createSheet();
//创建标题行
createTitle();
//写入内容
writeContent();
//导出为Excel
export();
}
/**
* 导出为Excel
*/
private void export() {
try {
this.outputStream = new FileOutputStream(filePath);
workbook.write(outputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
workbook.close();;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 写入list中的内容
*/
private void writeContent() {
for (int i = 0; i < list.size(); i++) {
//第一行给标题使用了,创建新的一行
row = sheet.createRow(i+1);
//遍历被注解的属性,获取到指定列和属性值
for (Object[] objects : fieldsList) {
Excel excel = (Excel) objects[1];
Field field = (Field) objects[0];
try {
//改变访问权限,使得可以访问私有字段
field.setAccessible(true);
//通过反射获取字段值
Object content = field.get(list.get(i));
//写到注解指定的列
row.createCell(excel.colmun()).setCellValue(content + "");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
/**
* 创建标题行
*/
private void createTitle() {
//产生第一行
this.row = sheet.createRow(0);
for (Object[] objects : fieldsList) {
Excel excel = (Excel) objects[1];
//在第1行创建一个单元格为注解所标注的列,并填充注解中写到的title
row.createCell(excel.colmun()).setCellValue(excel.title());
}
}
/**
* 创建sheet页
*/
private void createSheet() {
this.sheet = workbook.createSheet();
}
private void init(List<T> list, String filePath) {
this.list = list;
this.filePath = filePath;
//创建数组存放实体类属性
createFields();
//创建工作簿
creatWorkBook();
}
/**
* 创建工作簿
*/
private void creatWorkBook() {
this.workbook = new HSSFWorkbook();
}
/**
* 获取实体类属性
*/
private void createFields() {
this.fieldsList = new ArrayList<Object[]>();
List<Field> fields = new ArrayList<>();
//导出对象可能继承的父类中存在注解
fields.addAll(Arrays.asList(tClass.getSuperclass().getDeclaredFields()));
fields.addAll(Arrays.asList(tClass.getDeclaredFields()));
for (Field field : fields) {
//判断Excel.class的注解是否在field上
if (field.isAnnotationPresent(Excel.class)){
fieldsList.add(new Object[] {field,field.getAnnotation(Excel.class)});
}
}
}
}
/**
* 实体类
*/
class UserInfo{
@Excel(title = "编号",colmun = 0)
private int id;
@Excel(title = "姓名",colmun = 1)
private String name;
@Excel(title = "年龄",colmun = 2)
private int age;
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Excel{
//标题
String title();
//列
int colmun();
}