Java实现生成Excel树形表头完整代码示例

 更新时间:2017年12月07日 14:15:40   作者:zhangzeyuaaa  
这篇文章主要介绍了Java实现生成Excel树形表头完整代码示例,具有一定借鉴价值,需要的朋友可以参考下。

本文主要分享了Java实现生成Excel树形表头完整代码示例,没有什么好解释的,直接看看代码过程。

源数据格式:

String[] targetNames = { 
        "指标名称",  
        "单位",  
        "xx_yy1",  
        "xx_yy2_zz1",  
        "xx_yy2_zz2", 
        "2017年5月_主营业务收入_累计", "2017年5月_主营业务收入_同比",  
        "2017年5月_主营业务收入_本月", "2017年5月_主营业务收入_环比",  
        "2017年5月_利润_累计", "2017年5月_利润_同比", "2017年5月_利润_本月", "2017年5月_利润_环比", 
        "2017年6月_主营业务收入_累计", "2017年6月_主营业务收入_同比",  
        "2017年6月_主营业务收入_本月", "2017年6月_主营业务收入_环比",  
        "2017年6月_利润_累计", "2017年6月_利润_同比", "2017年6月_利润_本月", "2017年6月_利润_环比" 
      };

生成如下Excel:

第一行不属于树形表头。

代码

SplitCell:

