使用POI生成Excel报表

来源:互联网 发布:淘宝的驱鼠器有用吗 编辑:程序博客网 时间:2024/05/24 15:41

先把报表模板截图贴上来


使用POI生成Excel报表


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

[java] view plaincopyprint?
  1. package com.jadyer.report;  
  2.   
  3. import java.io.FileNotFoundException;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.OutputStream;  
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Date;  
  9. import java.util.HashMap;  
  10. import java.util.Map;  
  11.   
  12. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;  
  13. import org.apache.poi.ss.usermodel.Cell;  
  14. import org.apache.poi.ss.usermodel.CellStyle;  
  15. import org.apache.poi.ss.usermodel.Row;  
  16. import org.apache.poi.ss.usermodel.Sheet;  
  17. import org.apache.poi.ss.usermodel.Workbook;  
  18. import org.apache.poi.ss.usermodel.WorkbookFactory;  
  19.   
  20. /** 
  21.  * 使用POI生成Excel报表 
  22.  * @see 它所生成的报表是根据Excel模块文件生成的 
  23.  * @see 这里要用到poi-3.9-20121203.jar和poi-ooxml-3.9-20121203.jar 
  24.  * @see 另外模板文件<<ReportTemplate.xls>>下载地址为http://download.csdn.net/detail/jadyer/5736263 
  25.  * @create Jul 5, 2013 9:54:46 PM 
  26.  * @author 玄玉<http://blog.csdn.net/jadyer> 
  27.  */  
  28. public enum ExcelReport {  
  29.     //实现单例模式的唯一实例  
  30.     INSTANCE;  
  31.     /**报表模板文件的存储位置*/  
  32.     private static final String REPORT_TEMPLATE_FILE_PATH = "/ReportTemplate.xls";  
  33.     /**本列开始填充序号的标识*/  
  34.     private static final String SERIAL_NO = "serialNo";  
  35.     /**本行开始填充数据的标识*/  
  36.     private static final String DATA_BEGIN = "dataBegin";  
  37.     /**表格采用同列样式的标识*/  
  38.     private static final String USE_STYLES = "useStyles";  
  39.     /**表格样式采用的默认样式*/  
  40.     private static final String DEFAULT_STYLES = "defaultStyles";  
  41.     /**初始行的下标(指的是填充数据的第一个单元格下标)*/  
  42.     private int initRowIndex;  
  43.     /**初始列的下标(指的是填充数据的第一个单元格下标)*/  
  44.     private int initColIndex;  
  45.     /**当前行的下标(指的是填充数据的当前单元格下标)*/  
  46.     private int currRowIndex;  
  47.     /**当前列的下标(指的是填充数据的当前单元格下标)*/  
  48.     private int currColIndex;  
  49.     /**最后一行的下标*/  
  50.     private int lastRowIndex;  
  51.     /**序号列的第一个单元格的下标*/  
  52.     private int serialColIndex;  
  53.     /**默认行高(指的是填充数据的第一个单元格的行高)*/  
  54.     private float defaultRowHeight;  
  55.     /**存放模板中所有表格样式(键为99表示表格的默认样式)*/  
  56.     private Map<Integer, CellStyle> allCellStyle = new HashMap<Integer, CellStyle>();  
  57.     private Row currRow;  
  58.     private Sheet sheet;  
  59.     private Workbook wb;  
  60.       
  61.       
  62.     /** 
  63.      * 基础数据初始化 
  64.      */  
  65.     private ExcelReport(){  
  66.         try {  
  67.             //从指定目录中读取  
  68.             //wb = WorkbookFactory.create(new File(REPORT_TEMPLATE_FILE_PATH));  
  69.             //从classpath中读取模板文档  
  70.             wb = WorkbookFactory.create(ExcelReport.class.getResourceAsStream(REPORT_TEMPLATE_FILE_PATH));  
  71.             //获取模板中的第一个Sheet  
  72.             sheet = wb.getSheetAt(0);  
  73.         } catch (InvalidFormatException e) {  
  74.             throw new RuntimeException("模板文件格式无效", e);  
  75.         } catch (IOException e) {  
  76.             throw new RuntimeException("模板文件不存在", e);  
  77.         }  
  78.         for(Row row : sheet){  
  79.             for(Cell cell : row){  
  80.                 //报表模板文件default.xls中约定序号和SERIAL_NO和DATA_BEGIN都是String类型的  
  81.                 if(Cell.CELL_TYPE_STRING != cell.getCellType()){  
  82.                     continue;  
  83.                 }  
  84.                 String str = cell.getStringCellValue().trim();  
  85.                 //收集默认的表格样式  
  86.                 if(DEFAULT_STYLES.equals(str)){  
  87.                     this.allCellStyle.put(99, cell.getCellStyle());  
  88.                 }  
  89.                 //收集除默认表格样式以外的所有表格样式  
  90.                 if(USE_STYLES.equals(str)){  
  91.                     this.allCellStyle.put(cell.getColumnIndex(), cell.getCellStyle());  
  92.                 }  
  93.                 //定位序号列的第一个单元格下标  
  94.                 if(SERIAL_NO.equals(str)){  
  95.                     this.serialColIndex = cell.getColumnIndex();  
  96.                 }  
  97.                 //定位开始填充数据的第一个单元格的下标  
  98.                 if(DATA_BEGIN.equals(str)){  
  99.                     this.initColIndex = cell.getColumnIndex();  
  100.                     this.initRowIndex = row.getRowNum();  
  101.                     this.currColIndex = this.initColIndex;  
  102.                     this.currRowIndex = this.initRowIndex;  
  103.                     this.lastRowIndex = sheet.getLastRowNum();  
  104.                     this.defaultRowHeight = row.getHeightInPoints();  
  105.                 }  
  106.             }  
  107.         }  
  108.     }  
  109.       
  110.       
  111.     /** 
  112.      * 创建行 
  113.      */  
  114.     public void createNewRow(){  
  115.         //下移行的条件有2个:当前行非初始行,且当前行没有超过最后一行  
  116.         if(this.currRowIndex!=this.initRowIndex && this.lastRowIndex>this.currRowIndex){  
  117.             //将指定的几行进行下移一行  
  118.             sheet.shiftRows(this.currRowIndex, this.lastRowIndex, 1truetrue);  
  119.             //既然下移了那么最后一行下标就也要增大了  
  120.             this.lastRowIndex++;  
  121.         }  
  122.         //在指定的行上创建一个空行(如果此行原本有单元格和数据,那么也会被空行覆盖,且创建出来的空行是没有单元格的)  
  123.         this.currRow = sheet.createRow(this.currRowIndex);  
  124.         this.currRow.setHeightInPoints(this.defaultRowHeight);  
  125.         this.currRowIndex++;  
  126.         this.currColIndex = this.initColIndex;  
  127.     }  
  128.       
  129.       
  130.     /** 
  131.      * 构造单元格(包括创建单元格和填充数据) 
  132.      */  
  133.     public void buildCell(String value){  
  134.         Cell cell = this.currRow.createCell(this.currColIndex);  
  135.         if(this.allCellStyle.containsKey(this.currColIndex)){  
  136.             cell.setCellStyle(this.allCellStyle.get(this.currColIndex));  
  137.         }else{  
  138.             cell.setCellStyle(this.allCellStyle.get(99));  
  139.         }  
  140.         cell.setCellValue(value);  
  141.         this.currColIndex++;  
  142.     }  
  143.   
  144.       
  145.     /** 
  146.      * 插入序号 
  147.      */  
  148.     private void insertSerialNo(){  
  149.         int index = 1;  
  150.         Row row = null;  
  151.         Cell cell = null;  
  152.         for(int i=this.initRowIndex; i<this.currRowIndex; i++){  
  153.             row = sheet.getRow(i);  
  154.             cell = row.createCell(this.serialColIndex);  
  155.             cell.setCellValue(index++);  
  156.         }  
  157.     }  
  158.       
  159.       
  160.     /** 
  161.      * 替换模板文件中的常量 
  162.      */  
  163.     private void replaceConstantData(){  
  164.         Map<String, String> constantData = new HashMap<String, String>();  
  165.         constantData.put("title""优秀学生名单");  
  166.         constantData.put("date"new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));  
  167.         constantData.put("developer""玄玉博客<http://blog.csdn.net/jadyer>");  
  168.         for(Row row : sheet){  
  169.             for(Cell cell : row){  
  170.                 if(Cell.CELL_TYPE_STRING != cell.getCellType()){  
  171.                     continue;  
  172.                 }  
  173.                 String str = cell.getStringCellValue().trim();  
  174.                 if(str.startsWith("#")){  
  175.                     if(constantData.containsKey(str.substring(1))){  
  176.                         cell.setCellValue(constantData.get(str.substring(1)));  
  177.                     }  
  178.                 }  
  179.             }  
  180.         }  
  181.     }  
  182.       
  183.       
  184.     /** 
  185.      * 将生成的excel文件写到输出流中 
  186.      * @see 适用于文件下载 
  187.      */  
  188.     public void writeToStream(OutputStream os){  
  189.         this.insertSerialNo();  
  190.         this.replaceConstantData();  
  191.         try {  
  192.             wb.write(os);  
  193.         } catch (IOException e) {  
  194.             throw new RuntimeException("写入流失败", e);  
  195.         }  
  196.     }  
  197.       
  198.       
  199.     /** 
  200.      * 将生成的excel文件写到指定的文件中 
  201.      * @see 适用于硬盘保存 
  202.      */  
  203.     public void writeToFile(String filepath){  
  204.         this.insertSerialNo();  
  205.         this.replaceConstantData();  
  206.         FileOutputStream fos = null;  
  207.         try {  
  208.             fos = new FileOutputStream(filepath);  
  209.             wb.write(fos);  
  210.         } catch (FileNotFoundException e) {  
  211.             throw new RuntimeException("写入的文件[" + filepath + "]不存在", e);  
  212.         } catch (IOException e) {  
  213.             throw new RuntimeException("写入数据失败", e);  
  214.         } finally {  
  215.             if(null != fos){  
  216.                 try {  
  217.                     fos.close();  
  218.                 } catch (IOException e) {  
  219.                     e.printStackTrace();  
  220.                 }  
  221.             }  
  222.         }  
  223.     }  
  224. }  

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

