`
duolaaqian
  • 浏览: 14113 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

[joy]POI导出Excel简单扩展(一)

    博客分类:
  • java
阅读更多

学习实践

 

目标:

1、简化POI导出Excel的调用,方便使用(只提供数据即可)。

2、具有一定的扩展性(整体默认样式、单元格样式)。

3、对一些设计模式的具体实践。

 

技术要求:

对POI进行扩展。

模仿JSONObject(JsonValueProcessor)、easyui的datagrid(formatter/styler)。

模板方法模式、桥接模式。

 

涉及的类:

ExportGenerator 核心类 导出具体实现类,子类可对其进行扩展
ExportConfig 核心类 用于保存导出相关配置
CellValueProcessor 核心接口 单元格处理器接口
YearReportExportGenerator 扩展类 对ExportGenerator的扩展,提供一些基础样式

 



 

 整个程序的执行过程:



 

具体代码:

/**
 * 该类只提供生成workbook、填充数据到workbook 
 * 子类可对支持的数据格式进行拓展 子类可在生成前后加逻辑进行拓展
 * 
 * 支持的数据格式: List<Map>、List<DynaBean>、List<List> 
 * 其他数据格式可自己扩展 Collention<?> + ?[]
 * (Collention各种+数组各种) SimpleExportGenerator --> 简单导出,支持常见的格式
 * ComplexExportGenerator(implements simple) --> 复杂导出,支持Collention<?>
 * 
 * 生成workbook执行顺序(子类可重写) 
 * 1、postProcessBeforeGenerate() 
 * 2、generate()
 * 3、postProcessAfterGenerate()
 */
public class ExportGenerator {
	private List<Map> dataList; //所要导出的数据

	private HSSFWorkbook workBook; //workBook实体类

	private ExportConfig exportConfig; //导出配置信息

	public ExportGenerator() {
		this(new ArrayList<Map>());
	};
	public ExportGenerator(List<Map> dataList) {
		this(dataList==null?new ArrayList<Map>():dataList, new ExportConfig());
	};
	public ExportGenerator(List<Map> dataList, ExportConfig exportConfig) {
		this.dataList = dataList==null?new ArrayList<Map>():dataList;
		this.exportConfig = exportConfig==null?new ExportConfig():exportConfig;
	};

	public ExportConfig getExportConfig() {
		return this.exportConfig;
	}
	public void setExportConfig(ExportConfig exportConfig) {
		this.exportConfig = exportConfig;
	}

	public List<Map> getDataList() {
		return this.dataList;
	};
	public void setDataList(List<Map> dataList) {
		this.dataList = dataList;
	};
	
	public HSSFWorkbook getWorkBook() {
		return workBook;
	}
	public void setWorkBook(HSSFWorkbook workBook) {
		this.workBook = workBook;
	}

	/**
	 * 获取 HSSFWorkbook 的源头 子类可以进行拓展
	 */
	protected HSSFWorkbook initWorkbook() {
		return new HSSFWorkbook();
	}

	/**
	 * 生成excel模板方法 主要确定方法执行顺序
	 */
	public void generateWorkBook() {
		workBook = initWorkbook();
		postProcessBeforeGenerate(dataList, workBook);
		generate(dataList, workBook);
		postProcessAfterGenerate(dataList, workBook);
	}

	/**
	 * 填充数据前调用该方法
	 */
	public void postProcessBeforeGenerate(List<Map> dataList,HSSFWorkbook workBook) {};

	/**
	 * 填充完数据后调用该方法
	 */
	public void postProcessAfterGenerate(List<Map> dataList,HSSFWorkbook workBook) {};

	/**
	 * 获取sheet
	 */
	protected HSSFSheet getOrCreateSheet(int index,HSSFWorkbook workBook){
		if(workBook.getNumberOfSheets()>0){
			return workBook.getSheetAt(0);
		}
		return workBook.createSheet();
	}
	
	/**
	 * 具体生成workBook方法
	 */
	protected void generate(List<Map> dataList, HSSFWorkbook workBook) {
		HSSFSheet sheet = getOrCreateSheet(0,workBook);
		int rowIndex = exportConfig.getRowStartIndex(), colIndex = exportConfig.getColStartIndex();
		for (Map m : dataList) {
			HSSFRow row = sheet.createRow(rowIndex);
			for (Object k : m.keySet()) {
				HSSFCell cell = row.createCell(colIndex);
				Object value = processCellValue(m.get(k), row, cell);
				setValue(cell, value);
				cell.setCellStyle(processCellStyle(value, row, cell));
				colIndex++;
			}
			colIndex = 0;
			rowIndex++;
		}
	}

	/**
	 * 对poi中的cell进行赋值
	 */
	protected void setValue(HSSFCell cell, Object value) {
		if (null == value) {
			cell.setCellValue((java.lang.String) value);//如果值为null的话,poi自己会处理
		} else if (value instanceof java.lang.String) {
			cell.setCellValue((java.lang.String) value);
		} else if (value instanceof java.lang.Double) {
			cell.setCellValue((double) value);
		} else if (value instanceof java.lang.Float) {
			cell.setCellValue((float) value);
		} else if (value instanceof java.lang.Long) {
			cell.setCellValue((long) value);
		} else if (value instanceof java.lang.Integer) {
			cell.setCellValue((int) value);
		} else if (value instanceof java.lang.Short) {
			cell.setCellValue((short) value);
		} else if (value instanceof java.lang.Boolean) {
			cell.setCellValue((boolean) value);
		} else if (value instanceof java.util.Date) {
			cell.setCellValue((java.util.Date) value);
		} else if (value instanceof java.util.Calendar) {
			cell.setCellValue((java.util.Calendar) value);
		} else if (value instanceof org.apache.poi.ss.usermodel.RichTextString) {
			cell.setCellValue((org.apache.poi.ss.usermodel.RichTextString) value);
		} else {
			cell.setCellValue(value.toString());// 无匹配类型按String处理
		}
	}

	/**
	 * 根据Processor获取值
	 */
	protected Object processCellValue(Object obj, HSSFRow row, HSSFCell cell) {
		CellValueProcessor cvp = exportConfig.getCellValueProcessor();
		if (null == cvp) {
			return obj;
		}
		return cvp.processCellValue(obj, row, cell);
	}

	/**
	 * 根据Processor获取值 返回空不影响已有样式
	 */
	protected CellStyle processCellStyle(Object value, HSSFRow row,HSSFCell cell) {
		CellValueProcessor cvp = exportConfig.getCellValueProcessor();
		if (null == cvp) {
			return null;
		}
		return cvp.processCellStyle(value, row, cell);
	}

	public HSSFWorkbook getWorkBookInstance() {
		return getWorkBookInstance(false);
	}

	/**
	 * 向外部提供获取 HSSFWorkbook 的方法 refresh 是否重新生成HSSFWorkbook
	 */
	public HSSFWorkbook getWorkBookInstance(boolean refresh) {
		if (refresh || null == workBook) {
			generateWorkBook();
		}
		return workBook;
	}
}

 

/**
 * 导出配置,方便传递各种参数
 */
public class ExportConfig {
	
	/**
	 * 填充数据的开始行坐标
	 */
	private int rowStartIndex=0;
	
	/**
	 * 填充数据的开始列坐标
	 */
	private int colStartIndex=0;
	
	/**
	 * 填充单元格时的值处理器
	 */
	CellValueProcessor cellValueProcessor;

	public CellValueProcessor getCellValueProcessor(){
		return cellValueProcessor;
	}
	public void setCellValueProcessor(CellValueProcessor cellValueProcessor){
		this.cellValueProcessor = cellValueProcessor;
	}

	public int getRowStartIndex() {
		return rowStartIndex;
	}
	public void setRowStartIndex(int rowStartIndex) {
		this.rowStartIndex = rowStartIndex;
	}

	public int getColStartIndex() {
		return colStartIndex;
	}
	public void setColStartIndex(int colStartIndex) {
		this.colStartIndex = colStartIndex;
	}
}

 

/**
 * 值产生器接口
 */
public interface CellValueProcessor {
	
	Object processCellValue(Object value,HSSFRow row,HSSFCell cell);
	
	CellStyle processCellStyle(Object value,HSSFRow row,HSSFCell cell);
}

 

简单扩展:

public class YearReportExportGenerator extends ExportGenerator{
	public YearReportExportGenerator(List<Map> dataList) {
		super(dataList);
	}
	public YearReportExportGenerator(List<Map> dataList, ExportConfig exportConfig) {
		super(dataList, exportConfig);
	}
	
	/**
	 * 添加表头数据
	 */
	@Override
	public void postProcessBeforeGenerate(List<Map> dataList,HSSFWorkbook workBook) {
		createHead();
	}
	@Override
	public void postProcessAfterGenerate(List<Map> dataList,HSSFWorkbook workBook) {
		createBottom();
		createBorder();
	}
	
	/**
	 * 生成一个简易的表头
	 */
	public void createHead(){
		HSSFSheet sheet = getWorkBook().createSheet();
		HSSFRow row = sheet.createRow(0);
		HSSFCell cell = row.createCell(0);
		row.setHeight((short)500);
		cell.setCellValue("2015年XXX全年报表");
		for(int i=1;i<13;i++){
			row.createCell(i);
		}
		sheet.addMergedRegion(new CellRangeAddress(0,0,0,12));
		HSSFCellStyle style = getWorkBook().createCellStyle();
		HSSFFont font = getWorkBook().createFont();
		font.setBold(true);
		font.setFontHeightInPoints((short)16);
		style.setFont(font);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		cell.setCellStyle(style);
		
		HSSFRow row2 = sheet.createRow(1);
		HSSFCellStyle centerStyle = getWorkBook().createCellStyle();
		centerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		for(int i=0;i<13;i++){
			HSSFCell c = row2.createCell(i);
			if(i>0){
				c.setCellValue(i+"月");
				c.setCellStyle(centerStyle);
			}
		}
		ExportConfig cfg = getExportConfig();
		cfg.setRowStartIndex(cfg.getRowStartIndex()+2);
	}
	
	/**
	 * 添加边框
	 */
	public void createBorder(){
		HSSFSheet sheet = getWorkBook().getSheetAt(0);
		int rows = sheet.getLastRowNum();
		HSSFCellStyle style;
		for(int i=0;i<rows+1;i++){
			HSSFRow row = sheet.getRow(i);
			Iterator<Cell> iter = row.cellIterator();
			while(iter.hasNext()){
				Cell c = iter.next();
				style = row.getSheet().getWorkbook().createCellStyle();
				style.cloneStyleFrom(c.getCellStyle());
				style.setBorderTop((short)1);
				style.setBorderBottom((short)1);
				style.setBorderLeft((short)1);
				style.setBorderRight((short)1);
				c.setCellStyle(style);
			}
		}
	}
	
	/**
	 * 创建底部信息
	 */
	public void createBottom(){
		HSSFSheet sheet = getWorkBook().getSheetAt(0);
		int rows = sheet.getLastRowNum();
		HSSFRow row = sheet.createRow(rows+1);
		for(int i=1;i<13;i++){
			row.createCell(i);
		}
		Cell c = row.createCell(0);
		c.setCellValue("报告人:多啦a芊  报告日期:2015-12-17");
		HSSFCellStyle style = row.getSheet().getWorkbook().createCellStyle();
		style.cloneStyleFrom(c.getCellStyle());
		style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
		c.setCellStyle(style);
		sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(),row.getRowNum(),0,12));
	}
}

 

以下为调用端代码:

public class Client {
	public static void main(String[] args) throws IOException {
		test01();
		test02();
		test03();
	}
	
	/**
	 * 只导出数据Excel
	 */
	public static void test01() throws IOException{
		List<Map> l = getList();
		ExportGenerator generator = new ExportGenerator(l);
		HSSFWorkbook workBook = generator.getWorkBookInstance();
		FileOutputStream out = new FileOutputStream("D:\\excel1.xls");
		workBook.write(out);
	}
	
	/**
	 * 导出带表头、带边框的Excel
	 */
	public static void test02() throws IOException{
		List<Map> l = getList();
		ExportGenerator generator = new YearReportExportGenerator(l);
		HSSFWorkbook workBook = generator.getWorkBookInstance();
		FileOutputStream out = new FileOutputStream("D:\\excel2.xls");
		workBook.write(out);
	}
	
	/**
	 * 导出带表头、带边框和行样式的Excel
	 */
	public static void test03() throws IOException{
		List<Map> l = getList();
		CellValueProcessor cvp = new CellValueProcessor(){
			@Override
			public Object processCellValue(Object value, HSSFRow row,HSSFCell cell) {
				return value==null?"-":value;
			}
			@Override
			public CellStyle processCellStyle(Object value, HSSFRow row,HSSFCell cell) {
				HSSFCellStyle style = null;
				if(value instanceof Number){
					int v = (int)value;
					if(v<0){
						style = row.getSheet().getWorkbook().createCellStyle();
						style.cloneStyleFrom(cell.getCellStyle());
						style.setFillForegroundColor(HSSFColor.RED.index);
						style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
					}else if(v>100){
						style = row.getSheet().getWorkbook().createCellStyle();
						style.cloneStyleFrom(cell.getCellStyle());
						style.setFillForegroundColor(HSSFColor.BRIGHT_GREEN.index);
						style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
					}
				}else{
					style = row.getSheet().getWorkbook().createCellStyle();
					style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
				}
				return style;
			}
		};
		ExportConfig cfg = new ExportConfig();
		cfg.setCellValueProcessor(cvp);
		ExportGenerator generator = new YearReportExportGenerator(l,cfg);
		HSSFWorkbook workBook = generator.getWorkBookInstance();
		FileOutputStream out = new FileOutputStream("D:\\excel3.xls");
		workBook.write(out);
	}
	
	/**
	 * 获取假数据
	 */
	public static List<Map> getList(){
		List<Map> l = new ArrayList<Map>();
		Random r = new Random();
		Map m;
		for(int i=0;i<10;i++){
			m = new LinkedMap();
			m.put("name", "指标"+i);
			for(int j=0;j<12;j++){
				if(r.nextInt(20)<1){
					m.put(j, null);
				}else{
					m.put(j, r.nextInt(120)-10);	
				}
			}
			l.add(m);
		}
		return l;
	}
}

 

test01()生成结果:


 

test02()生成结果:


 

test03()生成结果:


 

 

  • 大小: 261.1 KB
  • 大小: 11.3 KB
  • 大小: 16.4 KB
  • 大小: 21.8 KB
  • 大小: 22.1 KB
分享到:
评论

相关推荐

    POI导出Excel文件

    以下是一个简化的示例,演示了如何使用POI导出Excel: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io....

    java使用POI导出 Excel工具类

    java使用POI导出 Excel+图片工具类 ,里面含有poi jar包,只调用接口即可直接保存Excel。使用的时候需先把数据封装,具体包装需根据实际导出数据进行处理。文件demo中只提供包装格式。

    POI导出Excel万级数据分页实现 解决内存溢出问题

    然而,当处理大量数据时,直接使用POI导出Excel可能会遇到内存溢出问题,因为POI将整个工作簿加载到内存中。本项目演示了如何通过分页方式解决这个问题,避免一次性加载过多数据导致的性能瓶颈。 首先,理解POI的...

    java poi导出Excel上传实例 可直接使用

    通过上述步骤,你就创建了一个基本的Java程序,能够使用Apache POI导出Excel文件。在项目中,你可以根据实际需求对这个示例进行扩展,比如从数据库读取数据、动态生成列名或自定义样式。这个"poi2"文件可能是包含此...

    POI导出Excel表格

    在Java编程领域,Apache POI是一个非常流行的库,它允许开发者读取、写入和修改Microsoft Office格式的文件,特别是Excel工作簿(.xls或.xlsx)。在这个“POI导出Excel表格”的实例中,我们将深入探讨如何利用Apache...

    java poi导出excel

    在Java中,如果你需要导出Excel文件,Java POI是一个非常实用的工具。下面将详细介绍如何使用Java POI来实现Excel的导出。 1. **引入依赖** 在Java项目中使用POI,首先需要在项目的构建文件(如Maven的pom.xml或...

    POI导出 POI导出 POI导出

    POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI导出POI...

    poi导出excel需要的jar

    Apache POI 是一个开源项目,专门用于处理Microsoft Office格式的文件,包括Excel。在Java环境中,使用POI库可以方便地读取、写入和修改Excel文档。"poi导出excel需要的jar"指的是在使用Apache POI进行Excel导出时,...

    POI的EXCEL导出,自动换行

    ### POI的EXCEL导出,自动换行 在日常工作中,经常需要处理大量的数据导入导出任务,尤其是在企业级应用开发中,Excel文件的处理成为了一项必不可少的能力。Apache POI项目提供了一系列用于读写Microsoft Office...

    poi导出excel生成下拉列表

    poi作为导出excel常用的工具,方便快捷。对于excel指定下拉列表的列,如何生成呢?本文提供如何生成下拉列表的excel列

    poi导出excel参考方法

    POI导出Excel参考方法 POI(Poor Obfuscation Implementation)是一个Java的API,用于操作Microsoft Office文档,包括Excel、Word、PowerPoint等。下面是POI导出Excel参考方法的相关知识点: 1. POI的基本概念 ...

    poi导出excel表格

    在IT行业中,Apache POI是一个广泛使用的Java库,它允许开发者读取、写入和修改Microsoft Office格式的文件,特别是Excel工作簿。本教程将详细讲解如何使用Apache POI在Web环境中导出Excel表格,避免生成不必要的...

    springboot+poi导出指定格式Excel模板

    springboot+poi导出指定格式Excel模板,完整项目,导出即用。springboot+poi导出指定格式Excel模板,完整项目,导出即用。springboot+poi导出指定格式Excel模板,完整项目,导出即用。springboot+poi导出指定格式...

    POI导出Excel工具类,自动设置标题 列名 文件名,可插入图片,合并单元格

    在这个场景中,我们关注的是如何使用POI来创建一个功能丰富的Excel导出工具类,它能够自动设置标题、列名、文件名,并且支持插入图片以及合并单元格。下面将详细介绍这些功能的实现。 首先,要创建一个Excel工作簿...

    Java实现POI导出Excel

    Java实现POI导出Excel是Java开发者常用的一种技术,用于生成和操作Microsoft Office Excel文件。在Java中,Apache POI库提供了对微软Office文档格式的支持,包括读取和写入Excel文件。这篇博客文章...

    poi导出excel2007

    ### 使用Apache POI导出Excel 2007并避免内存溢出问题 #### 背景介绍 在处理大量数据时,使用Java导出Excel文件可能会遇到内存溢出的问题,尤其是在导出Excel 2007(.xlsx格式)时更为常见。这是因为传统的`...

    poi导出excel通用类

    一个简单的“poi导出excel通用类”可能包含以下功能: 1. **初始化工作簿**:创建HSSFWorkbook对象,并根据需要创建多个Sheet。 2. **创建标题行**:在每个Sheet的第一个Row中添加列名,通常使用bold字体和居中...

    java导出excel POI jar包

    尽管在导出Excel时可能用不上,但这个库扩展了POI的功能范围。 `poi-ooxml-3.15-beta1.jar`是POI的OOXML支持库,主要处理.xlsx文件,与`poi-ooxml-schemas-3.15-beta1.jar`一起提供了对OOXML格式的支持。 `...

    java_poi实现excel导入导出

    要使用 Java POI 实现 Excel 导出,需要首先创建一个 HSSFWorkbook 或 XSSFWorkbook 对象,然后使用该对象创建一个工作表。下面是一个简单的示例: ```java import org.apache.poi.hssf.usermodel.HSSFWorkbook; ...

Global site tag (gtag.js) - Google Analytics