代码
package com.zanclick.zyjk.common.utils;
import org.apache.poi.xssf.usermodel.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.filechooser.FileSystemView;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
public class PoiUtil2 {
/**
* @param sheetName excel名
* @param headersName 表头名[]
* @param columns 列名对应实体的属性名[]
* @param list 列名对应的实体类属性的数据值集合[]
* */
public statistics<T> void exportExcel(String sheetName,String[] headersName, String[] columns, List<T> list ,HttpServletResponse response, HttpServletRequest request)
throws Exception {
//声明一个工作簿对象
XSSFWorkbook workbook = new XSSFWorkbook();
//声明一个sheet对象
XSSFSheet sheet = workbook.createSheet(sheetName);
//设置列自动适配内容
sheet.autoSizeColumn(columns.length);
//设置默认宽度
sheet.setDefaultColumnWidth(30);
//创建单元格样式
XSSFCellStyle style = workbook.createCellStyle();
style.setWrapText(true);
//创建表头行,就是第一行
XSSFRow row = sheet.createRow(0);
//设置表头内容对齐方式
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
XSSFCell cell=null;
//添加列表头内容
for (int i = 0; i < headersName.length; i++) {
cell = row.createCell(i);
cell.setCellValue(headersName[i]);//添加名字
cell.setCellStyle(style);//设置文本对齐
}
Iterator<T> it = list.iterator();
int rowIndex = 0;
while (it.hasNext()) {
rowIndex++;
row = sheet.createRow(rowIndex);
T t = it.next();//next()方法是取出当前的元素,并指向下一个元素
Class c=t.getClass();
/* 利用内省和Java反射机制来获取
* getBeanInfo(c,Object.class):若不想把父类的属性列出,参数2填父类
* */
BeanInfo beanInfo= Introspector.getBeanInfo(c,Object.class);
//获取所有属性
PropertyDescriptor[] propertyDescriptor=beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property:propertyDescriptor){
//获取属性名
String filedName=property.getName();
for (int i=0;i<columns.length;i++){
if (filedName.equals(columns[i])){
//获取getter方法
Method getter=property.getReadMethod();
//禁止Java语言访问检查,可以提高反射的运行速度
getter.setAccessible(true);
//invoke参数,参数一:调用该方法的对象,参数二:就是属性的类型
//取值
Object fieldValue =getter.invoke(t,null);
String textValue=fieldValue.toString();
//创建单元格
cell=row.createCell(i);
//填入内容
cell.setCellValue(textValue);
//设置单元格状态
cell.setCellStyle(style);
}
}
}
}
String fileName=sheetName + ".xlsx";
File desktopDir=FileSystemView.getFileSystemView().getHomeDirectory();
String desktopPath=desktopDir.getAbsolutePath();
String filePath=desktopPath+"\\"+fileName;
FileOutputStream out=new FileOutputStream(filePath);
workbook.write(out);
out.close();
downloadExcel(filePath,response);
/*
//写入到本地
String fileName = "C:\\Users\\Desktop\\excel.xlsx";
FileOutputStream out = new FileOutputStream(fileName );
workbook.write(out);
out.close();
*/
}
/**
* 下载
*/
public static void downloadExcel(String filePath, HttpServletResponse response)
throws IOException {
File file = new File(filePath);
String fileName = file.getName();
response.setContentType("application/vnd.ms-excel;charset=utf-8");
// response.setContentType("application/multipart/form-data");
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));//会出现乱码问题
response.setHeader("Content-Disposition", "attachment;filename=" +
URLEncoder.encode(fileName,"UTF-8"));
response.setCharacterEncoding("utf-8");
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
byte[] b = new byte[fis.available()];
fis.read(b);
OutputStream out=response.getOutputStream();
out.write(b);
out.flush();
fis.close();
if (file.exists()) {
file.delete();
}
out.close();
}
}
补充
1.什么是内省?
内省是Java语言对Bean类属性、事件的一种缺省处理方法。内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属
性、方法和事件,以后我们就可以操纵该JavaBean的属性。
2.怎么使用?
/**
* 修改的属性在传入的类中
* 就是范型T对应的参数
*/
public class PoiUtil2<T> {
public static void getIntrospector(){
/*
* 单属性操作
* */
T t = it.next();//next()方法是取出当前的元素,并指向下一个元素
Class c=t.getClass();
String name="province";
PropertyDescriptor pd = new PropertyDescriptor(name,c);
Method setter=pd.getWriteMethod();//获取setter方法
setter.invoke(t,"湖南");//修改name的值
Method getter1=pd.getReadMethod();//获取getter方法
String nameValue=getter1.invoke(t).toString();//获取name的值
System.out.println("nameValue:"+nameValue);
/*
* 多属性操作
* */
BeanInfo beanInfo= Introspector.getBeanInfo(c,Object.class);
//获取所有属性
PropertyDescriptor[] propertyDescriptor=beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property:propertyDescriptor){
//获取属性名
String filedName=property.getName();
System.out.println("filedName:"+filedName);
//获取getter方法
Method getter=property.getReadMethod();
//invoke参数,参数一:调用该方法的对象,参数二:就是属性的类型
//取值
Object fieldValue =getter.invoke(t);
String textValue=fieldValue.toString();
System.out.println("textValue:"+nameValue);
}
}
}
结果
1.单属性操作
操作起前
操作起后