博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用POI生成Excel报表
阅读量:6358 次
发布时间:2019-06-23

本文共 6218 字,大约阅读时间需要 20 分钟。

先把报表模板截图贴上来

使用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());	}}
你可能感兴趣的文章
Outlook.com高级版优惠价截止日顺延到6月30日
查看>>
CMOS感光元件市场谁是老大?索尼笑而不语
查看>>
浅析基于客户价值的客户关系管理
查看>>
大数据产业成机构布局重点
查看>>
大数据产业驱动中国经济新增长
查看>>
《SQL入门经典(第5版)》一一6.3 事务控制与数据库性能
查看>>
《Microsoft.NET企业级应用架构设计(第2版)》——1.4 笑到最后
查看>>
怎样才能自学好Java?
查看>>
《无线网络:理解和应对互联网环境下网络互连所带来的挑战》——2.9 蓝牙SIG...
查看>>
《OpenACC并行编程实战》—— 第3章 OpenACC计算构件 3.1 条件编译
查看>>
css的hover事件,如果点击之后通过js操作样式,hover事件就会失效的处理方法,外部css样式与js的DOM样式谁的权重高?...
查看>>
《DB2性能管理与实战》——2.6 DB2 pureScale环境中内存管理
查看>>
《Android应用开发入门经典(第3版)》——第6.9节练习
查看>>
演讲实录丨马迁 智慧教育的发展和分步实施
查看>>
超酷的 Vim 搜索技巧
查看>>
《软件测试技术实战:设计、工具及管理》—第1章 1.2节软件测试的七项基本原则...
查看>>
《精通Python网络爬虫:核心技术、框架与项目实战》——1.2 为什么要学网络爬虫...
查看>>
《C++ 黑客编程揭秘与防范(第2版)》——6.1 PE文件结构
查看>>
《Unity虚拟现实开发实战》——第2章,第2.3节测量工具
查看>>
聊聊身份欺诈和窃取那些事
查看>>