[java] view plaincopyprint?
  1. package com.jadyer.report;  
  2.   
  3. import java.io.File;  
  4.   
  5. import org.junit.Assert;  
  6. import org.junit.Test;  
  7.   
  8. import com.jadyer.report.ExcelReport;  
  9.   
  10. public class ExcelReportTest {  
  11.     @Test  
  12.     public void testExcelReportUtil(){  
  13.         ExcelReport eru = ExcelReport.INSTANCE;  
  14.         eru.createNewRow();  
  15.         eru.buildCell("aa");  
  16.         eru.buildCell("玄玉");  
  17.         eru.buildCell("cc");  
  18.         eru.buildCell("dd");  
  19.         eru.createNewRow();  
  20.         eru.buildCell("aa");  
  21.         eru.buildCell("http://blog.csdn.net/jadyer");  
  22.         eru.buildCell("cc");  
  23.         eru.buildCell("dd");  
  24.         eru.createNewRow();  
  25.         eru.buildCell("aa");  
  26.         eru.buildCell("蓄机而动");  
  27.         eru.buildCell("cc");  
  28.         eru.buildCell("dd");  
  29.         eru.writeToFile("D:/test.xls");  
  30.         Assert.assertTrue(new File("D:/test.xls").exists());  
  31.     }  
  32. }  
原创粉丝点击