package com.zzj.excel;
public class SplitCell {
	private String key;
	private String parentKey;
	private String value;
	private int columnIndex;
	private int rowIndex;
	public SplitCell() {
	}
	public SplitCell(String key, String value) {
		this.key = key;
		this.value = value;
	}
	public SplitCell(String key, String parentKey, String value,  
	      int columnIndex, int rowIndex) {
		this.key = key;
		this.parentKey = parentKey;
		this.value = value;
		this.columnIndex = columnIndex;
		this.rowIndex = rowIndex;
	}
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getParentKey() {
		return parentKey;
	}
	public void setParentKey(String parentKey) {
		this.parentKey = parentKey;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public int getColumnIndex() {
		return columnIndex;
	}
	public void setColumnIndex(int columnIndex) {
		this.columnIndex = columnIndex;
	}
	public int getRowIndex() {
		return rowIndex;
	}
	public void setRowIndex(int rowIndex) {
		this.rowIndex = rowIndex;
	}
	@Override 
	  public String toString() {
		return "CellContent [key=" + key + ", parentKey=" + parentKey + ", value=" + value + ", columnIndex=" 
		        + columnIndex + ", rowIndex=" + rowIndex + "]";
	}
}

MergedCell:

package com.zzj.excel;
public class MergedCell {
	private String key;
	private String parentKey;
	private String value;
	private int startC;
	private int endC;
	private int startR;
	private int endR;
	private Boolean leaf = true;
	// 默认叶子节点 
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getParentKey() {
		return parentKey;
	}
	public void setParentKey(String parentKey) {
		this.parentKey = parentKey;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public int getStartC() {
		return startC;
	}
	public void setStartC(int startC) {
		this.startC = startC;
	}
	public int getEndC() {
		return endC;
	}
	public void setEndC(int endC) {
		this.endC = endC;
	}
	/** 
   * 单元格合并结束列索引自增 
   */
	public void incEndC(){
		this.endC++;
	}
	public int getStartR() {
		return startR;
	}
	public void setStartR(int startR) {
		this.startR = startR;
	}
	public int getEndR() {
		return endR;
	}
	public void setEndR(int endR) {
		this.endR = endR;
	}
	public Boolean isLeaf() {
		return leaf;
	}
	public void setLeaf(Boolean leaf) {
		this.leaf = leaf;
	}
	@Override 
	  public String toString() {
		return "CellInfo [key=" + key + ", parentKey=" + parentKey + ", value=" + value + ", startC=" + startC 
		        + ", endC=" + endC + ", startR=" + startR + ", endR=" + endR + ", leaf=" + leaf + "]";
	}
}

CellTransformer:

package com.zzj.excel;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class CellTransformer {
	private final List<SplitCell> cellContents;
	private final int firstRowIndex;
	private final int rowSize;
	private Map<String, MergedCell> cellInfoMap = new LinkedHashMap<String, MergedCell>();
	public CellTransformer(List<SplitCell> cellContents, int firstRowIndex, int rowSize) {
		this.cellContents = cellContents;
		this.firstRowIndex = firstRowIndex;
		this.rowSize = rowSize;
	}
	public Map<String, MergedCell> transform(){
		cellInfoMap.clear();
		for (SplitCell cellContent : cellContents) {
			MergedCell cellInfo = cellInfoMap.get(cellContent.getKey());
			if (cellInfo == null) {
				cellInfo = convertToCellInfo(cellContent);
				cellInfoMap.put(cellInfo.getKey(), cellInfo);
			} else {
				/* 单元格出现多少次,则该单元格就合并多少列 */
				cellInfo.incEndC();
				// 列结束索引自增(用于列合并) 
				cellInfo.setLeaf(false);
				// 只要重复出现,则为非叶子节点
			}
		}
		// 行合并 
		for (MergedCell cellInfo : cellInfoMap.values()) {
			if (cellInfo.isLeaf()) {
				// 如果为叶子节点,则一定合并到最后一行 
				cellInfo.setEndR(firstRowIndex + rowSize - 1);
			}
		}
		return cellInfoMap;
	}
	private MergedCell convertToCellInfo(SplitCell cellContent){
		MergedCell cellInfo = new MergedCell();
		cellInfo.setKey(cellContent.getKey());
		cellInfo.setParentKey(cellContent.getParentKey());
		cellInfo.setValue(cellContent.getValue());
		cellInfo.setStartC(cellContent.getColumnIndex());
		// 结束索引默认为开始索引 
		cellInfo.setEndC(cellContent.getColumnIndex());
		cellInfo.setStartR(cellContent.getRowIndex());
		// 结束索引默认为开始索引 
		cellInfo.setEndR(cellContent.getRowIndex());
		return cellInfo;
	}
}

测试

package com.zzj.excel;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import jxl.Workbook;
import jxl.format.CellFormat;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
public class Main {
	private static final String SEPARATOR = "_";
	public static void main(String[] args) throws Exception {
		String[] targetNames = { 
		        "指标名称",  
		        "单位",  
		        "xx_yy1",  
		        "xx_yy2_zz1",  
		        "xx_yy2_zz2", 
		        "2017年5月_主营业务收入_累计", "2017年5月_主营业务收入_同比",  
		        "2017年5月_主营业务收入_本月", "2017年5月_主营业务收入_环比",  
		        "2017年5月_利润_累计", "2017年5月_利润_同比", "2017年5月_利润_本月", "2017年5月_利润_环比", 
		        "2017年6月_主营业务收入_累计", "2017年6月_主营业务收入_同比",  
		        "2017年6月_主营业务收入_本月", "2017年6月_主营业务收入_环比",  
		        "2017年6月_利润_累计", "2017年6月_利润_同比", "2017年6月_利润_本月", "2017年6月_利润_环比" 
		      };
		// 设第一行不属于树形表头 
		String[] extraNames = new String[targetNames.length];
		for (int i = 0; i < extraNames.length; i++) {
			extraNames[i] = "extra" + i;
		}
		final int firstTreeRowIndex = 1;
		int rowSize = getRowSize(targetNames);
		List<SplitCell> cellContents = new ArrayList<>();
		for (int i = 0; i < targetNames.length; i++) {
			String[] values = targetNames[i].split(SEPARATOR);
			for (int j = 0; j < values.length; j++) {
				String value = values[j];
				String key = getKey(values, j);
				String parentKey = getParentKey(values, j);
				SplitCell cellContent = new SplitCell(key, parentKey, value,  
				            i, j + firstTreeRowIndex);
				cellContents.add(cellContent);
			}
		}
		WritableWorkbook workbook = Workbook.createWorkbook(new File("F:\\template.xls"));
		CellFormat cellFormat = getCellFormat();
		WritableSheet sheet = workbook.createSheet("template", 0);
		// 第一行 
		for (int i = 0; i < extraNames.length; i++) {
			Label label = new Label(i, 0, extraNames[i], cellFormat);
			sheet.addCell(label);
		}
		// 树形表头 
		CellTransformer cellInfoManager = new CellTransformer(cellContents, firstTreeRowIndex, rowSize);
		Map<String, MergedCell> map = cellInfoManager.transform();
		for (MergedCell cellInfo : map.values()) {
			Label label = new Label(cellInfo.getStartC(),  
			          cellInfo.getStartR(), cellInfo.getValue(), cellFormat);
			if (cellInfo.getStartC() != cellInfo.getEndC() 
			          || cellInfo.getStartR() != cellInfo.getEndR()) {
				sheet.mergeCells(cellInfo.getStartC(), cellInfo.getStartR(),  
				            cellInfo.getEndC(), cellInfo.getEndR());
			}
			sheet.addCell(label);
		}
		workbook.write();
		workbook.close();
		System.out.println("导出成功!");
	}
	private static CellFormat getCellFormat() throws Exception{
		WritableFont font = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD);
		WritableCellFormat cellFormat = new WritableCellFormat();
		cellFormat.setFont(font);
		cellFormat.setAlignment(jxl.format.Alignment.CENTRE);
		cellFormat.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
		cellFormat.setWrap(false);
		return cellFormat;
	}
	private static int getRowSize(String[] targetNames) {
		int rowSize = 0;
		for (String t : targetNames) {
			rowSize = Math.max(rowSize, t.split(SEPARATOR).length);
		}
		return rowSize;
	}
	private static String getKey(String[] values, int index){
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < (index + 1); i++) {
			sb.append(values[i] + SEPARATOR);
		}
		sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}
	private static String getParentKey(String[] values, int index){
		if (index == 0) {
			return null;
		}
		return getKey(values, index - 1);
	}
}

