java poi导出树形结构到excel文件

maven pom.xml下载poi包

<dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.17</version>
        </dependency>
        <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.17</version>
        </dependency>
        <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>3.17</version>
        </dependency>

首先是实体类,也就是我们的数据集合

import java.util.List;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@TableName("test")
public class TestDomain {

	private String phone;
	
	private String parentPhone;
	
	@TableId
	private String id;
	
	private String parentId;

	@TableField(exist = false)
	private List<TestDomain> children;
	
	/**列数*/
	@TableField(exist = false)
	private Integer colNumber;
}

 再写个接口接收前端的导出请求,这里是使用的springboot 框架

@GetMapping("/test")
    public  void test(HttpServletResponse response, HttpServletRequest request) throws IOException {
        // 查询数据库
    	List<TestDomain> testDomains = testMapper.selectList(null);
        // 封装成树形结构
		TestTreeHandler testTreeHandler = new TestTreeHandler(testDomains);
		List<TestDomain> treeList = testTreeHandler.buildTree();
		
		//创建poi导出数据对象
		SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();

		//创建sheet页
		SXSSFSheet sheet = sxssfWorkbook.createSheet("sheet页名字");
	      
		//创建表头
		SXSSFRow headRow = sheet.createRow(0);
		//设置表头信息
		headRow.createCell(0).setCellValue("父号码");
		headRow.createCell(1).setCellValue("子号码");
		// 遍历上面数据库查到的数据
		for (TestDomain testDomain : treeList) {
        	//填充数据
        	SXSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);
  	        //序号
        	//看你实体类在进行填充
	        dataRow.createCell(0).setCellValue(testDomain.getParentPhone());
	        dataRow.createCell(1).setCellValue(testDomain.getPhone());
	        testDomain.setColNumber(1);
	        if(!CollectionUtils.isEmpty(testDomain.getChildren())) {
	        	child(testDomain.getChildren(), sheet,testDomain,dataRow);
	        }
	    	  
		}

	      // 下载导出
	      String filename = "导出excel表格名字";
	      // 设置头信息
	      response.setCharacterEncoding("UTF-8");
	      response.setContentType("application/vnd.ms-excel");
	      //一定要设置成xlsx格式
	      response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename + ".xlsx", "UTF-8"));
	      //创建一个输出流
	      ServletOutputStream outputStream = response.getOutputStream();
	      //写入数据
	      sxssfWorkbook.write(outputStream);

	      // 关闭
	      outputStream.close();
	      sxssfWorkbook.close();
    	
    	return null;
    }

递归子节点,往文件中逐级写入数据

/**
     * 
     * @Title: child   
     * @Description: 填充子节点数据 
     * @param childList 子节点数据
     * @param sheet 表格对象
     * @param parentDomain 父节点数据
     * @param parentRow  父节点行对象
     * void      
     * @throws   
     * @Author XX
     */
    public static void child(List<TestDomain> childList,SXSSFSheet sheet,TestDomain parentDomain,SXSSFRow parentRow) {
    	for (TestDomain testDomain : childList) {
    		// 获取sheet的最后一行
  	        SXSSFRow childRow = sheet.createRow(sheet.getLastRowNum()+1);
  	        // 合并单元格
  	        sheet.addMergedRegion(new CellRangeAddress(childRow.getRowNum(), childRow.getRowNum(), 0, parentDomain.getColNumber()));
  	        
  	        // 设置子节点表头 parentDomain.getColNumber()+1 和 parentDomain.getColNumber()+2 表示根据父节点最大列数往后挪移1-2列,如果是10个字段就往后挪移1-10列
  	        parentRow.createCell(parentDomain.getColNumber()+1).setCellValue("父号码");
  	        parentRow.createCell(parentDomain.getColNumber()+2).setCellValue("子号码");
  	        
  	        // 填充数据
  	        childRow.createCell(parentDomain.getColNumber()+1).setCellValue(testDomain.getParentPhone());
  	        childRow.createCell(parentDomain.getColNumber()+2).setCellValue(testDomain.getPhone());
  	        
  	        testDomain.setColNumber(parentDomain.getColNumber()+2);
  	        if(!CollectionUtils.isEmpty(testDomain.getChildren())) {
  	        	child(testDomain.getChildren(), sheet,testDomain,childRow);
  	        }
    	}
    }

将LIST装换成树形结构的处理类

import java.util.ArrayList;
import java.util.List;

import com.dadi01.scrm.service.mot.provider.domain.TestDomain;

public class TestTreeHandler {
	/**
	 * 	递归封装树形菜单
	 */
	List<TestDomain> nodes = new ArrayList<TestDomain>();

	public TestTreeHandler(List<TestDomain> nodes) {
	        super();
	        this.nodes = nodes;
    }

	/**
	 * 
	 * @Title: buildTree   
	 * @Description: 构建树形结构 
	 * @return      
	 * List<TestDomain>      
	 * @throws   
	 * @Author XX
	 */
	public List<TestDomain> buildTree() {
		List<TestDomain> TestDomains = new ArrayList<TestDomain>();
		List<TestDomain> rootNodes = getRootNodes();
		for (TestDomain rootNode : rootNodes) {
			buildChildNodes(rootNode);
			TestDomains.add(rootNode);
		}
		return TestDomains;
	}

	/**
	 * 
	 * @Title: buildChildNodes   
	 * @Description: 递归子节点 找出父节点下所有的层级 
	 * @param node 上级节点      
	 * void      
	 * @throws   
	 * @Author XX
	 */
	public void buildChildNodes(TestDomain node) {
		List<TestDomain> children = getChildNodes(node);
		if (!children.isEmpty()) {
			for (TestDomain child : children) {
				buildChildNodes(child);
			}
			node.setChildren(children);
		}
	}

	/**
	 * 
	 * @Title: getChildNodes   
	 * @Description:  获取父节点下所有的子节点 
	 * @param pnode 父节点
	 * @return      
	 * List<TestDomain>      
	 * @throws   
	 * @Author XX
	 */
	public List<TestDomain> getChildNodes(TestDomain pnode) {
		List<TestDomain> childNodes = new ArrayList<TestDomain>();
		for (TestDomain n : nodes) {
			if (pnode.getId().equals(n.getParentId())) {
				childNodes.add(n);
			}
		}
		return childNodes;
	}

	/**
	 * 
	 * @Title: rootNode   
	 * @Description: 判断是否为根节点 
	 * @param node 当前节点
	 * @return      
	 * boolean      
	 * @throws   
	 * @Author XX
	 */
	public boolean rootNode(TestDomain node) {
		return "0".equals(node.getParentId());
	}

	/**
	 * 
	 * @Title: getRootNodes   
	 * @Description: 获取集合中所有的根节点 
	 * @return      
	 * List<TestDomain>      
	 * @throws   
	 * @Author XX
	 */
	public List<TestDomain> getRootNodes() {
		List<TestDomain> rootNodes = new ArrayList<TestDomain>();
		for (TestDomain n : nodes) {
			if (rootNode(n)) {
				rootNodes.add(n);
			}
		}
		return rootNodes;
	}
}

浏览器敲地址访问就行了

http://localhost:8182/v1/excel/test

导出的文件内容 0为根节点

 

 

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值