1 实体
package com.company.common;
import java.io.Serializable;
/**
* 用户信息实体
* @author xindaqi
* @since 2020-12-19
*/
public class UserInformationEntity implements Serializable {
// private static final long serialVersionUID = 1547123013328323240L;
public String nickname;
private String address;
public UserInformationEntity() {}
public UserInformationEntity(String nickname, String address) {
this.nickname = nickname;
this.address = address;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
2 反射获取属性
获取类属性:共有属性和私有属性,通过getFields()方法获取公有属性,通过getDeclaredFields()方法获取所有属性,实现如下:
2.1 获取公共属性
package com.company.reflect;
import com.company.common.UserInformationEntity;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectGetMethodAndProperties {
public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InvocationTargetException {
Class<?> clzz = UserInformationEntity.class;
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江");
Class clzzUser = userInformationEntity.getClass();
/**
* 属性:公共
*/
Field[] fields = clzz.getFields();
for(Field field : fields) {
System.out.println("类公共属性名称:" + field.getName());
}
}
- 结果
类公共属性名称:nickname
2.2 获取所有属性
package com.company.reflect;
import com.company.common.UserInformationEntity;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectGetMethodAndProperties {
public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InvocationTargetException {
Class<?> clzz = UserInformationEntity.class;
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江");
Class clzzUser = userInformationEntity.getClass();
/**
* 属性: 所有
*/
Field[] allFields = clzz.getDeclaredFields();
for(Field field : allFields) {
System.out.println("所有属性:" + field.getName());
}
}
- 结果
所有属性:nickname
所有属性:address
3 反射获取属性值
package com.company.reflect;
import com.company.common.UserInformationEntity;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectGetMethodAndProperties {
public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InvocationTargetException {
Class<?> clzz = UserInformationEntity.class;
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江");
Class clzzUser = userInformationEntity.getClass();
/**
* 属性: 所有
*/
Field[] allFields = clzz.getDeclaredFields();
for(Field field : allFields) {
System.out.println("所有属性:" + field.getName());
}
/**
* 属性值
*/
Field[] userFields = clzzUser.getDeclaredFields();
for(Field field: allFields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clzzUser);
Method method = pd.getReadMethod();
Object invoke = method.invoke(userInformationEntity);
System.out.println(field.getName() + ":" + invoke);
}
}
- 结果
nickname:xiaoxiao
address:黑龙江
4 反射获取方法
package com.company.reflect;
import com.company.common.UserInformationEntity;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectGetMethodAndProperties {
public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InvocationTargetException {
Class<?> clzz = UserInformationEntity.class;
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江");
Class clzzUser = userInformationEntity.getClass();
/**
* 方法
*/
Method[] methods = clzz.getMethods();
for(Method method : methods) {
System.out.println("类方法名称:" + method.getName());
}
}
- 结果
类方法名称:getNickname
类方法名称:setNickname
类方法名称:setAddress
类方法名称:getAddress
类方法名称:wait
类方法名称:wait
类方法名称:wait
类方法名称:equals
类方法名称:toString
类方法名称:hashCode
类方法名称:getClass
类方法名称:notify
类方法名称:notifyAll
5 反射遍历为Excel赋值
按行为Excel写入数据,Excel模板如图5.1
Excel的每行(hang)为一个实体,通过遍历为Excel填充数据,使用反射机制,进行内层循环,即进行属性值遍历并填充,实现如下:
5.1 反射数据写入二维数组
package com.company.reflect;
import com.company.common.UserInformationEntity;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectGetMethodAndProperties {
public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InvocationTargetException {
Class<?> clzz = UserInformationEntity.class;
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江");
Class clzzUser = userInformationEntity.getClass();
/**
* 属性: 所有
*/
Field[] allFields = clzz.getDeclaredFields();
for(Field field : allFields) {
System.out.println("所有属性:" + field.getName());
}
/**
* 反射为二维数据赋值
* 用于Excel按行写入数据
*/
List<UserInformationEntity> userInformationEntityList = new ArrayList<>();
userInformationEntityList.add(userInformationEntity);
UserInformationEntity userInformationEntity1 = new UserInformationEntity("dada", "安徽");
userInformationEntityList.add(userInformationEntity1);
UserInformationEntity userInformationEntity2 = new UserInformationEntity("haha", "辽宁");
userInformationEntityList.add(userInformationEntity2);
String[][] arrays = new String[3][2];
for(int i = 0; i < userInformationEntityList.size(); i++) {
for(int j = 0; j < allFields.length; j++) {
PropertyDescriptor pd = new PropertyDescriptor(allFields[j].getName(), userInformationEntityList.get(i).getClass());
Method method = pd.getReadMethod();
String invoke = method.invoke(userInformationEntityList.get(i)).toString();
arrays[i][j] = invoke;
}
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 2; j++) {
System.out.println(arrays[i][j] + "");
}
}
}
}
- 结果
xiaoxiao
黑龙江
dada
安徽
haha
辽宁
5.2 反射数据写入Excel
- 实体
package com.company.microservicedata.vo;
/**
* 用户详情
* @author xindaqi
* @since 2020-10-07
*/
public class UserDetailsVO {
private Integer id;
private String username;
private String sex;
private String address;
public void setId(Integer id){
this.id = id;
}
public Integer getId(){
return id;
}
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
public void setSex(String sex){
this.sex = sex;
}
public String getSex(){
return sex;
}
public void setAddress(String address){
this.address = address;
}
public String getAddress(){
return address;
}
@Override
public String toString() {
return "UserDetailsVO{" +
"id=" + id +
", username='" + username + '\'' +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
- 实现
package com.company.microservicedata.util;
import com.company.microservicedata.vo.UserDetailsVO;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.IntStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
/**
* Excel文件处理工具类
* @author xindaqi
* @since 2020-12-13
*/
@Component
public class ExcelProcessUtil {
private static Logger logger = LoggerFactory.getLogger(ExcelProcessUtil.class);
public void rawWrite(Class<?> clazz, String savePath, String fileName) {
/**
* 新建Excel文件和Sheet
*/
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("原生POI生成Excel");
List<String> titleList = Stream.of("序号", "姓名", "性别", "地址").collect(Collectors.toList());
XSSFRow headRow = sheet.createRow(0);
for(int i = 0; i < titleList.size(); i++) {
headRow.createCell(i).setCellValue(titleList.get(i));
}
List<UserDetailsVO> userDetailsVOList = new ArrayList<>();
UserDetailsVO u1 = new UserDetailsVO();
// u1.setId(1);
u1.setAddress("黑龙江");
u1.setSex("male");
u1.setUsername("xiaoxiao");
userDetailsVOList.add(u1);
UserDetailsVO u2 = new UserDetailsVO();
// u2.setId(2);
u2.setAddress("辽宁");
u2.setSex("male");
u2.setUsername("xiaohei");
userDetailsVOList.add(u2);
UserDetailsVO u3 = new UserDetailsVO();
// u3.setId(3);
u3.setAddress("广东");
u3.setSex("male");
u3.setUsername("xiaohua");
userDetailsVOList.add(u3);
logger.info("user list: {}", userDetailsVOList);
Field[] fields = clazz.getDeclaredFields();
FileOutputStream fos = null;
try {
for(int i = 0; i < userDetailsVOList.size(); i++) {
// 每次遍历,重新生成行对象
XSSFRow row = sheet.createRow(i+1);
for(int j = 0; j < fields.length; j++) {
PropertyDescriptor pd = new PropertyDescriptor(fields[j].getName(), userDetailsVOList.get(i).getClass());
Method method = pd.getReadMethod();
// null置为空
String invoke = (null == method.invoke(userDetailsVOList.get(i))) ? "" : method.invoke(userDetailsVOList.get(i)).toString();
row.createCell(j).setCellValue(invoke);
}
}
File file = new File(savePath + fileName);
fos = new FileOutputStream(file);
workbook.write(fos);
logger.info("下载-完成写入");
} catch(Exception e) {
logger.error("下载异常:{}", e);
logger.info("下载异常:{}", e);
} finally {
try {
if(fos != null) {
fos.close();
}
logger.info("流关闭");
} catch (Exception e) {
logger.info("流关闭失败:{}", e);
}
try {
workbook.close();
logger.info("Workbook关闭");
} catch (Exception e) {
logger.info("Workbook关闭失败:{}", e);
}
}
}
}
- 调用方法
@Override
public String downloadExcel(HttpServletRequest request) {
String savePath = "/Users/xindaqi/xinPrj/java/webStudy/microservice-book/microservice-data/src/main/resources/template/";
String fileName = "下载-Excel.xlsx";
excelProcessUtil.rawWrite(UserDetailsVO.class, savePath, fileName);
String downloadLink = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getRequestURI() + "/" + fileName;
return downloadLink;
}
- 结果
6 小结
- 反射获取属性:公共属性:getFields(),所有属性:getDeclaredFields()
- 反射属性值:PropertyDescriptor,getReadMethod()获取属性值的方法(get方法),获取值invoke()
- 反射属性值会出现空指针,需要逻辑处理
- Excel每次写入行,需要重新建立行对象