POI导出数据为Excel格式(XSSF)(内省方式加反射)

代码

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.单属性操作

操作起前 在这里插入图片描述
操作起后
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值