通过java将数据导出为PDF,包扣合并单元格操作
最近项目中需要将查询出来的表格数据以PDF形式导出,并且表格的形式包含横向行与纵向列的单元格合并操作,导出的最终效果如图所示:
首先引入操作依赖
<!--导出pdf所需包--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.10</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>
最上面的基本信息是固定死的就是4*4的表格,这个创建起来 就比较简单,主要是下面这个表格,需要从数据库查出数据并循环进行展示,并且内容相同的列要进行合并。直接展示代码:
主类对外调用方法:
@Operation(summary = "导出PDF")@PostMapping("/download")@SneakyThrows(Exception.class)public void download(Long id,HttpServletResponse response, HttpServletRequest request) {// 防止日志记录获取session异常request.getSession();// 设置编码格式response.setContentType("application/pdf;charset=UTF-8");response.setCharacterEncoding("utf-8");String fileName = URLEncoder.encode("调试PDF", "UTF-8");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");contractDemandThreeRequestBaseService.download(id,response);}
具体实现类:
@Overridepublic void download(Long id, HttpServletResponse response) {//要下载的数据查询数据部分我去掉了有需要自己根据业务取ContractDemandThreeRequestBaseDO baseDO = contractDemandThreeRequestBaseMapper.selectById(id);ContractDemandThreeRequestBaseRespVO base = ContractDemandThreeRequestBaseConvert.INSTANCE.convert(baseDO);base.setDeptName(ObjectUtil.isEmpty(deptService.getDept(base.getDeptId())) ? null : deptService.getDept(base.getDeptId()).getName());base.setProjectLeaderName(ObjectUtil.isEmpty(userService.getUser(base.getProjectLeaderId())) ? null : userService.getUser(base.getProjectLeaderId()).getNickname());//子表数据List<ContractDemandThreeQuestionDO> details = contractDemandThreeQuestionMapper.selectList(Wrappers.lambdaQuery(ContractDemandThreeQuestionDO.class).eq(ContractDemandThreeQuestionDO::getDemandId, id));//下面进行表格的创建、字体设置、合并单元格// 定义全局的字体静态变量Font titlefont;Font headfont;Font keyfont = null;Font textfont = null;Font content = null;BaseFont bfChinese = null;// 最大宽度try {// 不同字体(这里定义为同一种字体:包含不同字号、不同style)这里我用的最后一个 content字体bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);titlefont = new Font(bfChinese, 16, Font.BOLD);headfont = new Font(bfChinese, 14, Font.BOLD);keyfont = new Font(bfChinese, 10, Font.BOLD);textfont = new Font(bfChinese, 15, Font.NORMAL);content = new Font(bfChinese, 10, Font.NORMAL);} catch (Exception e) {e.printStackTrace();}BaseFont bf;Font font = null;try {//创建字体bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);//使用字体并给出颜色font = new Font(bf, 20, Font.BOLD, BaseColor.BLACK);} catch (Exception e) {e.printStackTrace();}Document document = new Document();try {PdfWriter pdfWriter = PdfWriter.getInstance(document, response.getOutputStream());//打开生成的pdf文件document.open();//设置内容Paragraph paragraph = new Paragraph("采购需求三问", font);paragraph.setAlignment(1);//引用字体document.add(paragraph);// 设置表格的列宽和列数float[] widths = {25f, 25f, 25f, 25f};PdfPTable table = new PdfPTable(widths);table.setSpacingBefore(20f);// 设置表格宽度为100%table.setWidthPercentage(100.0F);table.setHeaderRows(1);table.getDefaultCell().setHorizontalAlignment(1);PdfPCell cell = null;//第一行:表格的名字cell = new PdfPCell(new Paragraph("采购项目名称", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);//表格里面的值(下面都是同样的操作)cell = new PdfPCell(new Paragraph(base.getProjectName(), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);//第二行cell = new PdfPCell(new Paragraph("项目编号", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(base.getProjectCode(), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("资金类型", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(getDitcValue("FundType", base.getFundType()), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);//第三行cell = new PdfPCell(new Paragraph("支出类别", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(getDitcValue("ExpenditureCategory", base.getExpenditureCategory()), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("预算含税总金额(万元)", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(String.valueOf(base.getBudgetIncludingTaxTotalMoney()), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);//第三行cell = new PdfPCell(new Paragraph("采购内容", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(base.getProcureContent(), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);//第四行cell = new PdfPCell(new Paragraph("需求部门", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(base.getDeptName(), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("项目负责人", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(base.getProjectLeaderName(), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);// 设置表格的列宽和列数float[] widths2 = {25f, 25f, 25f};PdfPTable table2 = new PdfPTable(widths2);table2.setSpacingBefore(20f);// 设置表格宽度为100%table2.setWidthPercentage(100.0F);table2.setHeaderRows(1);table2.getDefaultCell().setHorizontalAlignment(1);//需求三问详情信息标题栏cell = new PdfPCell(new Paragraph("需求三问", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(20);table2.addCell(cell);cell = new PdfPCell(new Paragraph("选择项", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);cell = new PdfPCell(new Paragraph("内容项", content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);//下面的代码就是样图中底下的表格,需要动态构建数据//人员列表数据-第五行List<List<String>> doList = new ArrayList<>();if (CollectionUtils.isNotEmpty(details)) {//组装数据for (ContractDemandThreeQuestionDO detail : details) {String natureType = "项目" + getDitcValue("QuestionType", detail.getDemandNatureType());String deviceGoodsType = getDitcValue(baseDO.getModelType(), detail.getItemValue());doList.add(Arrays.asList(natureType, deviceGoodsType, detail.getItemContent()));}makeData(doList, content, table2);//为两个表格添加标题document.add(new Paragraph("\n"));document.add(new Paragraph("▋ 基本信息", content));document.add(new Paragraph("\n"));document.add(table);document.add(new Paragraph("\n"));document.add(new Paragraph("▋ 采购需求三问内容", content));document.add(new Paragraph("\n"));//将table2中数据相同的列合并单元格(横向合并)document.add(table2);// 加水印(水印组成:下载人姓名-手机号-部门)PdfContentByte waterMar = pdfWriter.getDirectContentUnder();AtomicReference<String> text = new AtomicReference<>("");Long loginUserId = getLoginUserId();AdminUserRedisVO adminUserRedisVO = adminUserRedisDAO.get(loginUserId);Optional.ofNullable(adminUserRedisVO).ifPresent(vo -> {DeptDO dept = deptService.getDept(adminUserRedisVO.getDeptId());String deptName = Objects.nonNull(dept) ? dept.getName() : "";text.set(vo.getNickname() + "-" + vo.getMobile() + "-" + deptName);});addTextFullWaterMark(waterMar, text.get(), bfChinese);//关闭文档document.close();} catch (DocumentException | IOException e) {e.printStackTrace();log.error("导出pdf失败:{}", e);}}
补充说明:List<List<String>> doList = new ArrayList<>();
这个是我构建底下表格数据的格式,举个例子,类似于:
List<List<String>> headList = new ArrayList<>(); headList.add(Arrays.asList(new String[]{"1", "2", "3"})); headList.add(Arrays.asList(new String[]{"2", "6", "10"})); headList.add(Arrays.asList(new String[]{"1", "12", "13"})); headList.add(Arrays.asList(new String[]{"2", "9", "11"})); headList.add(Arrays.asList(new String[]{"1", "8", "12"}));
根据自己的实际业务构建,我底下的表格是一个n*3的表格,只有三列,所以数据结构就相当于上面的两层List结构,最外层的集合代表有多少行,嵌套的结合相当于多少列(这里就是三列),我将对象集合查询出来后使用循环,将我所用到的数据组装成这个示例的样子。
重点来了,以下是合并单元格的方法:
makeData(doList, content, table2);
/*** 合并单元格方法** @param list 表头数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并* @param fontChinese 支持转换中文的Font对象* @return*/private void makeData(List<List<String>> list, Font fontChinese, PdfPTable table2) {List<List<PdfPCell>> aa = new ArrayList<>();int length = list.get(0).size();//循环在外层,这里代表的是有几列(其实是固定的,因为上面构建的时候,列数就是三列)//下面的循环不用管,是将你组装的数据设置到单元格里for (int i = 0; i < list.size(); i++) {List<String> strings = list.get(i);int colNum = 1;List<PdfPCell> bb = new ArrayList<>();for (int j = 0; j < strings.size(); j++) {if (j + 1 < strings.size()) {if (strings.get(j).equals(strings.get(j + 1))) {colNum++;} else {PdfPCell cell = new PdfPCell();//合并列cell.setColspan(colNum);Paragraph elements = new Paragraph(strings.get(j), fontChinese);elements.setAlignment(1);cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);cell.addElement(elements);bb.add(cell);for (int a = 1; a < colNum; a++) {bb.add(null);}colNum = 1;}} else {PdfPCell cell = new PdfPCell();cell.setColspan(colNum);Paragraph elements = new Paragraph(strings.get(j), fontChinese);cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);elements.setAlignment(1);cell.setFixedHeight(30);cell.addElement(elements);bb.add(cell);for (int a = 1; a < colNum; a++) {bb.add(null);}colNum = 1;}}aa.add(bb);}//合并算法for (int i = 0; i < length; i++) {int rowSpan = 1;for (int j = 0; j < aa.size(); j++) {if (aa.get(j).get(i) == null) {continue;}if (j + 1 < aa.size()) {if (aa.get(j + 1).get(i) != null&& aa.get(j).get(i).getCompositeElements().get(0).toString().equals(aa.get(j + 1).get(i).getCompositeElements().get(0).toString())) {rowSpan++;} else {aa.get(j - rowSpan + 1).get(i).setRowspan(rowSpan);for (int a = 1; a < rowSpan; a++) {aa.get(j - rowSpan + 1 + a).set(i, null);}rowSpan = 1;}} else {aa.get(j - rowSpan + 1).get(i).setRowspan(rowSpan);for (int a = 1; a < rowSpan; a++) {aa.get(j - rowSpan + 1 + a).set(i, null);}rowSpan = 1;}}break;}for (List<PdfPCell> a : aa) {for (PdfPCell pCell : a) {if (pCell != null) {table2.addCell(pCell);}}}}
这里将合并算法进行一个说明:外层循环其实还就是表示列,我这里是三列,他会依次循环三列,并将横向与纵向的表格中有相同数据的都进行合并,也就是值相同的行进行合并,值相同的列也进行合并。但我的业务要求就是只合并第一列,所以我这里也没有改算法,偷了个懒,直接在第一次循环后加了break,直接终止后面的循环。这个自己看自己的业务要求。代码里的getDictValue方法是我自己获取字典值的方法,可自行定义
加水印:
public static void addTextFullWaterMark(PdfContentByte waterMar, String text, BaseFont bf) {waterMar.beginText();PdfGState gs = new PdfGState();// 设置填充字体不透明度为0.2fgs.setFillOpacity(0.2f);waterMar.setFontAndSize(bf, 20);// 设置透明度waterMar.setGState(gs);// 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度for (int x = 0; x <= 900; x += 200) {for (int y = -50; y <= 800; y += 200) {waterMar.showTextAligned(Element.ALIGN_RIGHT, text, x, y, 35);}}// 设置水印颜色waterMar.setColorFill(BaseColor.GRAY);//结束设置waterMar.endText();waterMar.stroke();}
这个操作PDF的类很强大,基本上你想怎么导出,都可以进行调整
相关文章:

通过java将数据导出为PDF,包扣合并单元格操作
最近项目中需要将查询出来的表格数据以PDF形式导出,并且表格的形式包含横向行与纵向列的单元格合并操作,导出的最终效果如图所示: 首先引入操作依赖 <!--导出pdf所需包--><dependency><groupId>com.itextpdf</groupId&…...
Java内存模式以及volatile关键字的使用
1.Java内存模型 (1)Java 内存模型(Java Memory Model,简称 JMM),它是一个抽象的概念,JMM是和多线程相关的,它是一组规范,描述了一组规则,定义了多线程对共享…...

每日5题Day3 - LeetCode 11 - 15
每一步向前都是向自己的梦想更近一步,坚持不懈,勇往直前! 第一题:11. 盛最多水的容器 - 力扣(LeetCode) class Solution {public int maxArea(int[] height) {//这道题比较特殊,因为两边是任意…...

路由器、交换机和网卡
大家使用VMware安装镜像之后,是不是都会考虑虚拟机的镜像系统怎么连上网的,它的连接方式是什么,它ip是什么? 路由器、交换机和网卡 1.路由器 一般有几个功能,第一个是网关、第二个是扩展有线网络端口、第三个是WiFi功…...

腾讯开源混元DiT文生图模型,消费级单卡可推理
节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接…...
shell脚本基础(if/else结构)
命令是双向选择语句,当用户执行脚本时如果不满足if后的表达式也会执行else后的命令,所以有很好的交互性。其结构为: if expression1 then command … command else command … command fi vim ifelse_exam.sh #ifelse_exam.sh #!/bin/bashec…...

万字长文破解 AI 图片生成算法-Stable diffusion (第一篇)
想象一下:你闭上眼睛,脑海中构思一个场景,用简短的语言描述出来,然后“啪”的一声,一张栩栩如生的图片就出现在你眼前。这不再是科幻小说里才有的情节,而是Stable Diffusion——一种前沿的AI图片生成算法—…...

Linux---编辑器vim的认识与简单配置
前言 我们在自己的电脑上所用的编译软件,就拿vs2022来说,我们可以在上面写C/C语言、python、甚至java也可以在上面进行编译,这种既可以用来编辑、运行编译,又可以支持很多种语言的编译器是一种集成式开发环境,集众多于…...
lucene中Collector类、CollectorManager类区分和用法
我的lucene版本是9.10.0,请说明Collector类、CollectorManager类区分和用法,尽量详细点 在 Lucene 9.10.0 中,Collector 类和 CollectorManager 类都是用于搜索结果的收集和处理 Collector 类 Collector 类是一个接口,用于收集…...

Android之给Button上添加按压效果
一、配置stateListAnimator参数实现按压效果 1、按钮控件 <Buttonandroid:id"id/mBtnLogin"android:layout_width"match_parent"android:layout_height"48dp"android:background"drawable/shape_jfrb_login_button"android:state…...
python EEL + vue3.js 项目中如何把组件中的函数提升为全局函数
eel官方示例中暴露的js函数是全局函数,vue中的自定义函数作用域通常都是组件范围内。要让eel.js调用,需要将其升为全局可用。 一般方法有 app.config.globalProperties 或 mixin等。 main.js //main.jsimport { createApp } from vue import App from…...

sqli-labs靶场第十四关
目录 1:分析 找闭合符: 2:开始注入 报错注入: 注入数据库名: 注入表名: 注入列名: 注入具体值: 1:分析 经过我们的实验发现当我们输入的密码后面存在双引号时会报…...

【C语言】6.C语言VS实用调试技巧(1)
文章目录 1.什么是 bug2.什么是调试(debug)?3.Debug 和 Release4.VS调试快捷键4.1 环境准备4.2 调试快捷键 5.监视和内存观察5.1 监视5.2 内存 1.什么是 bug bug现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题…...
AIGC行业现在适合进入吗
人工智能、物联网、基因编辑和量子计算等新兴技术领域正在以前所未有的速度发展,这些技术的结合正在重塑我们的世界。在这个充满机遇和挑战的时代,AIGC(人工智能、基因编辑和量子计算)行业备受关注,许多人都在考虑是否…...

ubuntu CUDA 驱动更新,版本更新,多CUDA版本管理
1 新版本驱动下载 前面介绍过window CUDA驱动更新,但是对于ubuntu 的驱动更新,没有一键操作。 本人笔记本电脑n年前装的CUDA DRIVER仅支持到cuda10.2,实在无法满足这日新月异的科技更新。 左 旧的驱动版本 右 新下载的硬件支持的驱动版本&…...

effective python学习笔记_类与接口
用组合类实现多层结构而不用内置类型 例子:成绩单,存储学生各科成绩多个然后加权重,如果用字典类型会导致字典有多层嵌套结构 思想 当用内置类型如字典元组等结构出现超过二层的多层嵌套结构时,读起来会比较难懂,此时…...

如何去除字符串两侧的空白字符?
TRIM函数会去掉字符串左侧和右侧的空格,语法是:TRIM(字符串) excel中,TRIM函数能去掉字符串左侧和右侧的空格,它的ASCII码是32。 以下设定一个字符串组合,它的第一个字符中空格,最后一个字符是换行符 &q…...
Flutter 中的 PageStorage 小部件:全面指南
Flutter 中的 PageStorage 小部件:全面指南 在Flutter中,PageStorage小部件提供了一种方法来保存和恢复页面间的信息,这对于具有多个页面且需要在这些页面之间共享状态的应用程序非常有用。本文将详细介绍PageStorage的用途、如何使用它以及…...

头歌实践教学平台:CG1-v2.0-直线绘制
第1关:直线光栅化-DDA画线算法 一.任务描述 1.本关任务 (1)根据直线DDA算法补全line函数,其中直线斜率0<k<1; (2)当直线方程恰好经过P(x,y)和T(x,y1)的中点M时,统一选取直线上方的T点为显示的像素点。 2.输入 (1)直线两…...

Nacos+GateWay 搭建微服务架构
文章目录 1.当前项目架构分析1.请求多个模块的方式1.请求renren-fast模块开发环境生产环境 2.请求sunliving-commodity模块1.使用环境变量资源路径的方式2.开发环境 dev.env.js3.生产环境 prod.env.js 3.文件上传请求 sunliving-service模块1.请求后端接口(开发环境…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...