总结

以上就是本文关于Java实现生成Excel树形表头完整代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • 在SpringBoot: SpringBoot里面创建导出Excel的接口教程

    在SpringBoot: SpringBoot里面创建导出Excel的接口教程

    这篇文章主要介绍了在SpringBoot: SpringBoot里面创建导出Excel的接口教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Java SpringBoot的相关知识点详解

    Java SpringBoot的相关知识点详解

    这篇文章主要介绍了SpringBoot的相关知识点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-10-10
  • SpringCloud使用Feign实现远程调用流程详细介绍

    SpringCloud使用Feign实现远程调用流程详细介绍

    OpenFeign源于Netflix的Feign,是http通信的客户端。屏蔽了网络通信的细节,直接面向接口的方式开发,让开发者感知不到网络通信细节。所有远程调用,都像调用本地方法一样完成
    2023-02-02
  • Spring IOC基于注解启动示例详析

    Spring IOC基于注解启动示例详析

    这篇文章主要给大家介绍了Spring IOC基于注解启动的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • SpringBoot使用SSE进行实时通知前端的实现代码

    SpringBoot使用SSE进行实时通知前端的实现代码

    这篇文章主要介绍了SpringBoot使用SSE进行实时通知前端,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • java判断回文数示例分享

    java判断回文数示例分享

    这篇文章主要介绍了java判断回文数示例,需要的朋友可以参考下
    2014-03-03
  • Jersey实现Restful服务(实例讲解)

    Jersey实现Restful服务(实例讲解)

    下面小编就为大家带来一篇Jersey实现Restful服务(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Springboot 配置RabbitMQ文档的方法步骤

    Springboot 配置RabbitMQ文档的方法步骤

    这篇文章主要介绍了Springboot 配置RabbitMQ文档的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • 使用itextpdf操作pdf的实例讲解

    使用itextpdf操作pdf的实例讲解

    下面小编就为大家分享一篇使用itextpdf操作pdf的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • java中的按位与(&)用法说明

    java中的按位与(&)用法说明

    这篇文章主要介绍了java中的按位与(&)用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08

最新评论