springboot自定义表格(动态合并单元格)

一、需求展示(一个订单多个商品,商品数量不限订单行合并)

二、技术选型(jxls自定义模板)

        <!-- 版本具体看官网Release,这里我们使用 2.13.0 --><dependency><groupId>org.jxls</groupId><artifactId>jxls</artifactId><version>2.13.0</version></dependency><dependency><groupId>org.jxls</groupId><artifactId>jxls-poi</artifactId><version>2.13.0</version></dependency><!-- 要使用基于JavaExcelAPI的转换器实现,请添加以下依赖项 --><dependency><groupId>hu.blackbelt.bundles.jxls</groupId><artifactId>org.jxls</artifactId><version>2.10.0_1</version></dependency>

三、导出订单的数据结构展示

[{"orderName": "订单1","no": "13465464464121","terminalValue": "微信 小程序","userInfo": "微信 小程序","items": [{"spuName": "ipnoe 6s","properties": "非卖品,勿拍!!!!","count": "10","originalUnitPrice": "10"}]
}]

四、对应模板展示

1、局部效果展示(一定要使用xlsx格式作为模板文档,xls有点问题)

2、jx:area(lastCell = "P2")参数解释:整个表的作用域是到P列第2行,作用与必须要并且必须放在表格的的首行首列

3、jx:each(items="tpList"var="tradeOrderPageItemRespVO" lastCell="P2")参数解析:tpList是最外层的order集合,tradeOrderPageItemRespVO是tpList循环时item的别称,P2是tpList循环作用表的生效范围。
4、jx:mergeCells(rows="tradeOrderPageItemRespVO.items.size()" lastCell="A2")参数解析:rows要合并行的行数,lastcall是定位那A列第2行要进行单元行合并,有多少列要合并就拷贝多少次并将lastcall定位到相关列进行修改。尝试设置为C2没有从A2的位置自动每列合并到C2不知道为啥,就一列一列的设置的。

5、jx:each(items="tradeOrderPageItemRespVO.items" var="tradeOrderItemBaseVO" lastCell="H2")参数解析:tradeOrderPageItemRespVO.items就是订单里边商品做循环,别名叫tradeOrderItemBaseVO,tradeOrderPageItemRespVO.items的作用范围就是批注D2到H2的位置可以使用用${}去到里边的变量。

6、其他表达式使用请参考官网JXLS - (sourceforge.net)或文末备注

五、代码参考

1、引入依赖

        <!-- 版本具体看官网Release,这里我们使用 2.13.0 --><dependency><groupId>org.jxls</groupId><artifactId>jxls</artifactId><version>2.13.0</version></dependency><dependency><groupId>org.jxls</groupId><artifactId>jxls-poi</artifactId><version>2.13.0</version></dependency><!-- 要使用基于JavaExcelAPI的转换器实现,请添加以下依赖项 --><dependency><groupId>hu.blackbelt.bundles.jxls</groupId><artifactId>org.jxls</artifactId><version>2.10.0_1</version></dependency>

2、工具构建

