Java 树形结构数据生成导出excel文件

article/2025/8/21 23:15:50
  1. 效果

  2. 用法

    String jsonStr = "{\"name\":\"aaa\",\"children\":[{\"name\":\"bbb\",\"children\":[{\"name\":\"eee\"},{\"name\":\"fff\",\"children\":[{\"name\":\"iii\"},{\"name\":\"jjj\",\"children\":[{\"name\":\"qqq\"},{\"name\":\"ttt\"}]}]},{\"name\":\"www\"}]},{\"name\":\"ccc\",\"children\":[{\"name\":\"ggg\"},{\"name\":\"hhh\",\"children\":[{\"name\":\"kkk\",\"children\":[{\"name\":\"ttt\"},{\"name\":\"mmm\"}]},{\"name\":\"uuu\"}]},{\"name\":\"ooo\"}]},{\"name\":\"ddd\",\"children\":[{\"name\":\"ggg\"},{\"name\":\"hhh\",\"children\":[{\"name\":\"kkk\"},{\"name\":\"uuu\"}]}]}]}";
    Map tree = JSONObject.parseObject(jsonStr, Map.class);
    tree2Excel(tree, "E:\\" + System.currentTimeMillis() + ".xls", "name", "children");

  3. 源码
     

    package pers.xxx.demo.tree2excel;import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.Closeable;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.List;
    import java.util.Map;/*** 树形结构数据导出excel工具* <p>* Created by lzy on 2021/2/24 14:09*/
    @SuppressWarnings("ALL")
    public class Tree2ExcelUtil {/*** 树形结构数据生成excel文件** @param tree     树形数据* @param filePath 文件路径* @return*/public static boolean tree2Excel(Map tree, String filePath) {return tree2Excel(tree, filePath, null, null);}/*** 树形结构数据生成excel文件** @param tree         树形数据* @param filePath     文件路径* @param lableName    标签Key名称* @param childrenName 子节点Key名称* @return*/public static boolean tree2Excel(Map tree, String filePath, String lableName, String childrenName) {if (isBlank(filePath)) {System.err.println("文件名称不能为空");return false;}try {doSame(tree, lableName, childrenName);createExcel(filePath, tree);return true;} catch (IOException e) {e.printStackTrace();}return false;}/*** 树形结构数据生成Workbook对象** @param tree    树形数据* @param fileSuf 文件后缀,xls/xlsx* @return*/public static Workbook tree2Worbook(Map tree, String fileSuf) {return tree2Worbook(tree, fileSuf, null, null);}/*** 树形结构数据生成Workbook对象** @param tree         树形数据* @param fileSuf      文件后缀,xls/xlsx* @param lableName    标签Key名称* @param childrenName 子节点Key名称* @return*/public static Workbook tree2Worbook(Map tree, String fileSuf, String lableName, String childrenName) {if (isBlank(fileSuf)) {System.err.println("必须指定文件后缀");return null;}try {doSame(tree, lableName, childrenName);return procesData(tree, fileSuf);} catch (Exception e) {e.printStackTrace();}return null;}//具体实现/*** 标识最大列*/private static int maxCol = 0;private static String lableName = "lable";private static String childrenName = "children";private static final String COL = "col";private static final String ROW = "row";private static final String ROW_OFT = "rowOft";private static final String ROW_SIZE = "rowSize";private static void doSame(Map tree, String lableName, String childrenName) {if (!isBlank(lableName)) {Tree2ExcelUtil.lableName = lableName;}if (!isBlank(childrenName)) {Tree2ExcelUtil.childrenName = childrenName;}coreAlgoCol(tree, 1);coreAlgoRow(tree);}/*** 主要算法,计算列的坐标,计算每个节点所占行** @param tree  数据* @param col   递增的列* @param trees 把高级别向下传递计算递增的行高*/private static void coreAlgoCol(Map tree, int col, Map... trees) {tree.put(COL, col);Object childrenObj = tree.get(childrenName);if (childrenObj != null) {List<Map> children = (List<Map>) childrenObj;if (children.size() > 0) {int size = children.size() * 2 - 1;tree.put(ROW_SIZE, size);int len = trees != null ? trees.length + 1 : 1;Map[] arrData = new Map[len];if (trees != null && trees.length > 0) {for (int i = 0; i < trees.length; i++) {Map tree1 = trees[i];tree1.put(ROW_SIZE, toInt(tree1.get(ROW_SIZE), 1) + size - 1);arrData[i] = tree1;}}arrData[len - 1] = tree;for (Map tree1 : children) {int newCol = col + 1;if (newCol > maxCol) {maxCol = newCol;}coreAlgoCol(tree1, newCol, arrData);}}}}/*** 主要算法,计算行的坐标** @param tree*/private static void coreAlgoRow(Map tree) {if (toInt(tree.get(ROW)) == 0) {tree.put(ROW, Math.round(toInt(tree.get(ROW_SIZE), 1) / 2.0f));}Object childrenObj = tree.get(childrenName);if (childrenObj != null) {List<Map> children = (List<Map>) childrenObj;if (children.size() > 0) {int tempOft = toInt(tree.get(ROW_OFT));for (Map tree1 : children) {int rowSize = toInt(tree1.get(ROW_SIZE), 1);tree1.put(ROW_OFT, tempOft);tree1.put(ROW, tempOft + Math.round(rowSize / 2.0f));tempOft += rowSize + 1;coreAlgoRow(tree1);}}}}/*** 创建excel文件** @param filePath 文件路径,具体路径到文件名* @param tree     数据* @throws IOException*/private static void createExcel(String filePath, Map tree) throws IOException {File file = new File(filePath);boolean bfile = file.createNewFile();// 复制模板到新文件if (bfile) {Workbook wk = procesData(tree, filePath);if (wk != null) {FileOutputStream fos = null;try {fos = new FileOutputStream(file);wk.write(fos);fos.flush();} finally {closeStream(fos);wk.close();}}}}/*** 处理excel数据** @param tree 数据* @return 工作表对象*/private static Workbook procesData(Map tree, String fileName) {Workbook wk = null;if (fileName.endsWith("xls")) {wk = new HSSFWorkbook();}if (fileName.endsWith("xlsx")) {wk = new XSSFWorkbook();}if (wk == null) {System.err.println("文件名称不正确");return null;}//创建一个sheet页Sheet sheet = wk.createSheet("Sheet1");int colSize = maxCol * 2 + 2;int rowSize = toInt(tree.get(ROW_SIZE), 1);for (int i = 0; i <= rowSize; i++) {Row row = sheet.createRow(i);for (int j = 0; j <= colSize; j++) {row.createCell(j);}}//配置单元格背景色CellStyle style1 = wk.createCellStyle();style1.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());style1.setFillPattern(FillPatternType.SOLID_FOREGROUND);CellStyle style2 = wk.createCellStyle();style2.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());style2.setFillPattern(FillPatternType.SOLID_FOREGROUND);dealCell(sheet, tree, style1, style2);return wk;}/*** 根据计算好的坐标填充每一个单元格** @param sheet  #* @param tree   数据* @param style1 单元格格式* @param style2 单元格格式*/private static void dealCell(Sheet sheet, Map tree, CellStyle style1, CellStyle style2) {Row row = sheet.getRow(toInt(tree.get(ROW)));int oftCol = (toInt(tree.get(COL)) - 1) * 2 + 1;Cell cell = row.getCell(oftCol);cell.setCellStyle(style1);cell.setCellValue(String.valueOf(tree.get(lableName)));sheet.setColumnWidth(oftCol, 256 * 20);Object childrenObj = tree.get(childrenName);if (childrenObj != null) {List<Map> children = (List<Map>) childrenObj;if (children.size() > 0) {int size = children.size();int startRow = toInt(children.get(0).get(ROW));int endRow = toInt(children.get(size - 1).get(ROW));int col = oftCol + 1;sheet.setColumnWidth(col, 256);for (; startRow <= endRow; startRow++) {sheet.getRow(startRow).getCell(col).setCellStyle(style2);}for (Map child : children) {dealCell(sheet, child, style1, style2);}}}}private static int toInt(Object val) {return toInt(val, 0);}private static int toInt(Object val, Integer defVal) {try {return Integer.parseInt(String.valueOf(val));} catch (NumberFormatException ignored) {}return defVal;}private static boolean isBlank(String str) {return str == null || str.trim().length() == 0;}/*** 关闭流** @param closeables 不定长数组 流对象*/public static void closeStream(Closeable... closeables) {for (Closeable closeable : closeables) {if (closeable != null) {try {closeable.close();} catch (IOException e) {e.printStackTrace();}}}}}


http://chatgpt.dhexx.cn/article/2m8C5KyB.shtml

相关文章

python 根据树型结构生成指定格式的excel数据

数据 tree {a: {a1: [(a1a, 1)],a2: [(a2a, 1),(a2b, 2),]},b: {b1: [(b1b, 1)],b2: [(b2b, 1)]} }excel 数据格式 代码实现 import xlrd from xlutils.copy import copyold_excel xlrd.open_workbook(1.xls) new_excel copy(old_excel) ws new_excel.get_sheet(0)def wr…

人工智能-高等数学之导数篇

高等数学之导数篇 线性代数的学习基本就先告一个段落了&#xff0c;接着学最重要的微积分&#xff0c;高等数学里的重中之重&#xff0c;也是近代科学的发展利器&#xff0c;微积分主要包括包括极限、微分学、积分学及其应用&#xff0c;而微分学包括求导数的运算&#xff0c;…

机器学习之数学基础 一 .导数

简单的说,导数是曲线的斜率,是曲线变化快慢的反应. 2阶导数是斜率变化快慢的反应,反应曲线的凸凹性 例如:加速度的方向总是指向轨迹曲线凹的一侧. 导数(Derivative)是微积分学中重要的基础概念.一个函数在某一点的导数描述了这个函数在这一点附近的变化率.导数的本质是通过极…

【数值优化之范数与导数】

本文参考书籍《最优化计算方法》 这一部分会介绍一些最优化需要用到的基本数学概念。 目录 1 范数 1.1 向量范数 1.2 矩阵范数 1.3 矩阵内积 2 导数 2.1 梯度与海瑟矩阵 2.2 矩阵变量函数的导数 1 范数 1.1 向量范数 范数相当于是从向量空间到实数域的映射&#xff…

微积分——什么是导数

目录 1. “导数(derivative)”名称的由来 1.1 “derivative”的词源 1.2 “derivative”的数学意义来源 1.3 “derivative”中文翻译为“导数” 2. “导数(derivative)”的数学意义 1. “导数(derivative)”名称的由来 1.1 “derivative”的词源 作为名词&#xff0c;始于…

一阶导数

本文引用与百度百科。 简介 导数&#xff08;英语&#xff1a;Derivative&#xff09;是微积分学中重要的基础概念。一个函数在某一点的导数描述了这个函数在这一点附近的变化率。导数的本质是通过极限的概念对函数进行局部的线性逼近。当函数 f 的自变量在一点 x0 上产生一个…

AI笔记: 数学基础之方向导数的计算和梯度

方向导数 定理 若函数f(x,y,z)在点P(x,y,z)处可微&#xff0c;沿任意方向l的方向导数 ∂ f ∂ l ∂ f ∂ x c o s α ∂ f ∂ y c o s β ∂ f ∂ z c o s γ \frac{\partial f}{\partial l} \frac{\partial f}{\partial x} cos \alpha \frac{\partial f}{\partial y} c…

图像处理之_导数微分

1. 一阶导数应用&#xff1a;图像的梯度 1) 用途: 在图像处理中, 常用梯度求取图像的边缘, 这是一个很基础的应用. 下图为在OpenCV中使用cvSobel()函数的具体效果. 四张图分别为: 原图, 在x方向上的梯度, y方向上的梯度, xy方向上的梯度. 2) 二元函数 这里我们只讨论二元…

如何理解微分、差分、导数

先说差分和微分 自变量x的差分就是微分 即&#xff1a; Δxdx 因变量y的差分是函数y的变化量 即 Δyy(xΔx)-y(x) 因变量y的微分是指函数图像在某一点处的切线在横坐标取得增量Δx以后&#xff0c;纵坐标取得的增量dy。 dyf(x)dx 总结&#xff1a; 微分是差分的线…

神经网络学习之导数

在神经网络中&#xff0c;有一个常用的激活函数sigmoid函数&#xff0c;这个函数在高等数学中应该是有的&#xff0c;只是当时没有理会。函数图像如下&#xff0c;本文主要主要梳理下相应的数学知识&#xff0c;具体的应用在后续的文章中会涉及。 本文涉及到数学公式&#xff…

Matlat计算符号导数

MATLAB提供用于计算符号导数的diff命令。 如下&#xff1b;指定t为变量&#xff0c;输入一个函数表达式&#xff0c;使用diff(f)求其导数&#xff1b; 再计算一个&#xff1b; 输入一些常用函数&#xff0c;查看其导数&#xff1b;例如sin(x)的导数是cos(x)&#xff0c;cos(x…

R语言数值导数

文章目录 3 数值导数 3 数值导数 根据导数的定义&#xff0c;当函数的定义域不连续时&#xff0c;其不连续处显然是不存在导数的&#xff0c;但图形可以“欺骗”我们的眼睛。 > x seq(-1,1,0.1) > y sin(x) > y1 cos(x) > xEnd x0.1 > yEnd yy1*0.1 >…

MATLAB之怎样利用MATLAB中值差分法求一阶二阶导数

** MATLAB初学之怎么利用中值差分法求一阶二阶导数 ** 我们最近在学习MATLAB。在MATLAB中怎么求导数? MATLAB中有专门求导的函数 针对f(x)类的函数: diff(f,x) :求f关于x的导数 diff(diff(f,x),x):求f二阶导数 针对f(x,y)类的函数求偏导: diff(f,x) :求f关于x…

C语言之自然对数ln(x)的导数

设计要求&#xff1a;求自然对数ln(x)的导数&#xff0c;输入双精度实数x>1&#xff0c;输出自然实数ln(x)的导数&#xff08;精确到小数点后2位有效数&#xff0c;小数点后第2位四舍五入所得&#xff09;。 详细设计&#xff1a; lnx的导数的设计主要是利用到高等数学的导…

python实现之导数

导数&#xff08;Derivative&#xff09;&#xff0c;也叫导函数值。又名微商&#xff0c;是微积分中的重要基础概念。当函数yf&#xff08;x&#xff09;的自变量x在一点x0上产生一个增量Δx时&#xff0c;函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存…

python实现之一阶二阶导数

函数的和、差、积、商的求导法则 uu(x),vv(x) (uv)uv (u-v)u-v (Cu)Cu (uv)uvuv (u/v)(uv-uv)/v^2 复合函数求导法则 yf(u)&#xff0c;uφ(v) 复合函数yf[φ(v)]的导数为 dy/dxdy/du*du/dxf(u)*φ(v) (u-vz)u-vz&#xff0c;且(Cu)Cu exam1: y 2*x*^3 -5*x^23*x-7 y6*x^2-10x3…

《高等数学》 总结 导数、微分、不定积分

必须掌握各个概念的定义。从定义中,深入的理解概念,以及发掘概念之间的相互联系。 导数&微分 微积分有两种定义: 1、古典微积分 这是一种直观、便于理解的定义。首先定义微分是微小变化量。比如函数y=f(x)中dx是x的微小变化量,那么dy就是dx对应的y的微小变化。导数…

电脑连不上WiFi,右下角出现红叉怎么解决

我的电脑经常出现这个问题&#xff0c;后来解决得多了就知道方法了&#xff0c;是我的电脑无线网卡驱动的问题&#xff0c;解决办法&#xff1a; 1.电脑桌面单击此电脑&#xff0c;右键选择属性 2.选择网络适配器&#xff0c;一般出现问题就是因为网络适配器列表里面的一些东…

windows10 右下角网络连接栏显示一个电脑加上一个红叉,已解决

如下图所示&#xff1a; 解决办法&#xff1a; 找到命令行&#xff08;黑窗口&#xff09;管理员身份打开&#xff0c;一定要管理员身份&#xff0c;win10权限比较高输入 netsh winsock reset重启电脑即可