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

Posted yangzongzhuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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为根节点

 

 

以上是关于java poi导出树形结构到excel文件的主要内容,如果未能解决你的问题,请参考以下文章

java如何导出excel表格,如果用poi,java代码如何实现.,求代码!!!

java使用poi导出excel表格,可以导出到服务器,怎么才能让客户端进行选择导出的excel的路径呢

Java POI怎样判断导出的Excel数据是不是正确地保存到本地。考虑网络中断,客户不正确操作等因素。

关于java poi导出excel弹出下载框无法弹出的问题

急!!!java用poi导出excel文件,打开导出的文件时报错“文件错误,数据可能丢失”

poi导出Excel的奇怪问题