`
whoosh
  • 浏览: 235397 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

“Java+POI+模板”一:打造复杂Excel 报表

 
阅读更多

1 设计思路

Java 对于Excel 的操作一般借助于POI 类库,由于有些报表的表头比较复杂,直接用POI 控制报表的生成比较困难,这时可以先制作Excel 报表模板,而后再通过Java 调用POI 函数将用户数据写入到Excel 报表模板,最后导出到新的目标文件即可。

2 设计步骤

2.1 初始步骤

2.1.1创建Excel 报表模板

根据需要设计出Excel 报表,并保存为default.xls。如下图所示。



2.1.2创建ExcelTemplate类

/**
 * 该类实现了基于模板的导出
 * 如果要导出序号,需要在excel中定义一个标识为sernums
 * 如果要替换信息,需要传入一个Map,这个map中存储着要替换信息的值,在excel中通过#来开头
 * 要从哪一行那一列开始替换需要定义一个标识为datas
 * 如果要设定相应的样式,可以在该行使用styles完成设定,此时所有此行都使用该样式
 * 如果使用defaultStyls作为表示,表示默认样式,如果没有defaultStyles使用datas行作为默认样式
 */
public class ExcelTemplate {
        private ExcelTemplate() {

	}

	public static ExcelTemplate getInstance() {
		return et;
	}
}

 下面是以后要用到的一些变量和常量

/**
	 * 数据行标识
	 */
	public final static String DATA_LINE = "datas";
	/**
	 * 默认样式标识
	 */
	public final static String DEFAULT_STYLE = "defaultStyles";
	/**
	 * 行样式标识
	 */
	public final static String STYLE = "styles";
	/**
	 * 插入序号样式标识
	 */
	public final static String SER_NUM = "sernums";
	private static ExcelTemplate et = new ExcelTemplate();
	
	private Workbook wb;
	
	private Sheet sheet;
	/**
	 * 数据的初始化列数
	 */
	private int initColIndex;
	/**
	 * 数据的初始化行数
	 */
	private int initRowIndex;
	/**
	 * 当前列数
	 */
	private int curColIndex;
	/**
	 * 当前行数
	 */
	private int curRowIndex;
	/**
	 * 当前行对象
	 */
	private Row curRow;
	/**
	 * 最后一行的数据
	 */
	private int lastRowIndex;
	/**
	 * 默认样式
	 */
	private CellStyle defaultStyle;
	/**
	 * 默认行高
	 */
	private float rowHeight;
	/**
	 * 存储某一方所对于的样式
	 */
	private Map<Integer,CellStyle> styles;
	/**
	 * 序号的列
	 */
	private int serColIndex;

 

2.2 读取excel报表模板的数据

/**
	 * 1、读取相应的模板文档
	 */
	public ExcelTemplate readTemplateByClasspath(String path){
		try {
			wb=WorkbookFactory.create(ExcelTemplate.class.getResourceAsStream(path));
			initTemplate();
		} catch (InvalidFormatException e) {
			e.printStackTrace();
			throw new RuntimeException("InvalidFormatException, please check.");
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("The template is not exist, please check.");
		}
		return this;
	}
	
	public ExcelTemplate readTemplateByPath(String path){
		try {
			wb=WorkbookFactory.create(new File(path));
		} catch (InvalidFormatException e) {
			e.printStackTrace();
			throw new RuntimeException("InvalidFormatException, please check.");
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("The template is not exist, please check.");
		}
		return this;
	}

 在读取报表模板的时候会初始化模板,记录模板的样式,插入数据的位置

private void initTemplate(){
		sheet=wb.getSheetAt(0);
		initConfigData();
		lastRowIndex = sheet.getLastRowNum();
		curRow=sheet.getRow(curRowIndex);
	}
/**
	 * 循环遍历,找到有datas字符的那个单元,记录initColIndex,initRowIndex,curColIndex,curRowIndex
	 * 调用initStyles()方法
	 * 在寻找datas字符的时候会顺便找一下sernums,如果有则记录其列号serColIndex;如果没有则调用initSer()方法,重新循环查找
	 */
	private void initConfigData() {
		boolean findData=false;
		boolean findSer = false;
		for(Row row : sheet){
			if(findData) break;
			for(Cell c: row){
				if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue;
				String str=c.getStringCellValue().trim();
				if(str.equals(SER_NUM)){
					serColIndex=c.getColumnIndex();
					findSer=true;
				}
				if(str.equals(DATA_LINE)){
					initColIndex=c.getColumnIndex();
					initRowIndex=row.getRowNum();
					curColIndex=initColIndex;
					curRowIndex=initRowIndex;
					findData=true;
					break;
				}
			}
		}
		if(!findSer){
			initSer();
		}
		initStyles();
	}
/**
	 * 初始化序号位置
	 */
	private void initSer() {
		for(Row row:sheet) {
			for(Cell c:row) {
				if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue;
				String str = c.getStringCellValue().trim();
				if(str.equals(SER_NUM)) {
					serColIndex = c.getColumnIndex();
				}
			}
		}
	}
	
	/**
	 * 初始化样式信息
	 */
	private void initStyles(){
		styles = new HashMap<Integer, CellStyle>();
		for(Row row:sheet) {
			for(Cell c:row) {
				if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue;
				String str = c.getStringCellValue().trim();
				if(str.equals(DEFAULT_STYLE)) {
					defaultStyle = c.getCellStyle();
					rowHeight=row.getHeightInPoints();
				}
				if(str.equals(STYLE)||str.equals(SER_NUM)) {
					styles.put(c.getColumnIndex(), c.getCellStyle());
				}
			}
		}
	}

 

2.3 新建excel并向其写数据

public void writeToFile(String filepath){
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream(filepath);
			wb.write(fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("写入的文件不存在"+e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("写入数据失败"+e.getMessage());
		} finally{
			if(fos!=null)
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

 

2.4 实现Excel公共模板的第一步(实现了数据插入)

下面是创建单元格的方法,以及重载方法

public void createCell(String value){
		Cell c =curRow.createCell(curColIndex);
		setCellStyle(c);
		c.setCellValue(value);
		curColIndex++;
	}
	public void createCell(int value) {
		Cell c = curRow.createCell(curColIndex);
		setCellStyle(c);
		c.setCellValue((int)value);
		curColIndex++;
	}
	public void createCell(Date value) {
		Cell c = curRow.createCell(curColIndex);
		setCellStyle(c);
		c.setCellValue(value);
		curColIndex++;
	}
	public void createCell(double value) {
		Cell c = curRow.createCell(curColIndex);
		setCellStyle(c);
		c.setCellValue(value);
		curColIndex++;
	}
	public void createCell(boolean value) {
		Cell c = curRow.createCell(curColIndex);
		setCellStyle(c);
		c.setCellValue(value);
		curColIndex++;
	}
        public void createCell(Calendar value) {
		Cell c = curRow.createCell(curColIndex);
		setCellStyle(c);
		c.setCellValue(value);
		curColIndex++;
	}

上面的方法会调用setCellStyle方法来设置单元格样式

/**
	 * 设置某个单元格的样式
	 * @param c
	 */
	private void setCellStyle(Cell c) {
		if(styles.containsKey(c.getColumnIndex())) {
			c.setCellStyle(styles.get(c.getColumnIndex()));
		} else {
			c.setCellStyle(defaultStyle);
		}
	}

 createNewRow方法用于创建新的行,新的行的位置位于curRowIndex,从curRowIndex到lastRowIndex的所有行会自动向下移动一行。

public void createNewRow(){
		if(lastRowIndex>curRowIndex&&curRowIndex!=initRowIndex) {
			sheet.shiftRows(curRowIndex, lastRowIndex, 1,true,true);
			lastRowIndex++;
		}
		curRow = sheet.createRow(curRowIndex);
		curRow.setHeightInPoints(rowHeight);
		curRowIndex++;
		curColIndex=initColIndex;
	}

2.5 实现增加序号

/**
	 * 插入序号,会自动找相应的序号标示的位置完成插入
	 */
	public void insertSer() {
		int index = 1;
		Row row = null;
		Cell c = null;
		for(int i=initRowIndex;i<curRowIndex;i++) {
			row = sheet.getRow(i);
			c = row.createCell(serColIndex);
			setCellStyle(c);
			c.setCellValue(index++);
		}
	}

 2.6 替换模板中#开头的值

/**
	 * 根据map替换相应的常量,通过Map中的值来替换#开头的值
	 * @param datas
	 */
	public void replaceFinalData(Map<String,String> datas) {
		if(datas==null) return;
		for(Row row:sheet) {
			for(Cell c:row) {
				if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue;
				String str = c.getStringCellValue().trim();
				if(str.startsWith("#")) {
					if(datas.containsKey(str.substring(1))) {
						c.setCellValue(datas.get(str.substring(1)));
					}
				}
			}
		}
	}

 3实现步骤

@Test
	public void test01() {
		ExcelTemplate et = ExcelTemplate.getInstance()
					.readTemplateByClasspath("/excel/default.xls");
		et.createNewRow();
		et.createCell("1111111");
		et.createCell("aaaaaaaaaaaa");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("222222");
		et.createCell("bbbbb");
		et.createCell("b");
		et.createCell("dbbb");
		et.createNewRow();
		et.createCell("3333333");
		et.createCell("cccccc");
		et.createCell("a1");
		et.createCell(12333);
		et.createNewRow();
		et.createCell("4444444");
		et.createCell("ddddd");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell(112);
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell("a2a2");
		et.createNewRow();
		et.createCell("555555");
		et.createCell("eeeeee");
		et.createCell("a1");
		et.createCell("a2a2");
		Map<String,String> datas = new HashMap<String,String>();
		datas.put("title","测试用户信息");
		datas.put("date","2012-06-02 12:33");
		datas.put("dep","昭通师专财务处");
		et.replaceFinalData(datas);
		et.insertSer();
		et.writeToFile("d:/test/poi/test01.xls");
	}

 4 最后结果



 

  • 大小: 55 KB
  • 大小: 170.8 KB
分享到:
评论

相关推荐

    \"java+poi+Excel模板\"制作简单的报表

    标题中的“`java+poi+Excel模板`”指的是使用Java编程语言,结合Apache POI库来处理Microsoft Excel模板,以生成或编辑Excel报表的过程。Apache POI是一个流行的开源项目,它允许开发者使用Java读写Microsoft Office...

    “java+poi+模板”打造复杂excel报表.pdf

    《“java+poi+模板”打造复杂excel报表》 在Java开发中,生成复杂的Excel报表是一项常见的需求,尤其在数据分析、报表生成等领域。Apache POI库是Java中处理Microsoft Office格式文件的重要工具,它提供了对Excel...

    “java+poi+模板”打造复杂excel报表.docx

    本文将详细介绍如何利用Java+POI+模板的方式打造复杂Excel报表。 首先,理解设计思路。在Java应用中,Apache POI是一个流行的API,它允许程序读取、写入和修改Microsoft Office格式的文件,包括Excel。对于复杂报表...

    “Java POI 模板”打造复杂Excel报表.pdf

    Java POI 模板打造复杂Excel报表 本文主要介绍了使用Java POI模板来生成复杂的Excel报表的方法。POI(Poor Obfuscation Implementation)是一个Java API,用于读取和写入Microsoft Office文件格式,包括Excel文件。...

    java基于poi使用excel模板导出

    在Java开发中,Apache POI库是一个非常流行的用于读写Microsoft Office格式文件的库,包括Excel。本篇文章将深入探讨如何使用Apache POI基于模板来导出Excel文件,以满足数据展示和报告生成的需求。 首先,我们需要...

    poi 操作excel模板

    Apache POI 是一个开源项目,专门用于处理Microsoft Office格式的文件,包括Excel。在Java开发中,POI库被广泛用于生成、修改和读取Excel文档。本篇将深入探讨如何利用Apache POI来操作Excel模板,以及如何读取数据...

    java使用 POI Excel模板导出数据

    这篇博客"java使用POI Excel模板导出数据"探讨了如何利用POI库在Java中创建Excel模板并填充数据。下面将详细介绍这个过程以及相关知识点。 首先,我们需要理解Apache POI的基本概念。POI是Apache软件基金会的一个...

    java poi 根据excel模板生成excel文件

    Java POI库是Apache软件基金会开发的一个开源项目,专门用于读写Microsoft Office格式的文件,包括Excel。在本文中,我们将深入探讨如何使用Java POI库根据已有的Excel模板生成新的Excel文件。 首先,理解“模板”...

    java通过poi模板导出excel

    Java通过Apache POI库导出Excel是常见的数据处理任务,特别是在大数据分析、报表生成和数据交换等场景...在实际项目中,根据需求调整细节,如增加数据验证、公式计算、图表生成等高级特性,以满足复杂的Excel报表需求。

    Java Struts2+poi插件 实现导出Excel

    这个项目"Java Struts2+poi插件 实现导出Excel"就是结合这两个工具,为用户提供一个功能,能够将数据导出到Excel格式的文件中。 首先,让我们详细了解一下Struts2。Struts2的核心是Action,它负责接收请求、处理...

    使用java Apache poi 根据word模板生成word报表.rar

    在本项目中,“使用java Apache poi 根据word模板生成word报表.rar”是一个压缩包,其中包含了一套使用Java和Apache POI库来根据预设的Word模板生成定制化报表的解决方案。 首先,我们需要理解Apache POI API的工作...

    java复杂模板excel导出例子

    总的来说,Java中导出复杂模板Excel的过程涉及模板设计、API使用、数据填充、格式调整等多个环节。熟练掌握Apache POI或其他相关库的用法,结合业务需求,能有效提高工作效率并提供高质量的Excel导出功能。在实际...

    java 生成Excel,可根据模板格式生成 Excel打印专用 报表

    在Java编程环境中,生成Excel报表是一项常见的任务,特别是在数据分析、数据导出或报表制作的场景中。本示例关注的是如何使用Java根据模板格式来创建适用于打印的专业Excel报表。这通常涉及到对Apache POI库的使用,...

    Java操作Excel之Poi模板导入导出

    在"Java操作Excel之Poi模板导入导出"这个主题中,我们将深入探讨如何使用POI库来处理Excel模板,并进行数据的导入和导出。 首先,了解Excel模板的基本概念。模板通常包含预定义的样式、格式和计算,开发人员可以...

    java Apache poi word模板 表格模板 word报表.zip

    Java Apache POI 是一个强大的库,它允许程序员在Java应用程序中创建、修改和显示Microsoft Office格式的文件,包括Word文档(.docx)和Excel工作簿(.xlsx)。本资料包着重介绍了如何利用Apache POI库来处理Word...

    java实现poi模板生成PPT文件代码

    Apache POI 是一个开源项目,它提供了Java API来处理Microsoft Office格式的文件,如XLS(Excel),DOC(Word)和PPT。在我们的场景中,我们将专注于PPT文件的创建。 2. **POI与PPT文件结构**: PowerPoint文档由...

    java生成excel文件(poi).rar_POI java_java excel_poi EXCEL模板_poi-3.8-

    在“POI java_java excel_poi EXCEL模板”这一标签中,我们可以推测这个项目可能包含了一些使用POI创建Excel模板的方法,这些模板可以用于填充动态数据并生成定制化的报表。 在具体使用POI时,主要涉及以下几个关键...

    Java通过POI和JXL给Excel动态添加水印

    - **Apache POI**: 同样是处理Excel文件的强大Java库,除了支持.xls外还支持.xlsx等新版本格式,并且提供了更多的功能,如图表、图片等复杂元素的处理。 #### 实现步骤详解 ### 步骤一:创建模型类 首先,我们...

    poi报表+详细文档

    在Excel报表的创建中,Apache POI提供了一个强大的API,允许开发者用Java编程语言来处理Excel工作簿、工作表、单元格等元素。以下是使用POI进行Excel报表制作的一些关键知识点: 1. **HSSFWorkbook与XSSFWorkbook**...

Global site tag (gtag.js) - Google Analytics