poi模板导出excel 高扩展性和维护性

前几天和大家分享了poi导出excel,设置自适应列宽,今天再跟大家分享poi模板导出excel。
模板导出,相比前几天用LinkedHashMap,excel样式和所需导出内容修改,只需修改模板即可,无需修改代码,可后期维护和可扩展性更强,可保存模板的样式(列宽,背景色,字号等)。

**poi excel模板导出操作思想:
1. 读取模板,获取表头中每列对应的属性(Map中的key值)。
2. 复制模板文件,重命名,遍历数据,将对应属性的值,填充到对应的列。
3. 删除模板文件,从响应流输出,生成下载。**

**excel模板要求:

  1. 只有一个sheet,命名与之后输出时的sheet不要重复。
    1. sheet中有两行数据,第一行即是输出excel的表头显示内容,包含自己所需格式。第二行为该列所对应的对象的属性。**

以下为excelExportUtil代码,仅供参考。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.eos.system.annotation.Bizlet;
import commonj.sdo.DataObject;

/**
     * @author RangoLan
     * @param fileName 生成的文件名前缀
     * @param sheetName sheet名称前缀
     * @param response 响应对象,获取响应输出流生成下载
     * @param criteriaEntity 查询实体对象,用于检索获取Excel填充数据
     * @param templatePath 倒出时选取的Excel文件路径和文件名 模板文件中必须只有一个sheet
     * @param datePattern 日期数据格式化
     * @throws Exception
     */
    @Bizlet("数据写入Excel并生成下载")
    public static void exportExcelByTemplate(String fileName,String sheetName,HttpServletResponse response,DataObject criteriaEntity,String templatePath,String datePattern) throws Exception {



        //根据查询对象criteria填充数据源
        DataObject[] datas = (DataObject[])com.eos.foundation.database.DatabaseUtil.queryEntitiesByCriteriaEntity("default", criteriaEntity);
        if (datas != null && datas.length > 0) {

            if(datePattern==null){
                datePattern = "yyyy-MM-dd";
            }

            //读取导出模板文件
            FileInputStream inputStream = new FileInputStream(templatePath);
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);

            inputStream.close();

            //获得模板sheet
            Sheet sheetTmp = workbook.getSheetAt(0);


            //属性行,限定为第二行,rowIndex=1
            Row propertyRow = sheetTmp.getRow(1);

            //获取输出的列数
            int columns = propertyRow.getLastCellNum();

            //DataObject属性Property数组
            String[] properties = new String[columns];

            for (int i = 0; i < columns; i++) {

                properties[i]=propertyRow.getCell(i).getStringCellValue();

            }


            /** 设置格式* */

            // 单元格样式
            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
            //垂直居中
            cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
            //设置边框
            cellStyle.setBorderTop(CellStyle.BORDER_THIN);
            cellStyle.setBorderRight(CellStyle.BORDER_THIN);
            cellStyle.setBorderBottom(CellStyle.BORDER_THIN);
            cellStyle.setBorderLeft(CellStyle.BORDER_THIN);

            //设置自动换行
            cellStyle.setWrapText(true);

            //设置字体
            Font cellFont = workbook.createFont();
            cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
            cellStyle.setFont(cellFont);

            // 遍历集合数据,产生数据行,填充Excel
            int rowIndex = 0;
            Sheet sheet = null;

            int sheetIndex=1;//sheet索引,从模板之后开始,所以为1
            for (DataObject data : datas) {

                if (rowIndex == 65535 || rowIndex == 0) {

                    //复制sheet
                    sheet = workbook.cloneSheet(0);// 如果数据超过了,则在第二页显示


                    //sheet命名
                    workbook.setSheetName(sheetIndex, sheetName+sheetIndex);


                    //删除第二行中的内容
                    sheet.removeRow(sheet.getRow(1));

                    rowIndex = 1;// 数据内容从 rowIndex=1开始
                    sheetIndex++;
                }

                //创建行
                Row dataRow = sheet.createRow(rowIndex);

                for (int i = 0; i < properties.length; i++) {
                    //创建单元格
                    Cell newCell = dataRow.createCell(i);

                    Object o = data.get(properties[i]);
                    String cellValue = "";
                    if (o == null) {//为空处理
                        cellValue = "";
                    } else if (o instanceof Date) {//日期格式化处理
                        cellValue = new SimpleDateFormat(datePattern).format(o);
                    } else {
                        cellValue = o.toString();
                    }
                    //单元格赋值
                    newCell.setCellValue(cellValue);
                    //单元格格式设置
                    newCell.setCellStyle(cellStyle);
                }
                rowIndex++;

            }

            OutputStream out = null;

            try {
                out = response.getOutputStream();
                fileName = fileName
                        + "_"
                        + new SimpleDateFormat("yyyyMMDDhh24mmssSSS")
                                .format(System.currentTimeMillis()) + ".xlsx";
                response.setContentType("application/x-msdownload");
                response.setHeader("Content-Disposition",
                        "attachment; filename="
                                + URLEncoder.encode(fileName, "UTF-8"));


                //删除模板
                workbook.removeSheetAt(0);
                // 保存报表文件
                workbook.write(out);
            } catch (IOException e) {

                e.printStackTrace();
            } finally {
                try {
                    if (out != null)
                        out.close();
                    response.flushBuffer();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }


        } 



    }


以下是调用代码(由于项目架构,是在jsp中调用的。):

try{

        DataObject criteria = (DataObject)request.getAttribute("criteria");
        //输出文件名前缀
        String fileName="PRODUCT";
        //sheet名前缀
        String sheetName="产品明细表";
        //日期格式
        String  datePattern = "yyyy-MM-dd";

        //获取项目在服务器目录中的路径
        String realPath=request.getSession().getServletContext().getRealPath("/");

        //模板相对路径+文件名
        String template="abframe\\excel-config\\productDetailTemplate.xlsx";

        String templatePath=realPath+template;


        ExcelExportUtil.exportExcelByTemplate(fileName,sheetName,response,criteria,templatePath,datePattern);




    } finally {
        out.clear();
        out = pageContext.pushBody();

    }

另外,在完成本项目时,excel的数据时条件查询的,所以根据条件检索后不一定有数据,所以为了用户体验(系统友好),在导出之前先调用Ajax检验是否有数据,有数据调用下载,无数据即可弹出提示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值