使用POI生成Excel报表

jopen 6年前

先把报表模板截图贴上来

 

使用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 另外模板文件<>下载地址为http://download.csdn.net/detail/jadyer/5736263   * @create Jul 5, 2013 9:54:46 PM   * @author 玄玉   */  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 allCellStyle = new HashMap();   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 constantData = new HashMap();    constantData.put("title", "优秀学生名单");    constantData.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));    constantData.put("developer", "玄玉博客");    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 FileOutputStream(filepath);     wb.write(fos);    } catch (FileNotFoundException e) {     throw new RuntimeException("写入的文件[" + filepath + "]不存在", e);    } catch (IOException e) {     throw new RuntimeException("写入数据失败", e);    } finally {     if(null != fos){      try {       fos.close();      } catch (IOException e) {       e.printStackTrace();      }     }    }   }  }

最后是其单元测试类ExcelReportTest.java(即演示实际调用步骤)

package com.jadyer.report;    import java.io.File;    import org.junit.Assert;  import org.junit.Test;    import com.jadyer.report.ExcelReport;    public class ExcelReportTest {   @Test   public void testExcelReportUtil(){    ExcelReport eru = ExcelReport.INSTANCE;    eru.createNewRow();    eru.buildCell("aa");    eru.buildCell("玄玉");    eru.buildCell("cc");    eru.buildCell("dd");    eru.createNewRow();    eru.buildCell("aa");    eru.buildCell("http://blog.csdn.net/jadyer");    eru.buildCell("cc");    eru.buildCell("dd");    eru.createNewRow();    eru.buildCell("aa");    eru.buildCell("蓄机而动");    eru.buildCell("cc");    eru.buildCell("dd");    eru.writeToFile("D:/test.xls");    Assert.assertTrue(new File("D:/test.xls").exists());   }  }