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

java导出word使用模版与自定义联合出击解决复杂表格!

1. 看一下需要导出什么样子的表格
在这里插入图片描述如图所示,这里的所有数据行都是动态的,需要根据查询出来的数据循环展示。
如果只是这样的话,使用freemarker应该都可以搞定,但是他一列中内容相同的单元格,需要合并。
这对于表格样式固定的freemarker就搞不定了。
经过一通百度,发现了一个导出文档很好用的框架 poi-tl(实际用的时候也并不怎么好用,学习成本高,功能全)
下面上实战
2. 引入poi-tl 的相关依赖

    <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version></dependency>

关于版本问题,老版比新版好用,新版太过规范
官方文档地址

3.先放一个docx的模版,模版样子如下
在这里插入图片描述生产装置下面哪一行小字是:{{templateRowRenderData}},用来填充数据的,使用双花括号标记。
在这里插入图片描述
放在根目录下面,不然找不到哦
3.开始建立实体类,查询数据,填充数据,渲染模版
实体类,如果类中有什么字典,数字标识字段需要转成所表示的字符串

package com.ruoyi.prevention.inventory.domain.vo;import lombok.Data;/*** 安全风险管控措施对象 prevention_risk_measures** @author ruoyi* @date 2023-06-27*/
@Data
public class AllInventoryVo {private String id;/*** 管控对象(分析对象名称)*/private Integer zoneType;private String zoneTypeStr;/*** 责任部门名称*/private String responsibleDepartmentName;/*** 责任人名称*/private String responsibleStaffName;/*** 风险分析单元名称*/private String riskUnitName;/*** 风险单元id*/private String riskUnitId;/*** 安全风险事件*/private String riskEventName;/** 风险事件id */private String riskEventId;/** 管控措施分类 1 */private String controlMeasuresClassify1;/** 管控措施分类 2 */private String controlMeasuresClassify2;/** 管控措施分类 3 */private String controlMeasuresClassify3;/** 管控措施描述 */private String controlMeasuresDescription;/** 隐患排查内容 */private String treacherousContent;/** 管控措施id */private String riskMeasuresId;/** 岗位负责人 */private String postResponsible;/** 巡检周期 */private Integer checkCycle;/** 巡检周期单位 */private Integer checkCycleUnit;private String checkCycleUnitStr;}

渲染数据到templateRowRenderData,这里和模版的参数名要保持一致

package com.ruoyi.prevention.inventory.word;import com.deepoove.poi.expression.Name;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author: fanbaolin* @Date: 2023/12/12* @Description: 基础数据+动态数据即* @Version: 1.0*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TemplateData {@Name("templateRowRenderData")private TemplateRowRenderData templateRowRenderData;}

定义哪一列需要填充哪一个字段的值

