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

学习实践

 

目标:

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()生成结果:


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值