package cn.iocoder.yudao.module.trade.utils;import org.apache.commons.jexl3.JexlBuilder;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.util.JxlsHelper;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;public class JxlsUtils {public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException {Context context = new Context();if (model != null) {for (String key : model.keySet()) {context.putVar(key, model.get(key));}}JxlsHelper jxlsHelper = JxlsHelper.getInstance();Transformer transformer = jxlsHelper.createTransformer(is, os);JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformer.getTransformationConfig().getExpressionEvaluator();Map<String, Object> funcs = new HashMap<>();funcs.put("utils", new JxlsUtils()); // 添加自定义功能evaluator.setJexlEngine(new JexlBuilder().namespaces(funcs).create());jxlsHelper.processTemplate(context, transformer);}
}

3、Controller导出

    @GetMapping("/export-excel")@Operation(summary = "导出订单表格 Excel")@PreAuthorize("@ss.hasPermission('trade:order:export')")@OperateLog(type = EXPORT)public void exportActivityExcel(TradeOrderPageReqVO reqVO,HttpServletResponse response) throws IOException {CommonResult<PageResult<TradeOrderPageItemRespVO>> orderPage = getOrderPage(reqVO);List<TradeOrderPageItemRespVO> list = orderPage.getData().getList();List<TradeOrderExcelVO> result = new ArrayList<>();for (TradeOrderPageItemRespVO tradeOrderPageItemRespVO : list) {TradeOrderExcelVO convert = TradeOrderConvert.INSTANCE.convert(tradeOrderPageItemRespVO, 1);result.add(convert);}// 设置响应头response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment; filename=output.xlsx");// 使用 jXLS 进行模板变量替换并导出 Exceltry (InputStream inputStream = getClass().getResourceAsStream("/tem/tem.xlsx");OutputStream outputStream = response.getOutputStream()) {//excel模板内,数据组装Map<String, Object> map = new HashMap<>();map.put("tpList", result);JxlsUtils.exportExcel(inputStream, outputStream, map);}}

六、备注

jx:mergeCells(lastCell="合并单元格范围"
[, cols="合并的列数"]
[, rows="合并的行数"]
[, minCols="要合并的最小列数"]
[, minRows="要合并的最小行数"]
)lastCell:合并单元格范围;
cols:合并的列数;
rows:合并的行数;
minCols:要合并的最小列数;
minRows:要合并的最小行数;jx:each(items="countMonths" var="month" lastCell="C3" direction="RIGHT")
这里还是通过jx:each来使用,不同的是direction 属性的值为:RIGHT(向右),默认为:DOWN(向下)
countMonths:动态列集合,month为集合循环的实体,取值为:${month}
contracts:行数据集合,contract、colData 都是集合循环的实体,取值为:${contract.custName}等
colData.monthData.get(month):动态列的数据,根据列名去匹配实体字段
${empty()}:判断集合对应动态列数据 是否为空,做好判断,写入数据
动态列数据行的数据获取:${empty(colData.monthData.get(month) ) ? 0 : colData.monthData.get(month)}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/61887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fastdds之core

目录 Entity Entity

基于JavaWeb和mysql实现校园订餐前后台管理系统(源码+数据库)

一、项目简介 本项目是一套基于JavaWeb和mysql实现网上书城前后端管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都…

Kubernetes技术--k8s核心技术 configMap

1.概述 configMap最主要的作用是存储一些不加密的数据到/etcd,让pod以变量或者数据卷(volume)挂载到容器。 应用场景:配置文件、存储信息等 2.使用 -1.创建配置文件。 这里我们需要先编写一个配置文件。使用redis,如下所示:

Android studio实现圆形进度条

参考博客 效果图 MainActivity import androidx.appcompat.app.AppCompatActivity; import android.graphics.Color; import android.os.Bundle; import android.widget.TextView;import java.util.Timer; import java.util.TimerTask;public class MainActivity extends App…

2023开学季图书馆荐八一新书《乡村振兴战略下传统村落文化旅游设计 》中大许少辉博士后著

2023开学季图书馆荐八一新书《乡村振兴战略下传统村落文化旅游设计 》中大许少辉博士后著

说说大表关联小表

分析&回答 Hive 大表和小表的关联 优先选择将小表放在内存中。小表不足以放到内存中&#xff0c;可以通过bucket-map-join(不清楚的话看底部文章)来实现&#xff0c;效果很明显。 两个表join的时候&#xff0c;其方法是两个join表在join key上都做hash bucket&#xff0c…

【数据结构回顾】

数据结构回顾 一、单链表二、单循环链表 一、单链表 #include <stdio.h> #include <stdlib.h>typedef struct Node {int data;Node *next; }Node;Node* initList() {Node *list (Node*)malloc(sizeof(Node));list->data 0;list->next NULL;return list; }…

Netty源码NioEventLoop解析

带着问题源码 Netty 的 NioEventLoop 是如何实现的&#xff1f;它为什么能够保证 Channel 的操作是线程安全的&#xff1f;Netty 如何解决 JDK epoll 空轮询 Bug&#xff1f;NioEventLoop 是如何实现无锁化的&#xff1f; 一、作用与设计原理 Netty的NioEventLoop并不是一个存…

pg_database中的datlastsysoid

一&#xff0c;关于 pg_database 在 PostgreSQL 中&#xff0c;对于在数据库集群内创建的每个数据库,其关键信息都会被保存到 pg_database 系统表中。 PostgreSQL 确保通过 pg_database 系统表持久化存储每个数据库的属性信息&#xff0c;以方便后续管理和使用。这也让 pg_da…

Windows安装配置Tomcat服务器教程 - 外网远程访问

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#xff0…

振动智能监测与设备可靠性:无线技术的契机

在现代工业领域&#xff0c;设备的可靠性和稳定运行对于生产效率和安全性至关重要。然而&#xff0c;由于设备的频繁使用和各种环境影响&#xff0c;设备故障和突发停机仍然是不可避免的挑战。为了有效地应对这些挑战&#xff0c;振动智能监测技术结合无线传感器的应用正在成为…

W5500-EVB-PICO主动PING主机IP检测连通性(十)

前言 上一章我们用W5500_EVB_PICO 开发板做UDP组播数据回环测试&#xff0c;那么本章我们进行W5500_EVB_PICO Ping的测试。 什么是PING&#xff1f; Ping &#xff08;Packet Internet Groper&#xff09;是一种因特网包探索器&#xff0c;用于测试网络连接量的程序 。Ping是…

“北科Java面试宝典(211最详细讲解)“

Version : V1.0 北科Java面试宝典一、Java基础面试题【24道】二、JVM虚拟机面试题【14道】三、集合相关面试题【17道】四、多线程 【25道】五、IO【5道】六、网络编程 【9道】七、MySQL以及SQL面试题【20道】八、常用框架【19道】九、中间件和分布式 【54道】十、设计模式面试 …

Plex私人影音云盘搭建教程:本地电脑使用内网穿透实现远程访问

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频&#xff0c;已经算是生活中稀松平常的场景了&#xff0c;特别是各…

数据库和缓存如何保证一致性?

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【一心同学】&#xff0c;一位上进心十足的【Java领域博主】&#xff01;&#x1f61c;&#x1f61c;&#x1f61c; ✨【一心同学】的写作风格&#x…

匿名函数( lambda 表达式)

在 C 中&#xff0c;匿名函数也被称为 lambda 表达式。C11 引入了 lambda 表达式&#xff0c;使得在需要函数对象&#xff08;函数符&#xff09;的地方可以使用匿名函数来代替。 lambda 表达式的基本语法如下&#xff1a; [capture list] (parameter list) -> return typ…

JVM-CMS

when 堆大小要求为4-8G 原理 初始标记&#xff1a;执行CMS线程->STW&#xff0c;标记GC Root直接关联的对象->低延迟 并发标记&#xff1a;执行CMS线程和业务线程&#xff0c;从GC Root直接关联的对象开始遍历整个对象图 重新标记&#xff1a;执行CMS线程->STW&a…

Mybatis-Plus快速入门

目录 一、基础工程 1、创建一个数据库&#xff1a;mp 2、添加数据 3、创建初始工程 4、添加依赖 二、Mybatis Mybatis-Plus 1、创建子工程&#xff1a;mybatis-plus-simple 2、在子工程下添加配置 2.1Mybatis实现查询User 2.1.1、编写User实体对象 2.1.2、编写UserMa…

【业务功能篇93】微服务-springcloud-多线程-异步处理-异步编排-CompletableFutrue-实战运用

异步处理编排 我们可以在商品详细信息查询的位置实现CompletableFuture的异步编排处理。 根据业务分析&#xff1a;3.4.5数据接口的入参信息需要来源于1数据接口的返回信息&#xff0c;也就是skuid 所以可以设计 1 3 4 5 串行线程 &#xff0c;而 3 4 5依赖1 &#xff0c;需要等…

Redis项目实战——优惠券秒杀

目录 Redis自增功能解决全局唯一IDRedis实现优惠券秒杀的主要思路实现过程中出现的问题及解决方法超卖问题方案1 悲观锁方案2 乐观锁 一人一单问题分布式锁如何用Redis实现分布式锁&#xff1f; Redis优化秒杀消息队列实现异步秒杀List发布订阅模式Stream Redis自增功能解决全局…