package com.ruoyi.prevention.inventory.word;import com.deepoove.poi.data.CellRenderData;
import com.deepoove.poi.data.ParagraphRenderData;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.style.CellStyle;
import com.deepoove.poi.data.style.ParagraphStyle;
import com.deepoove.poi.data.style.RowStyle;
import com.deepoove.poi.data.style.Style;
import com.ruoyi.prevention.inventory.domain.vo.AllInventoryVo;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** @author: fanbaolin* @Date: 2023/12/12* @Description: 将实体类转化为一个表格 因为渲染只接受RowRenderData类型* ps:新版真的难用* @Version: 1.0*/
@Data
public class TemplateRowRenderData {/*** 管控分类措施*/private List<RowRenderData> typeRowRenderDataList;private RowStyle rowStyle;public TemplateRowRenderData(List<AllInventoryVo> inventoryVos) {// 初始化样式initStyle();// 初始化动态数据initData(inventoryVos);}private void initStyle() {// 字体样式Style style = new Style("宋体", 10);// 段落样式ParagraphStyle paragraphStyle = new ParagraphStyle();paragraphStyle.setDefaultTextStyle(style);// ps:这里才是字体居中对齐paragraphStyle.setAlign(ParagraphAlignment.CENTER);// 表格样式CellStyle cellStyle = new CellStyle();// ps:表格也需要居中,否则字体不在正中间,会偏上cellStyle.setVertAlign(XWPFTableCell.XWPFVertAlign.CENTER);cellStyle.setDefaultParagraphStyle(paragraphStyle);// 行样式this.rowStyle = new RowStyle();rowStyle.setDefaultCellStyle(cellStyle);}private void initData(List<AllInventoryVo> inventoryVos) {// 管控分类List<RowRenderData> newTypeRowRenderDataList = new ArrayList<>();if (CollectionUtils.isNotEmpty(inventoryVos)) {for (AllInventoryVo inventoryVo : inventoryVos) {// 共有14列List<CellRenderData> cellDataList = new ArrayList<>();cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getZoneTypeStr())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getResponsibleDepartmentName())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getResponsibleStaffName())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getRiskUnitName())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getRiskEventName())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getControlMeasuresClassify1())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getControlMeasuresClassify2())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getControlMeasuresClassify3())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getControlMeasuresDescription())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getTreacherousContent())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getPostResponsible())));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getCheckCycle() == null ? "":inventoryVo.getCheckCycle() + "")));cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText(inventoryVo.getCheckCycleUnitStr())));// 备注先空着cellDataList.add(new CellRenderData().addParagraph(new ParagraphRenderData().addText("")));RowRenderData rowRenderData = new RowRenderData();// 样式rowRenderData.setRowStyle(rowStyle);rowRenderData.setCells(cellDataList);newTypeRowRenderDataList.add(rowRenderData);}this.typeRowRenderDataList = newTypeRowRenderDataList;}else{this.typeRowRenderDataList = Collections.emptyList();}}
}

渲染数据并合并列,这里我的数据是摊平的,用了两个指针,首指针和尾指针找同一列上数据相同挨着的单元格然后把它们合并

package com.ruoyi.prevention.inventory.word;import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import com.deepoove.poi.policy.TableRenderPolicy;
import com.deepoove.poi.util.TableTools;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;import java.util.List;/*** @author: fanbaolin* @Date: 2023/12/12* @Description: 自定义渲染插件-for循环* 这里因为需要操作表格-所以集成DynamicTableRenderPolicy:动态表格插件,允许直接操作表格对象* 详情请看:http://deepoove.com/poi-tl/#_%E9%BB%98%E8%AE%A4%E6%8F%92%E4%BB%B6* @Version: 1.0*/
@NoArgsConstructor
public class TemplateTableRenderPolicy extends DynamicTableRenderPolicy {private XWPFTable xwpfTable;@Overridepublic void render(XWPFTable xwpfTable, Object data) throws Exception {if (null == data) {return;}this.xwpfTable = xwpfTable;TemplateRowRenderData templateRowRenderData = (TemplateRowRenderData) data;// 分类和管控措施的数据List<RowRenderData> typeRowRenderDataList = templateRowRenderData.getTypeRowRenderDataList();if (CollectionUtils.isNotEmpty(typeRowRenderDataList)) {// 表头下面那一行int typeMemberRow = 1;// 移除空白的表头下面那一行xwpfTable.removeRow(typeMemberRow);// 得到表头那一行的数据XWPFTableRow xwpfTableRow = xwpfTable.getRow(0);for (int i = typeRowRenderDataList.size() - 1; i > -1; i--) {// 重新插入表格XWPFTableRow insertNewTableRow = xwpfTable.insertNewTableRow(typeMemberRow);// 统一高度insertNewTableRow.setHeight(xwpfTableRow.getHeight());for (int j = 0; j < 14; j++) {insertNewTableRow.createCell();}// 渲染数据TableRenderPolicy.Helper.renderRow(xwpfTable.getRow(typeMemberRow), typeRowRenderDataList.get(i));}// 合并行 下标为1的行开始合并(去除表头)必须一个一个catchcatchMergeRow(typeRowRenderDataList,0);catchMergeRow(typeRowRenderDataList,1);catchMergeRow(typeRowRenderDataList,2);catchMergeRow(typeRowRenderDataList,3);catchMergeRow(typeRowRenderDataList,4);catchMergeRow(typeRowRenderDataList,5);catchMergeRow(typeRowRenderDataList,6);catchMergeRow(typeRowRenderDataList,7);}}private void catchMergeRow(List<RowRenderData> typeRowRenderDataList, int cell){try {mergeRow(typeRowRenderDataList,cell,1,1,false);}catch (RuntimeException ignore){}}/*** 首尾指针递归判断列表下一个值是否和自己相同** @param typeRowRenderDataList* @param cell* @param from* @param to* @param hasDef*/private void mergeRow(List<RowRenderData> typeRowRenderDataList, int cell, int from, int to, boolean hasDef) {if(from == typeRowRenderDataList.size()){throw new RuntimeException("跳出递归");}else{for (int i = from - 1 ; i < typeRowRenderDataList.size() - 1; i++) {String content = typeRowRenderDataList.get(i).getCells().get(cell).getParagraphs().get(0).getContents().toString();String nextContent = typeRowRenderDataList.get(i + 1).getCells().get(cell).getParagraphs().get(0).getContents().toString();if(nextContent.equals(content)){to = to + 1;}else{if(from > to){return;}if(from == to){// 整体下移一个单位from += 1;to += 1;}else{// 合并行TableTools.mergeCellsVertically(xwpfTable, cell, from, to);// 合并完成 首指针指向尾端from = to;}// 递归调用mergeRow(typeRowRenderDataList,cell,from,to,true);}}}// 如果这一列没有不同的值 全给他合并了if(!hasDef){if(from >= to){return;}TableTools.mergeCellsVertically(xwpfTable, cell, from, to);}}
}

4.service层掉用
这里我还做了一个word转pdf的操作(用的aspose),没有需求的老铁可以不用要

