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

news2024/11/21 0:32:57

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

二、技术选型(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 进行模板变量替换并导出 Excel
        try (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.coloradmin.cn/o/955052.html

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

相关文章

分布式集群框架——zookeeper必考面试题②

15、数据同步 整个集群完成 Leader 选举之后&#xff0c;Learner&#xff08;Follower 和 Observer 的统称&#xff09;回向Leader 服务器进行注册。当 Learner 服务器想 Leader 服务器完成注册后&#xff0c;进入数据同步环节。数据同步流程&#xff1a;&#xff08;均以消息…

工作流程flowable

目录 Flowable工作流分类&#xff1a;一、会签流程二、或签流程分支流程四、并行流程 第二步&#xff1a;源码及表结构对应关系部署一次流程 第三步 流程监听器与任务监听器 Flowable 工作流分类&#xff1a; 参考: link 官方中文文档&#xff1a;网关 一、会签流程 适用场…

【C语言】循环语句详解

✨个人主页&#xff1a; Anmia.&#x1f389;所属专栏&#xff1a; C Language &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 目录 1.什么是循环结构&#xff1f; 2.while循环 while流程图 while语句中的break和continue break continue 3.for循环 for流…

Ubuntu 20.04.5 怎么安装微信

这是我的ubutun版本号 在这个系统装桌面版微信很多功能不健全。搜索了很多方法&#xff0c;这个算是不错的一个法子。 1.添加仓库 首次使用时&#xff0c;你需要运行如下一条命令将移植仓库添加到系统中。 wget -O- https://deepin-wine.i-m.dev/setup.sh | sh 2.应用安装 …

无代码:软件开发从代码语言到业务语言的拐点

在互联网巨头和中小企业纷纷追求移动互联和“上云”的今天&#xff0c;业务在线已成为众多企业数字化转型的必经之路。然而&#xff0c;传统的软件重装开发模式已经无法满足企业快速变化的需求&#xff0c;同时IT专业人才的成本也在不断攀升&#xff0c;使得企业的IT交付能力面…

ACL 访问控制 过滤数据 维护网络安全(第七课)

一 ACL 简介 ACL是Access Control List&#xff08;访问控制列表&#xff09;的缩写&#xff0c;是一种用于控制文件、目录、网络设备等资源访问权限的方法。ACL可以对每个用户或用户组设置不同的访问权&#xff0c;即在访问控制清单中为每个用户或用户组指定允许或禁止访问该…

十年网络安全工程师整理:渗透测试工具使用方法介绍

渗透测试&#xff0c;是为了证明网络防御按照预期计划正常运行而提供的一种机制。 渗透人员在不同的位置&#xff08;比如从内网、从外网等位置&#xff09;利用各种手段对某个特定网络进行测试&#xff0c;以期发现和挖掘系统中存在的漏洞&#xff0c;然后输出渗透测试报告&a…

RT-Thread 内核对象模型

静态对象和动态对象 RTT内核采用面向对象的设计思想进行设计&#xff0c;系统级的基础设施都是一种内核对象&#xff0c;例如线程&#xff0c;信号量&#xff0c;互斥量&#xff0c;定时器等。 内核对象分为两类&#xff1a;静态内核对象和动态内核对象&#xff0c;静态内核对…

Walmart电商促销活动即将开始,如何做促销活动?需要注意什么?

近日&#xff0c;沃尔玛官宣Baby Days优惠活动将于9月1日正式开始&#xff01;卖家可以把握机会&#xff0c;通过设置促销定价&#xff0c;以最优惠的婴儿相关产品价格吸引消费者&#xff0c;包括汽车座椅、婴儿车、尿布袋、家具、床上用品、消耗品、婴儿服装、孕妇装等。注意本…

一文了解评估 K8s 原生存储产品需要关注的关键能力

近些年&#xff0c;越来越多的企业使用 Kubernetes&#xff08;K8s&#xff09;支持生产环境关键业务。这些业务往往对存储性能和稳定性具有更高的要求&#xff0c;传统存储方案难以充分满足&#xff0c;因此不少用户开始关注更契合 K8s 环境的 K8s 原生存储方案。 不过&#…

VSAN硬盘出现resetremoved

原创作者&#xff1a;运维工程师 谢晋 VSAN硬盘出现reset&removed 客户环境有8台服务器dell R740和R740XD服务器组成了一套VSAN集群&#xff0c;但R740那四台的物理机老是出现硬盘故障需进行硬盘更换&#xff0c;后发现刚换完的硬盘没过几天又坏了&#xff0c;先开始怀疑…

shell超基础入门(超详细)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

财报解读:“百亿生态”成效初显,拼多多跨越S型曲线?

电商江湖再起变化&#xff0c;掀起浪潮者仍然是拼多多。 在这充满挑战与机遇的商业环境中&#xff0c;企业的发展轨迹正如S型曲线般&#xff0c;充满起伏和曲折&#xff0c;而拼多多的最新财报数据无疑已经展现出了与S曲线理论相契合的发展轨迹。它不仅在发展中不断进行战略调…

c++:QT day2 信号和槽

1.多态&#xff1a; 静态多态&#xff1a;函数的重载 动态多态&#xff1a;程序运行 多态的实现:父类的指针或引用&#xff0c;指向或初始化子类的对象&#xff0c;调用子类对父类重写的函数&#xff0c;进而展开子类的功能 2.虚函数&#xff1a;用virtua关键字修饰的函数是虚函…

信息技术04--初/高中--教学设计知识点梳理

文章目录 第一章 信息技术基础1.1 信息概念与特征1.1.1 信息的概念1.1.2 信息的特征 1.2 信息技术概述1.2.1 信息技术概念1.2.2 信息技术五次革命 1.3 信息的获取1.3.1 信息获取的过程&#xff1a;1.3.2 搜索引擎1.3.3 引擎符号 1.4 信息的表示和编码1.4.1 进制分类1.4.2 二进制…

字符函数和字符串函数(1)

C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在常量字符串中或者字符数组 中。字符串常量适用于那些对它不做修改的字符串函数。 目录 函数介绍 strlen strcpy strcat strcmp strncpy strncat strncmp s…

LINQ详解(查询表达式)

什么是LINQ&#xff1f; LINQ(语言集成查询)是将查询功能直接集成到C#中。数据查询表示简单的字符串&#xff0c;在编译时不会进行类型检查和IntelliSense(代码补全辅助工具)支持。 在开发中&#xff0c;通常需要对不同类型的数据源了解不同的查询语句&#xff0c;如SQL数据库…

⚠️ WinRAR 中的趋势漏洞 CVE-2023-38831

在漏洞区域 WinRAR 是一种流行的数据压缩程序。网络犯罪分子已经利用 CVE-2023-38831攻击交易者。 经纪账户面临风险 利用 CVE-2023-38831 漏洞&#xff0c;攻击者会创建 ZIP 压缩文件来传播各种恶意软件系列&#xff0c;如 DarkMe、GuLoader、Remcos RAT&#xff0c;并将其…

Zabbix --- Snmp Trap监控详细教程

一、zabbix服务器安装snmptrapd服务 1、安装服务 yum -y install net-snmp net-snmp-agent-libs net-snmp-devel net-snmp-libs net-snmp-perl net-snmp-utils 注&#xff1a;使用perl脚本解析trap信息并进行格式化&#xff0c;net-snmp-perl 2、zabbix启用snmptrap进程&…

react轮播图

这里 我用的是组件&#xff1a; 网址&#xff1a;Collapse 折叠面板 - Ant Design Mobile 1.首先 先声明一个变量 2、把需要的数据存存进去 3、组件内容复制过来&#xff08;这里用到的是map循环&#xff09; 然后图片就出来了 就是这个简单 哈哈哈哈&#xff01;&#xff01…