通过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.请求后端接口(开发环境…...

【2024华为HCIP831 | 高级网络工程师之路】刷题日记(18)
个人名片:🪪 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:&a…...

在抖音做电商,没有货源,不懂直播怎么办?分享一种解决方案!
大家好,我是电商糖果 糖果做电商的时间也挺久了,天猫,京东,闲鱼都搞过。 从学校进入社会工作,创业,一直都是围绕电商打转。 做的时间久了,好像只会做这一件事儿了。 2020年开始专攻抖音小店&…...

基于单片机的智能安防系统设计(32+4G+WIFI版)-设计说明书
设计摘要: 本设计基于STM32单片机,旨在实现一个智能安防系统,主要包括烟雾和温度传感器、人体红外传感器、显示屏、按键、4G模块和WiFi模块等组件。通过这些组件的协作,实现了火灾检测、入侵监测、状态显示、用户交互和远程通信等…...

云服务器配置mysql允许被远程连接从而使用图形化界面
介绍 在云服务器上搭建和配置数据库是进行网站和应用开发的关键步骤之一。本文将介绍如何在云服务器上设置 MySQL 8 和 MySQL 5,以允许远程连接,从而让你的数据库能够被远程用户访问。这样你的本机就可以访问linux服务器上的mysql能,就可以使…...

【软件测试】需求概念|软件的⽣命周期|开发模型|测试模型
目录 推荐 一、什么是需求 1.1 ⽤⼾需求 1.2 软件需求 二、开发模型 2.1 什么是“模型” 2.2 软件的⽣命周期 2.3 常⻅开发模型 2.3.1 瀑布模型 2.3.2 螺旋模型 2.3.3 增量模型、迭代模型 2.3.4 敏捷模型 2.4 测试模型 2.4.1 V模型 2.4.2 W模型(双V模型࿰…...

SQL中的LAG函数与LEAD函数用法
LAG:函数用于获取结果集中当前行之前的某一行的值 LAG (scalar_expression [,offset] [,default]) OVER ([partition_by_clause ] order_by_clause ) -----汉字解释 LAG (字段 [,偏移量默认为1] [,如果没有值时候默认值]) OVER ( [ partition_by 字段 ] order_by 字…...

数据结构------二叉树经典习题1
博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1判断相同的树 OJ链接 这道题相对简单,运用我们常规的递归写法就能轻松写出 所以我们解题思路应该这样想: 1.如果p为空,q为空,那么就是两颗空树肯定相等 2.如果一个树为空另一棵树不为空那么…...

汇聚荣:拼多多长期没有流量如何提高?
在电商的海洋中,拼多多以其独特的团购模式吸引了众多消费者的目光。然而,随着市场竞争的加剧和消费者需求的多样化,一些商家发现自家店铺的流量持续低迷,销售业绩难以突破。面对这样的挑战,如何有效提升拼多多店铺的客…...

Chrome的常用操作总结
Chrome的常用操作总结 最近的自己真的好忙啊,好久真好久没有写博客了,今天我就趁着周末的这段时间总结一下最近自己的用的Chrome浏览器常用的命令 不得不说: 就是特么的丝滑!吊打一切浏览器(不接受反驳哈哈哈)因为反驳我也不听嘻嘻 用好快捷键,就是事半功倍!!!重要的事儿说一遍…...

dvwa靶场 JavaScript Attacks(js攻击)全难度教程(附代码分析)
JS简介 一种解释型语言(代码不需要编译),一般镶嵌在html或者php中实现。 JavaScript Attacks(Security Level: low) 代码分析 <?php $page[ body ] . <<<EOF <script>/* MD5 code from here h…...