当前位置: 首页 > news >正文

excel导出多重表头utils_java excel复杂表头和复杂数据导出

懒得写废话了。。。

package com.ruoyi.common.utils.poi;

import com.ruoyi.framework.config.RuoYiConfig;

import com.ruoyi.framework.web.domain.AjaxResult;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.apache.poi.ss.usermodel.Workbook;

import org.apache.poi.ss.util.CellRangeAddress;

import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.Comparator;

import java.util.List;

import java.util.UUID;

public class DocumentUtil {

private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);

private String sheetName;

private Workbook wb;

private Sheet sheet;

private List list;

private List columns;

private List fields;

private int maxDepth;

public Class clazz;

public DocumentUtil(Class clazz)

{

this.clazz = clazz;

}

public void init(List list, List columns, String sheetName)

{

if (list == null)

{

list = new ArrayList();

}

this.list = list;

this.fields = new ArrayList<>();

this.columns = columns;

this.sheetName = sheetName;

this.wb = new SXSSFWorkbook(500);

}

public AjaxResult exportExcel(List list, List columns, String sheetName)

{

this.init(list, columns, sheetName);

return exportExcel();

}

private AjaxResult exportExcel() {

OutputStream out = null;

try {

sheet = wb.createSheet(sheetName);

generateHeader(this.columns);

this.fields.sort((a, b) -> b.getFirstCol() - a.getFirstCol());

generateData(this.list,maxDepth + 1);

String filename = encodingFilename(sheetName);

out = new FileOutputStream(getAbsoluteFile(filename));

wb.write(out);

return AjaxResult.success(filename);

}

catch (Exception ex) {

System.out.print(ex.getMessage());

}

return null;

}

public String encodingFilename(String filename)

{

filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx";

return filename;

}

public String getAbsoluteFile(String filename)

{

String downloadPath = RuoYiConfig.getDownloadPath() + filename;

File desc = new File(downloadPath);

if (!desc.getParentFile().exists())

{

desc.getParentFile().mkdirs();

}

return downloadPath;

}

private void generateHeader(List columns) {

maxDepth = getMaxDepth(this.columns, 0);

generateHeader(columns, null, maxDepth);

}

private void generateHeader(List columns, Column parent, int maxDepth) {

int colIndex = 0, rowIndex = 0;

if (parent != null) {

colIndex = parent.getFirstCol();

rowIndex = parent.getLastRow() + 1;

}

for (Column column : columns) {

Row row = sheet.getRow(rowIndex);

if (row == null) {

row = sheet.createRow(rowIndex);

}

column.setFirstRow(rowIndex);

column.setLastRow(rowIndex);

column.setFirstCol(colIndex);

column.setLastCol(colIndex);

if (column.getChildrens() != null && column.getChildrens().size() > 0) {

column.setLastCol(colIndex + column.getChildrens().size() - 1);

generateHeader(column.getChildrens(), column, maxDepth);

} else {

if (column.getWidth() > 0) {

this.sheet.setColumnWidth(colIndex, column.getWidth() * 256);

}

this.fields.add(column);

column.setLastRow(maxDepth);

}

if (parent != null && column.getLastCol() > parent.getLastCol()) {

parent.setLastCol(column.getLastCol());

}

if (column.getLastRow() > column.getFirstRow() || column.getLastCol() > column.getFirstCol()) {

sheet.addMergedRegion(new CellRangeAddress(column.getFirstRow(), column.getLastRow(), column.getFirstCol(), column.getLastCol()));

}

Cell cell = row.createCell(column.getFirstCol());

cell.setCellValue(column.getName());

colIndex = column.getLastCol() + 1;

}

}

private int generateData(List list, int firstRow) {

int lastRow = firstRow;

int totalRow = 0;

for (T item : list) {

Row row = sheet.getRow(lastRow);

if (row == null) {

row = sheet.createRow(lastRow);

}

if (item.getChildrens() != null && item.getChildrens().size() > 0) {

int total = generateData(item.getChildrens(), lastRow);

lastRow += total - 1;

totalRow += total;

} else {

totalRow++;

}

Class cls = item.getClass();

for (Field field : cls.getDeclaredFields()) {

Column column = this.fields.stream().filter(p -> p.getField().equals(field.getName())).findFirst().get();

try {

field.setAccessible(true);

Object obj = field.get(item);

String value = obj == null ? "" : obj.toString();

Cell cell = row.createCell(column.getFirstCol());

cell.setCellValue(value);

if (lastRow > firstRow) {

sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, column.getFirstCol(), column.getLastCol()));

}

} catch (Exception ex) {

System.out.print(ex.getMessage());

}

}