  /*** 导出安全风险清单*/@Overridepublic void report() {ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletResponse response = requestAttributes.getResponse();response.setContentType("application/pdf");response.setHeader("Content-Disposition", "attachment; filename=" + "report.pdf");List<AllInventoryVo> allInventoryVos = flatList();clearTreacherousContentLabel(allInventoryVos);TemplateRowRenderData templateRowRenderData3 = new TemplateRowRenderData(allInventoryVos);// 2)完整数据TemplateData templateData = new TemplateData(templateRowRenderData3);try {Configure config = Configure.builder().bind("templateRowRenderData", new TemplateTableRenderPolicy()).build();//  四、导出ClassPathResource classPathResource = new ClassPathResource("templates" + File.separator + "prevention.docx");XWPFTemplate template = XWPFTemplate.compile(classPathResource.getInputStream(), config).render(templateData);String filePath = "";if (SystemUtil.getOsInfo().isWindows()) {filePath = "d:/tmp\\work\\report.doc";}else{filePath = "/tmp/work/report.doc";}template.writeAndClose(Files.newOutputStream(Paths.get(filePath)));File file = new File(filePath);// 生成word filePath是将要被转化的word文档Document doc = new Document(filePath);// 转换 字体不一样doc.save(response.getOutputStream(), SaveFormat.PDF);// 删除临时文件file.delete();} catch (Exception e) {throw new RuntimeException(e);}}

5.controller就不写了,结果如下
在这里插入图片描述
学习成本一天半,刚入门的新手建议不要看了

相关文章:

java导出word使用模版与自定义联合出击解决复杂表格!

1. 看一下需要导出什么样子的表格 如图所示&#xff0c;这里的所有数据行都是动态的&#xff0c;需要根据查询出来的数据循环展示。 如果只是这样的话&#xff0c;使用freemarker应该都可以搞定&#xff0c;但是他一列中内容相同的单元格&#xff0c;需要合并。 这对于表格样式…...

GO设计模式——9、过滤器模式(结构型)

目录 过滤器模式&#xff08;Filter/Criteria Pattern&#xff09; 代码实现 过滤器模式&#xff08;Filter/Criteria Pattern&#xff09; 过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种设计模式&#xff0c;…...

fastadmin 导出

php 接收数据 set_time_limit(0);ini_set(memory_limit, -1);$ids $this->request->post(ids);$filter $this->request->post(filter);$op $this->request->post(op);$search $this->request->post(search);$whereIds $ids all ? 11 : [id >…...

六、CM4树莓派USBRS转485串口通讯

一、串行通讯接口 串行通讯接口简称串口&#xff08;UART&#xff09; 采用串行通信方式的扩展接口&#xff0c;数据位一位一位的按照顺序传送 优点&#xff1a;通信线路简单&#xff0c;只要一对传输线就可以实现双向通信能够大大降低成本&#xff0c;适合远距离通信。 缺点…...

c++知识总结

一 细碎知识 1.27 # 1.27.1 # pragma once 参考 C++学习笔记之pragma once的理解_pragma once什么意思-CSDN博客https://blog.csdn.net/lynnlee_36/article/details/105322937作用 保证只被编译一次,和#ifndef,#define,#endif功能相同 1.27.2 #if defined(__cplusplus…...

python-爬取壁纸

代理池的&#xff0c;防止IP 被封 找到图片真实地址 现在看到的只是图片的预览地址 (previews) 1.检查&#xff1a; 2.鼠标变为箭头时查看网页源代码 关于怎样在源代码中找到图片的真实地址 ??? 为什么在源代码界面 ctrl f 时候搜索的是 .png ??? 首先图片地址是以 .j…...

第31期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…...

湖仓一体架构理论与实践汇总

湖仓一体架构理论与实践汇总 软件研发本质上属于“手工业”。软件研发在很大程度上还是依赖于个人的能力。当软件规模较小时&#xff0c;依赖“手工业”可以解决问题&#xff0c;但是当软件规模大了之后再依赖“手工业”就不行了。 软件的复杂度包含两个层面&#xff1a;软件…...

Redission从入门到入门

1. Redisson简介 Redisson 是一个在 Java 环境中使用的 Redis 客户端库。它提供了丰富的功能&#xff0c;使得在 Java 应用中与 Redis 交互变得更加简单和高效。Redisson 不仅提供了基本的 Redis 操作&#xff0c;还提供了许多高级功能&#xff0c;使其成为在 Java 项目中实现…...

PHP对接企业微信

前言 最近在做项目中&#xff0c;要求在后台管理中有企业微信管理的相关功能。相关准备工作&#xff0c;需要准备好企业微信账号&#xff0c;添加自建应用&#xff0c;获得相应功能的权限&#xff0c;以及agentid、secre等。 参考文档&#xff1a; 企业微信开发文档 功能实现 因…...

【原创】录剪视频的折腾之路

制作视频的起因 本人为IT男&#xff0c;IT发展快&#xff0c;需要学习的东西又多。往往为了一个技术小问题&#xff0c;花好几天时间学习&#xff0c;接下来十来分钟把事情做完。下次遇到这个同样的问题的时候&#xff0c;可能是几个月后&#xff0c;甚至是几年以后了。这些技…...

【BI】FineBI功能学习路径-20231211

FineBI功能学习路径 https://help.fanruan.com/finebi/doc-view-1757.html 编辑数据概述 1.1 调整数据结构 1.2 简化数据 2.1上下合并 2.2其他表添加列 2.3左右合并 新增分析指标 函数参考 https://help.fanruan.com/finereport/doc-view-1897.html 数值函数 日期函数 文…...

pytorch之torch.utils.data学习

1、概述 PyTorch 数据加载利用的核心是torch.utils.data.DataLoader类 。它表示在数据集上 Python 可迭代&#xff0c;支持 map-style and iterable-style datasets&#xff08;地图样式和可迭代样式数据集&#xff09;&#xff0c; customizing data loading order&#xff…...

Spring Boot 3中一套可以直接用于生产环境的Log4J2日志配置

文章目录 一 Log4J2 相关概念及基本特点二 Spring Boot3 中启用Log4J2的pom.xml配置三 application.properties 的配置四 完整配置 一 Log4J2 相关概念及基本特点 Log4J2是Apache Log4j的升级版&#xff0c;参考了logback的一些优秀的设计&#xff0c;并且修复了一些问题&…...

iOS按钮控件UIButton使用

1.在故事板中添加按钮控件,步聚如下: 同时按钮Shift+Commad+L在出现在控件库中选择Button并拖入View Controller Scene中 将控件与变量btnSelect关联 关联后空心变实心 如何关联?直接到属性窗口拖按钮变量到控件上,出现一条线,然后松开,这样就关联成功了 关联成功后属性窗口…...

小程序开发实战案例之三 | 小程序底部导航栏如何设置

小程序中最常见的功能就是底部导航栏了&#xff0c;今天就来看一下怎么设置一个好看的导航栏&#xff5e;这里我们使用的是支付宝官方小程序 IDE 做示范。 官方提供的底部导航栏 第一步&#xff1a;页面创建 一般的小程序会有四个 tab&#xff0c;我们这次也是配置四个 tab 的…...

Android : 序列化 JSON简单应用

1. JSON介绍 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于阅读和写入&#xff0c;同时也易于机器解析和生成。它基于JavaScript的子集&#xff0c;采用完全独立于语言的文本格式来存储和表示数据。JSON是纯文本&#x…...

Java小案例-RocketMQ的11种消息类型,你知道几种?(普通消息和批量消息)

前言 这篇给大家讲普通消息和批量消息&#xff0c;主要配合代码进行讲解&#xff0c;关于RocketMQ的基础知识已经在上篇给大家讲过需要回顾的点击下面这个链接去看 RocketMQ基础知识 普通消息 普通消息其实就很简单&#xff0c;是Apache RocketMQ中最基础的消息形式&#x…...

前端小技巧: 设计一个简版前端统计 SDK

统计 sdk 如何设计 1 ) 概述 客户端一个sdk &#xff0c;把数据发送给服务端(第三方统计平台)服务端产生一个统计的报表 2 &#xff09;需求点 访问量&#xff1a;pv自定义事件&#xff1a;用户的一切行为我们都可以自定义采集性能&#xff0c;错误 3 ) 代码实现 const P…...

DevOps搭建(十一)-Jenkins容器内部使用Docker详解

1、目的 配置的目的是使得Jenkins容器可以直接使用宿主机的Docker,从而可以直接使用Docker命令进行本地打包操作,然后推送到Harbor镜像仓库。 2、修改数据卷 如何在docker中执行宿主机的docker操作,我们管它叫docker in docker。 至于为什么要在docker中操作宿主机的doc…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

Caliper 配置文件解析:config.yaml 和 fisco-bcos.json 附加在caliper中执行不同的合约方法

Caliper 配置文件解析:config.yaml 和 fisco-bcos.json Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO…...

CSS(2)

文章目录 Emmet语法快速生成HTML结构语法 Snipaste快速生成CSS样式语法快速格式化代码 快捷键&#xff08;VScode&#xff09;CSS 的复合选择器什么是复合选择器交集选择器后代选择器(重要)子选择器(重要&#xff09;并集选择器(重要&#xff09;**链接伪类选择器**focus伪类选…...

跑通 TrackNet-Badminton-Tracking-tensorflow2 项目全记录

&#x1f4dd; 跑通 TrackNet-Badminton-Tracking-tensorflow2 项目全记录 git clone https://github.com/Chang-Chia-Chi/TrackNet-Badminton-Tracking-tensorflow2.git TrackNet-Badminton-Tracking-tensorflow2 conda create --prefix /cloud/TrackNet-Badminton-Tracking-…...