Excel导出工具类

一. 工具类(基于Apache POI )

package com.huawei.esysadmin.common.util;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class ExportExcel 
{
    /**
     * 利用了JAVA的反射,将javabean的集合以一定的格式输出到指定IO设备上
     * @param sheetName
     *             工作表标题
     * @param headerMap
     *             表格列属性及属性名
     * @param dataset
     *             需要显示的数据集合
     * @param out
     *             与输出设备相关的流对象,可以将Excel文档导出到本地或者网络中
     * @throws IOException 
     */
    public void exportExcel(String sheetName, Map headerMap, Collection dataset, OutputStream out) throws IOException{
        //声明一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //生成一个工作表
        HSSFSheet sheet = workbook.createSheet(sheetName);
        //设置表格默认列宽
         //有些资料在设置宽度的时候用的是short(20),但是在实际使用的过程中,short(20)已不被推荐使用,所以直接使用int(20)
        sheet.setDefaultColumnWidth(20);
        //获取属性Map的keySet
        Set keySet = headerMap.keySet();
        //获取属性的数组
        String[] fields = keySet.toArray(new String[0]);
        //对keySet进行遍历,获得属性对应的属性名称来构成标题行
        Iterator key = keySet.iterator();
        //第一行
        HSSFRow row = sheet.createRow(0);
        for(int i = 0; key.hasNext(); i++){
            //产生单元格
            HSSFCell cell = row.createCell(i);
            //产生标题行
            HSSFRichTextString title = new HSSFRichTextString(headerMap.get(key.next()));
            cell.setCellValue(title);
        }
        
        /*
         * 遍历数据集合,产生数据行
         * 利用反射,通过属性数组来拼接getXXX的方法去获得属性的值
         */
        //属性数组的长度
        int size = fields.length;
        //属性的get方法的数组
        String[] methodNames = new String[size];
        for(int i = 0; i < size; i++)
        {
         //拼凑属性的getter方法
         methodNames[i] = "get"
                            + fields[i].substring(0, 1).toUpperCase()
                            + fields[i].substring(1);
        }
        Iterator ite = dataset.iterator();
        for(int index = 1; ite.hasNext(); index++)
        {
            row = sheet.createRow(index);
            T t = (T)ite.next();
            for(int i = 0; i < size; i++)
            {
                HSSFCell cell = row.createCell(i);
                try
                {
                    Class cla = t.getClass();
                    Method getMethod = cla.getMethod(methodNames[i], new Class[]{});
                    Object value = getMethod.invoke(t, new Object[]{});
                    String textValue = null;
                    //如果属性的类型是String,则直接输出字符串
                    if(value instanceof String)
                    {
                        textValue = value.toString();
                    }
                    if(value instanceof Integer || value instanceof Double) 
                    {
                    	textValue = String.valueOf(value);
                    }
                    //如果属性的类型是Date,则需要格式转换
                    if(value instanceof Date)
                    {
                        Date date = (Date)value;
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
                        textValue = sdf.format(date);
                    }
                    if(textValue != null)
                    {
                        HSSFRichTextString richString = new HSSFRichTextString(textValue);
                        cell.setCellValue(richString);
                    }
                }catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
        //将workbook输出到输出设备中
        workbook.write(out);
        //关闭资源
        out.flush();
        workbook.close();
        out.close();
    }
}

二.项目实战使用

2.1.思路

一般我们导出excel,首先是先查询出一个集合bean,然后使用apache poi 处理数据, 生成excel,此处我们指的是同步导入excel,

异步导入Excel(原始数据组装比较耗时的话)需要使用多线程,此文不讨论.

2.2 代码实现:

  1.目标:出学生信息Excel

  2.实体类(学生信息)

public class Student implements Serializable
{

	private static final long serialVersionUID = 1L;
	
	private String name;
	
	private int age;
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	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;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

 3.Controller类处理

/**
 * 导出结果为excel表格
 */
@ResponseBody
@RequestMapping(value = "/exportExcel", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public BaseResBean exportExcel(@RequestBody ExportAwardReqDto req) 
{
	BaseResBean res = new BaseResBean();
	try {
		// Excel导出的查询条件
		SearchParamBean searchParamBean = req.getSearchParamBean();
		String filename = "学生信息.xls";
		HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getResponse();
		// 设置响应头
		response.setContentType("application/vnd.ms-excel;charset=utf-8");
		// 设置文件名
		response.setHeader("Content-Disposition",
				"attachment;filename=\"" + URLEncoder.encode(filename, "UTF-8") + "\" ");
		OutputStream out = response.getOutputStream();

		// 第一步:获取需要导出的原始数据集合
		List dataList = studentService.queryDetail(searchParamBean);

		for (Student student : dataList) {
			//进行数据组装
			asseblemInfo(student);
		}

		// 第二步:设置excel表头对应的属性值和属性名
		Map headerMap = buildExcelHeadMap();

		// 第三步:生成excel文件
		ExportExcel ex = new ExportExcel();
		ex.exportExcel("学生信息", headerMap, dataList, out);
	} catch (Exception e) 
	{
		e.printStackTrace();

	}
	return res;
}

private Map buildExcelHeadMap() 
{
	Map headerMap = new LinkedHashMap();
	headerMap.clear();
	headerMap.put("name", "姓名");
	headerMap.put("age", "年龄");
	return headerMap;
}


//工具类: T为查询的集合的那个bean
public class ExportExcel 
{
    /**
     * 利用了JAVA的反射,将javabean的集合以一定的格式输出到指定IO设备上
     * @param sheetName
     *             工作表标题
     * @param headerMap
     *             表格列属性及属性名
     * @param dataset
     *             需要显示的数据集合
     * @param out
     *             与输出设备相关的流对象,可以将Excel文档导出到本地或者网络中
     * @throws IOException 
     */
    public void exportExcel(String sheetName, Map headerMap, Collection dataset, OutputStream out) throws IOException{
        //声明一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //生成一个工作表
        HSSFSheet sheet = workbook.createSheet(sheetName);
        //设置表格默认列宽
         //有些资料在设置宽度的时候用的是short(20),但是在实际使用的过程中,short(20)已不被推荐使用,所以直接使用int(20)
        sheet.setDefaultColumnWidth(20);
        //获取属性Map的keySet
        Set keySet = headerMap.keySet();
        //获取属性的数组
        String[] fields = keySet.toArray(new String[0]);
        //对keySet进行遍历,获得属性对应的属性名称来构成标题行
        Iterator key = keySet.iterator();
        //第一行
        HSSFRow row = sheet.createRow(0);
        for(int i = 0; key.hasNext(); i++){
            //产生单元格
            HSSFCell cell = row.createCell(i);
            //产生标题行
            HSSFRichTextString title = new HSSFRichTextString(headerMap.get(key.next()));
            cell.setCellValue(title);
        }
        
        /*
         * 遍历数据集合,产生数据行
         * 利用反射,通过属性数组来拼接getXXX的方法去获得属性的值
         */
        //属性数组的长度
        int size = fields.length;
        //属性的get方法的数组
        String[] methodNames = new String[size];
        for(int i = 0; i < size; i++)
        {
         //拼凑属性的getter方法
         methodNames[i] = "get"
                            + fields[i].substring(0, 1).toUpperCase()
                            + fields[i].substring(1);
        }
        Iterator ite = dataset.iterator();
        for(int index = 1; ite.hasNext(); index++)
        {
            row = sheet.createRow(index);
            T t = (T)ite.next();
            for(int i = 0; i < size; i++)
            {
                HSSFCell cell = row.createCell(i);
                try
                {
                    Class cla = t.getClass();
                    Method getMethod = cla.getMethod(methodNames[i], new Class[]{});
                    Object value = getMethod.invoke(t, new Object[]{});
                    String textValue = null;
                    //如果属性的类型是String,则直接输出字符串
                    if(value instanceof String)
                    {
                        textValue = value.toString();
                    }
                    if(value instanceof Integer || value instanceof Double) 
                    {
                    	textValue = String.valueOf(value);
                    }
                    //如果属性的类型是Date,则需要格式转换
                    if(value instanceof Date)
                    {
                        Date date = (Date)value;
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
                        textValue = sdf.format(date);
                    }
                    if(textValue != null)
                    {
                        HSSFRichTextString richString = new HSSFRichTextString(textValue);
                        cell.setCellValue(richString);
                    }
                }catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
        //将workbook输出到输出设备中
        workbook.write(out);
        //关闭资源
        out.flush();
        workbook.close();
        out.close();
    }
}

三.Apache中的poi包中的XSSFWorkbook与HSSFWorkbook的区别:

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls

XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx

 

你可能感兴趣的:(java,poi,excel,java)