当前位置: 代码迷 >> 报表 >> poi导出excel表格(备忘)
  详细解决方案

poi导出excel表格(备忘)

热度:409   发布时间:2016-05-05 07:32:03.0
poi导出excel报表(备忘)

???? poi导出excel这种很多人写,我写的也是导出excel,代码网上一搜一大把,我也不上传了,简单的讲下导出excel的思路。本文是写给自己备忘的,可以不用看。

??? 前提条件:

??? 报表是固定的,数据只统计最近的15天,数据量很小。

?

??? (一)创建报表模板

???? 因为报表格式是固定的,所以可以采用模版导出的方式,可以手动创建模版,我第一次做的时候只给了我个截图,作为程序员能用代码就用代码,所以写了个简单的类来创建报表模版。

??? 用于报表大部分是2列的,有合并表头的情况存在,自己定义的表头数据格式为(只支持表头<=2行的):

???

测试调查公司#2#1$

?? 格式:表头标题名#跨2行#跨1列$

?

??? 然后自己解析,创建表头,这很容易就实现了,效果如下:

???

?

?

?? (二)调整报表模版

??? 使用代码由于要兼容大部分报表情况,有些列宽度设置的不是很合理,需要手动调整,看到这里,请不要吐槽说我的方法又是个手动完成的,没全部用代码,谢谢。

?

??? 调整后的样式为:

???

?

? (三)插入数据

?? 这部分对于大部分程序员来说太容易了,给个JavaBean使用反射一下就OK了,So easy!

?? 我的报表要求是对于某些连续列在数据相同情况下要求合并,这就有问题了。

?? 问题1:表头下的数据要和表头列一致,最下面的表头如果有合并n列为1列的情况发生,数据也要这样做

??

?? 问题2:相同列在跨行合并时候可能列有合并n列为1列的情况。

?

?? 解决方法:

?? 问题1:得到报表excel报表某个sheet页下所有的合并区域,在写数据时候注意数据和最下面的表头一致,该合并的合并就OK了。

????

/**	 * 得到sheet页中所有的合并区域	 * @param sheet	 * @return	 */	public Map<String, Integer> getSheetMergeRegion(XSSFSheet sheet) {		int num = sheet.getNumMergedRegions();		Map<String, Integer> mergMap = new TreeMap<String, Integer>();		CellRangeAddress cellR = null;		String str = null;		for (int i = 0; i < num; i++) {			cellR = sheet.getMergedRegion(i);			// 最后一行+第一列,最后一列			str = cellR.getLastRow() + "#" + cellR.getFirstColumn();			mergMap.put(str, cellR.getLastColumn());		}		return mergMap;	}

?

?? 问题2:对于已经有合并n列为1列的情况,由于要合并相同列下n行为1列,先把报表excel某个sheet页下要合并的列拆分为n列单元格,在合并单元格。

??

?? 得到所有合并区域的id,方便删除,有删除操作时候每次必须取最新的合并区域信息,否则删除时候报错。

public Map<String, Integer> getSheetMergeRegionIndex(XSSFSheet sheet) {		int num = sheet.getNumMergedRegions();		Map<String, Integer> mergMap = new TreeMap<String, Integer>();		CellRangeAddress cellR = null;		String str = null;		for (int i = 0; i < num; i++) {			cellR = sheet.getMergedRegion(i);			// 最后一行+第一列,id			str = cellR.getLastRow() + "#" + cellR.getFirstColumn();			mergMap.put(str, i);		}		return mergMap;	}

???对于已合并过的单元格,再合并是没有效果的,所以需要先把合并过的单元格拆分在一起合并。

// 合并单元格//拆分 再合并 注意复制单元格样式	public void splitAndMergeCells(XSSFSheet sheet, int startRow, int endRow,			int startCell, int endCell) {		XSSFCellStyle tmpCellStyle = null;		XSSFRow tmpRow = sheet.getRow(startRow);		XSSFCell tmpCell = tmpRow.getCell(startCell);		String tmpValue = tmpCell.getStringCellValue();		tmpCellStyle = tmpCell.getCellStyle();		Map<String, Integer> indexMap=new HashMap<String, Integer>();		String tmpKey = null;		String tmpKey2 = null;		for (int r = startRow; r <= endRow; r++) {			//用于有删除合并单元格,每次取最新的单元格信息			indexMap = getSheetMergeRegionIndex(sheet);			for (Map.Entry<String, Integer> map : indexMap.entrySet()) {				tmpKey = map.getKey();				tmpKey2 = new String(r + "#" + startCell);				if (tmpKey.equals(tmpKey2)) {					//删除合并的单元格					sheet.removeMergedRegion(map.getValue());				}			}			indexMap = null;		}		tmpRow = sheet.getRow(startRow);		tmpCell = tmpRow.getCell(startCell);		tmpCell.setCellValue(tmpValue);		tmpCell.setCellStyle(tmpCellStyle);		sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startCell,				endCell));	}

?

?? 报表导出效果如下:

?

?

???

???? 本文系原创,转载请注明出处,估计也没人转载,谢谢。

??? 全文完。

?

  相关解决方案