lastRow++;

firstRow = lastRow;

}

return totalRow;

}

private > int getMaxDepth(List list, int depth) {

int maxDepth = 0;

for (TreeNode item : list)

{

item.setDepth(depth);

if (item.getChildrens() != null)

{

int res = getMaxDepth(item.getChildrens(), depth + 1);

if (res > maxDepth) maxDepth = res;

}

if (depth > maxDepth) maxDepth = depth;

}

return maxDepth;

}

}

用到的实体类:

package com.ruoyi.common.utils.poi;

import java.util.List;

public abstract class TreeNode {

private int depth;

private List childrens;

public int getDepth() {

return depth;

}

public void setDepth(int depth) {

this.depth = depth;

}

public List getChildrens() {

return childrens;

}

public void setChildrens(List childrens) {

this.childrens = childrens;

}

}

package com.ruoyi.common.utils.poi;

import java.util.List;

public class Column extends TreeNode {

public Column(String name, String field) {

this.name = name;

this.field = field;

}

public Column(String name, List childrens) {

this.name = name;

this.setChildrens(childrens);

}

private String field;

private String name;

private int width;

private int firstRow;

private int lastRow;

private int firstCol;

private int lastCol;

public String getField() {

return field;

}

public void setField(String field) {

this.field = field;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getWidth() {

return width;

}

public void setWidth(int width) {

this.width = width;

}

public int getFirstRow() {

return firstRow;

}

public void setFirstRow(int firstRow) {

this.firstRow = firstRow;

}

public int getLastRow() {

return lastRow;

}

public void setLastRow(int lastRow) {

this.lastRow = lastRow;

}

public int getFirstCol() {

return firstCol;

}

public void setFirstCol(int firstCol) {

this.firstCol = firstCol;

}

public int getLastCol() {

return lastCol;

}

public void setLastCol(int lastCol) {

this.lastCol = lastCol;

}

}

标签:java,String,column,excel,表头,int,private,import,public

来源: https://www.cnblogs.com/cxyzj/p/13029433.html

相关文章:

  • 程序异常退出的原因_Python异常处理详解(基础篇十一)
  • h5显示今天的时间_试驾红旗H5!红旗品牌卖得最火的车型,开起来究竟咋样?...
  • 雷迪9000使用说明_雷迪司UPS监控软件使用说明
  • libsvm python_LibSVM for Python 使用
  • 列表输出循环左移_Java Note-数据结构(3)列表
  • mysql 远程日志_将syslog ng日志写入MySQL(远程)数据库
  • mysql npe问题_万恶的 NPE 如何避免,几种你必须知道的方案!!!
  • dubbo monitor mysql_dubbox 的各种管理和监管
  • mysql传入Bean_mysql 表映射为java bean 手动生成。
  • mysql数据库程序员_大神程序员养成之路-Mysql数据库基础
  • mac svn客户端_SmartSVN 12 for Mac(SVN客户端)
  • mysql随机数据插入_mysql随机数据生成并插入
  • asp 备份 mysql数据库_用Asp备份与恢复SQL Server 数据库_数据库相关_脚本
  • mysql rds数据库优势_云数据库RDS基础版的优势及适用场景
  • mysql写下拉树_PHP+mysql实现从数据库获取下拉树功能的方法
  • FastReport在线报表设计器工作原理
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • input实现文字超出省略号功能
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Magento 1.x 中文订单打印乱码
  • Mysql优化
  • Python中eval与exec的使用及区别
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • underscore源码剖析之整体架构
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​2021半年盘点,不想你错过的重磅新书
  • #{}和${}的区别?
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • $.ajax()方法详解
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (论文阅读40-45)图像描述1
  • (七)Java对象在Hibernate持久化层的状态
  • (一)80c52学习之旅-起始篇
  • (译)2019年前端性能优化清单 — 下篇
  • (正则)提取页面里的img标签
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .NET文档生成工具ADB使用图文教程
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @html.ActionLink的几种参数格式
  • @Service注解让spring找到你的Service bean
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • []FET-430SIM508 研究日志 11.3.31