当前位置:软件学习 > Excel >>

使用POI生成Excel报表

先把报表模板截图贴上来

 

下面是POI编写的报表生成类ExcelReport.java


 

package com.jadyer.report; 
 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.HashMap; 
import java.util.Map; 
 
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; 
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.CellStyle; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.ss.usermodel.Sheet; 
import org.apache.poi.ss.usermodel.Workbook; 
import org.apache.poi.ss.usermodel.WorkbookFactory; 
 
/**
 * 使用POI生成Excel报表
 * @see 它所生成的报表是根据Excel模块文件生成的
 * @see 这里要用到poi-3.9-20121203.jar和poi-ooxml-3.9-20121203.jar
 * @see 另外模板文件<<ReportTemplate.xls>>下载地址为http://download.csdn.net/detail/jadyer/5736263
 * @create Jul 5, 2013 9:54:46 PM
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */ 
public enum ExcelReport { 
    //实现单例模式的唯一实例  
    INSTANCE; 
    /**报表模板文件的存储位置*/ 
    private static final String REPORT_TEMPLATE_FILE_PATH = "/ReportTemplate.xls"; 
    /**本列开始填充序号的标识*/ 
    private static final String SERIAL_NO = "serialNo"; 
    /**本行开始填充数据的标识*/ 
    private static final String DATA_BEGIN = "dataBegin"; 
    /**表格采用同列样式的标识*/ 
    private static final String USE_STYLES = "useStyles"; 
    /**表格样式采用的默认样式*/ 
    private static final String DEFAULT_STYLES = "defaultStyles"; 
    /**初始行的下标(指的是填充数据的第一个单元格下标)*/ 
    private int initRowIndex; 
    /**初始列的下标(指的是填充数据的第一个单元格下标)*/ 
    private int initColIndex; 
    /**当前行的下标(指的是填充数据的当前单元格下标)*/ 
    private int currRowIndex; 
    /**当前列的下标(指的是填充数据的当前单元格下标)*/ 
    private int currColIndex; 
    /**最后一行的下标*/ 
    private int lastRowIndex; 
    /**序号列的第一个单元格的下标*/ 
    private int serialColIndex; 
    /**默认行高(指的是填充数据的第一个单元格的行高)*/ 
    private float defaultRowHeight; 
    /**存放模板中所有表格样式(键为99表示表格的默认样式)*/ 
    private Map<Integer, CellStyle> allCellStyle = new HashMap<Integer, CellStyle>(); 
    private Row currRow; 
    private Sheet sheet; 
    private Workbook wb; 
     
     
    /**
     * 基础数据初始化
     */ 
    private ExcelReport(){ 
        try { 
            //从指定目录中读取  
            //wb = WorkbookFactory.create(new File(REPORT_TEMPLATE_FILE_PATH));  
            //从classpath中读取模板文档  
            wb = WorkbookFactory.create(ExcelReport.class.getResourceAsStream(REPORT_TEMPLATE_FILE_PATH)); 
            //获取模板中的第一个Sheet  
            sheet = wb.getSheetAt(0); 
        } catch (InvalidFormatException e) { 
            throw new RuntimeException("模板文件格式无效", e); 
        } catch (IOException e) { 
            throw new RuntimeException("模板文件不存在", e); 
        } 
        for(Row row : sheet){ 
            for(Cell cell : row){ 
                //报表模板文件default.xls中约定序号和SERIAL_NO和DATA_BEGIN都是String类型的  
                if(Cell.CELL_TYPE_STRING != cell.getCellType()){ 
                    continue; 
                } 
                String str = cell.getStringCellValue().trim(); 
                //收集默认的表格样式  
                if(DEFAULT_STYLES.equals(str)){ 
                    this.allCellStyle.put(99, cell.getCellStyle()); 
                } 
                //收集除默认表格样式以外的所有表格样式  
                if(USE_STYLES.equals(str)){ 
                    this.allCellStyle.put(cell.getColumnIndex(), cell.getCellStyle()); 
                } 
                //定位序号列的第一个单元格下标  
                if(SERIAL_NO.equals(str)){ 
                    this.serialColIndex = cell.getColumnIndex(); 
                } 
                //定位开始填充数据的第一个单元格的下标  
                if(DATA_BEGIN.equals(str)){ 
                    this.initColIndex = cell.getColumnIndex(); 
                    this.initRowIndex = row.getRowNum(); 
                    this.currColIndex = this.initColIndex; 
                    this.currRowIndex = this.initRowIndex; 
                    this.lastRowIndex = sheet.getLastRowNum(); 
                    this.defaultRowHeight = row.getHeightInPoints(); 
                } 
            } 
        } 
    } 
     
     
    /**
     * 创建行
     */ 
    public void createNewRow(){ 
        //下移行的条件有2个:当前行非初始行,且当前行没有超过最后一行  
        if(this.currRowIndex!=this.initRowIndex && this.lastRowIndex>this.currRowIndex){ 
            //将指定的几行进行下移一行  
            sheet.shiftRows(this.currRowIndex, this.lastRowIndex, 1, true, true); 
            //既然下移了那么最后一行下标就也要增大了  
            this.lastRowIndex++; 
        } 
        //在指定的行上创建一个空行(如果此行原本有单元格和数据,那么也会被空行覆盖,且创建出来的空行是没有单元格的)  
        this.currRow = sheet.createRow(this.currRowIndex); 
        this.currRow.setHeightInPoints(this.defaultRowHeight); 
        this.currRowIndex++; 
        this.currColIndex = this.initColIndex; 
    } 
     
     
    /**
     * 构造单元格(包括创建单元格和填充数据)
     */ 
    public void buildCell(String value){ 
        Cell cell = this.currRow.createCell(this.currColIndex); 
        if(this.allCellStyle.containsKey(this.currColIndex)){ 
            cell.setCellStyle(this.allCellStyle.get(this.currColIndex)); 
        }else{ 
            cell.setCellStyle(this.allCellStyle.get(99)); 
        } 
        cell.setCellValue(value); 
        this.currColIndex++; 
    } 
 
     
    /**
     * 插入序号
     */ 
    private void insertSerialNo(){ 
        int index = 1; 
        Row row = null; 
        Cell cell = null; 
        for(int i=this.initRowIndex; i<this.currRowIndex; i++){ 
            row = sheet.getRow(i); 
            cell = row.createCell(this.serialColIndex); 
            cell.setCellValue(index++); 
        } 
    } 
     
     
    /**
     * 替换模板文件中的常量
     */ 
    private void replaceConstantData(){ 
        Map<String, String> constantData = new HashMap<String, String>(); 
        constantData.put("title", "优秀学生名单"); 
        constantData.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 
        constantData.put("developer", "玄玉博客<http://blog.csdn.net/jadyer>"); 
        for(Row row : sheet){ 
            for(Cell cell : row){ 
                if(Cell.CELL_TYPE_STRING != cell.getCellType()){ 
                    continue; 
                } 
                String str = cell.getStringCellValue().trim(); 
                if(str.startsWith("#")){ 
                    if(constantData.containsKey(str.substring(1))){ 
                        cell.setCellValue(constantData.get(str.substring(1))); 
                    } 
                } 
            } 
        } 
    } 
     
     
    /**
     * 将生成的excel文件写到输出流中
     * @see 适用于文件下载
     */ 
    public void writeToStream(OutputStream os){ 
        this.insertSerialNo(); 
        this.replaceConstantData(); 
        try { 
            wb.write(os); 
        } catch (IOException e) { 
            throw new RuntimeException("写入流失败", e); 
        } 
    } 
     
     
    /**
     * 将生成的excel文件写到指定的文件中
     * @see 适用于硬盘保存
     */ 
    public void writeToFile(String filepath){ 
        this.insertSerialNo(); 
        this.replaceConstantData(); 
        FileOutputStream fos = null; 
        try { 
            fos = new Fi
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,