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

springboot使用xdoc-report包导出word

背景:项目需要使用xdoc-report.jar根据设置好的word模版,自动填入数据 导出word

框架使用

我的需求是我做一个模板然后往里面填充内容就导出我想要的word文件,问了下chatgpt还有百度,最后选用了xdocreport这个框架,主要它使用docx模板以及freemarker模板引擎就可以做导出,不用各种转换,而且文档demo也很齐全,虽然最新的版本已经两年没更新了!!参考文档

制作模板

模板效果图如下

文字显示

比如说,我们需要显示一些文档的元数据,例如 文档的标题,文档的时间等等可以单独显示的属性。我们可以使用一个对象来封装这些属性,现在我封装了一个Project对象

class ExportProject() {  var title: String? = null  var type: String? = null  var car: String? = null  var className: String? = null  var date: String? = null  var problem: String? = null  var range: String? = null  var signature: IImageProvider? = null  constructor(vo: DriverCheckVo) : this() {  type = vo.spec  car = vo.usageCode  className = vo.shift  date = "${vo.date?.year} 年 ${vo.date?.monthValue} 月 ${vo.date?.dayOfMonth} 日"  xproblem = vo.problemSummary  }  
}

生成word文档时,只要new一个对象实例,扔到xdocreport的context中,就可以使用啦。当然具体展示还是需要在docx模板上做特殊处理的。比如我想控制我生成的docx文件中的标题,我直接在标题处,生成一个域即可,具体操作步骤如下,(下列例子中使用了wps),另外模版的文件格式名一定是docx

step-》 将光标放在标题处-》点击插入 -》选择文档部件-》点击域-》选择邮件合并-》输入变量 ${project.title} -》 点击确定 

效果如下!

其他的地方,例如年份,也是一样 输入 变量 ${project.range}即可。这样我们就可以将需要单独显示的文字,控制在xdocreport context里面 project变量里面了,当然具体怎么取名,放在哪,都随便。

列表嵌套

上面说了一些单独显示的文字显示,那列表控制如何显示呢,比如下图

首先还是定义控制对象 

class DriverCheckData {  
/**  
* 大检查项  
*/  
var name: String? = null  /**  
* 是否有小检查项  
*/  
var hasLittleCheck: Boolean? = false  /**  
* 小检查项列表  
*/  
var items: List<DriverCheckItem>? = null  
}  class DriverCheckItem {  
/**  
* 小检查项列表  
*/  
var name: String? = null  /**  
* 序号  
*/  
var sequence: Int? = null  /**  
* 检查内容  
*/  
var content: String? = null  /**  
* 检查结果  
*/  
var result: String? = null  
}

定义了两个类,大检查项类以及小检查项类,大检查项内嵌小检查项。这样我们在输出列表数据时,只需要定义一个大检查项列表就可以展示了,因为是展示的还是文本,所以定义还是跟上面一样,使用域来关联变量,写法么,就跟mybatis,el表达式差不多。

即使用 [#list noTag as data] 这个将 notag 这个list 里面的子元素 定义变量名为 data,[/#list] 代表列表结束,就跟html的标签对一样,然后是,data的数据展示了,直接使用 ${data.name} 这样的域就可以展示data里面的属性,可以看到,我这个图里面 用的不是[#list noTag as data] ,而是加了前缀,list的结尾也加了后缀,这是为了处理docx里面的表格而做的处理。照猫画虎即可,如果不是在表格里展示,直接使用

以下案例即可

«[#list developers as developer]»Name: «${developer.name}»Mail : [${developer.mail}]Mail2 : [${developer.mail}]«[/#list]»

图片展示

例如我们展示文本,使用了域,对于图片呢,需要使用书签,如果我说的不清楚,直接看官方demo

流程如下:

step-》添加一个图片(啥图片都行)当做模板,选中图片-》点击插入-》书签-》添加书签名-》添加

这个书签名非常重要,他的名字对应了我们在context里面设置的变量。如果是单独展示,直接设置一级变量名,与书签名对应即可,但是如果是图片列表,而且我们放在对象里面,怎么办呢?使用官方示例,不用[#list noTag as data],而是在java/kotlin程序里面对该列表进行处理,使用列表名中对应的图片属性即可。详见 官方示例

代码展示

springboot加载模板实例

@Component  
@Data  
class ExportInstanceConfig(  
private val resourceLoader: ResourceLoader  
) {  
private var driverExport: IXDocReport? = null  
private var checkExport: IXDocReport? = null  
@PostConstruct  
fun init(){  
driverExport = getInstance("classpath:check.docx")  
checkExport = getInstance("classpath:driver.docx")  
}  private fun getInstance(path:String):IXDocReport{  
var inputStream :InputStream? = null  
try{  
val res = resourceLoader.getResource(path)  
inputStream = res.inputStream  
return XDocReportRegistry  
.getRegistry()  
.loadReport(  
inputStream,  
TemplateEngineKind.Freemarker  
)  
}catch (e:IOException){  
throw e  
}finally {  
inputStream?.close()  
}  
}

将导出的数据转成二进制数组

private fun exportProcess(report: IXDocReport, context: IContext): ByteArray {  val bos = ByteArrayOutputStream()  val res: ByteArray  try {  // 导入模板  report.process(context, bos)  res = bos.toByteArray()  } catch (e: IOException) {  throw e  } finally {  bos.close()  }  return res  
}

进行单独图片导出

private fun exportDriverCheckDocx(param: DriverCheckVo, title: String): ByteArray {  val report = exportInstanceConfig.getDriverExport()  val metadata = report.createFieldsMetadata()  val context = report.createContext()  val exportProject = ExportProject(param).apply { this.title = title }  // 这里是对上传的图片的base64编码 进行解码val image = param.checkPeopleDocumentary?.split(",")?.let { decoder.decode(it[1]) }  if (image != null) {  // 对应模板中,单独显示的图片metadata.addFieldAsImage("signature")  // 导出图片时,图片对应的类 的格式context.put("signature",ByteArrayImageProvider(ByteArrayInputStream(image)))  }  val noTags = param.dataList?.filter { it.hasLittleCheck == false }?.toList()  val hasTags = param.dataList?.filter { it.hasLittleCheck == true }?.toList()  context.put("project", exportProject)  context.put("noTag", noTags)  context.put("hasTag", hasTags)  return exportProcess(report, context)  
}  

图片迭代导出

private fun exportCheckDocx(param: CheckVo, title: String, range: String?): ByteArray {  val report = exportInstanceConfig.getCheckExport()  val context = report.createContext()  val metadata = report.createFieldsMetadata()  // 对带图片列表的对象进行load处理,方便模板识别metadata.load("re",CheckRecord::class.java,true)  val exportProject = ExportProject().apply {  this.title = title  this.range = range  }  val noTags = param.dataList?.filter { it.hasLittleCheck == false }?.toList()  param.recordList?.forEach { it ->  if(it.documentary!=null){  val image = it.documentary?.split(",")?.let { decoder.decode(it[1]) }  if (image != null) {  it.signature = ByteArrayImageProvider(image).apply {  this.setSize(100f,100f)  }  }  }  }  val hasTags = param.dataList?.filter { it.hasLittleCheck == true }?.toList()  context.put("project", exportProject)  context.put("noTag", noTags)  context.put("hasTag", hasTags)  // 将带图片的列表加载进上下文context.put("re", param.recordList)  return exportProcess(report, context)  
}

带图片的迭代对象定义

class CheckRecord {  
/**  
* 设备型号  
*/  
var spec: String? = null  /**  
* 车号  
*/  
var usageCode: String? = null  /**  
* 检查日期  
*/  
var checkDate: String? = null  /**  
* 检查情况  
*/  
var checkContent: String? = null  /**  
* 整改要求及完成日期  
*/  
var require: String? = null  /**  
* 检查人签名  
*/  
var documentary: String? = null  
/**  
* 图片实体  
*/  
@get:FieldMetadata(images = [ ImageMetadata(name = "signature", behaviour = NullImageBehaviour.RemoveImageTemplate) ])  
var signature: IImageProvider? = null  
}

文件压缩

因为导出docx文件有多个,要求压缩成一个压缩包,这边使用的是

<dependency>  
<groupId>org.apache.commons</groupId>  
<artifactId>commons-compress</artifactId>  
<version>1.23.0</version>  
</dependency>

代码如下,将得到的docx二进制数组转成zip

// 不同类型的文件对应不同的MIME类型  
response.apply {  characterEncoding = "UTF-8" // 设置编码字符  setHeader("Content-disposition", "attachment;filename=${URLEncoder.encode("下载文件" + ".zip", "utf-8")}")  contentType = "application/zip"  
}
val zipOutputStream = ZipArchiveOutputStream(response.outputStream) 
try {   var sequence = 0  taskExportVo.forEach {  // 实例化 ZipEntry 对象,源文件数组中的当前文件  sequence++  val date = it.date  val fileName = when (query.inspType) {  EqpInspPlanType.日常检查 ->  "${it.eqpCategoryName}${it.exportType}${date?.year}${date?.monthValue}${date?.dayOfMonth}-$sequence.docx"  EqpInspPlanType.点检员点检 -> "${it.eqpCategoryName}${it.exportType}.docx"  EqpInspPlanType.专检组专检 -> "${it.eqpCategoryName}${it.exportType}.docx"  }  zipOutputStream.putArchiveEntry(ZipArchiveEntry(fileName)) // 导出单个docx文件val data = memEqpInspCheckRecordService.exportDocx(it)  // 写入zip流data?.let { it1 -> zipOutputStream.write(it1, 0, it1.size) }  zipOutputStream.closeArchiveEntry()  }  
} catch (i: IOException) {  i.printStackTrace()  
} finally{zipOutputStream.close()
}

其他:可视化Word模板设计和导出可以使用NopReport引擎,它不依赖于poi库,直接使用Word进行模板设计。​编辑juejin.cn

附录:Java版本读取数据库数据生成word模板并压缩成Zip中返回

参考:https://juejin.cn/post/7265673876032766015

相关文章:

springboot使用xdoc-report包导出word

背景&#xff1a;项目需要使用xdoc-report.jar根据设置好的word模版&#xff0c;自动填入数据 导出word 框架使用 我的需求是我做一个模板然后往里面填充内容就导出我想要的word文件&#xff0c;问了下chatgpt还有百度&#xff0c;最后选用了xdocreport这个框架&#xff0c;主…...

电脑中所有word文件图标变白怎么恢复

电脑中的word文件图标变白&#xff0c;如下图所示&#xff1a; 解决方法&#xff1a; 1.winR-->在弹出的运行窗口中输入“regedit”(如下图所示)&#xff0c;点击确定&#xff1a; 2.按照路径“计算机\HKEY_CLASSES_ROOT\Word.Document.12\DefaultIcon”去找到“&#xff0…...

node.js如何实现双 Token + Cookie 存储 + 无感刷新机制

node.js如何实现双 Token Cookie 存储 无感刷新机制 为什么要实施双token机制&#xff1f; 优点描述安全性Access Token 短期有效&#xff0c;降低泄露风险&#xff1b;Refresh Token 权限受限&#xff0c;仅用于获取新 Token用户体验用户无需频繁重新登录&#xff0c;Toke…...

如何从 iPhone 获取照片:5 个有效解决方案

有时&#xff0c;我们在 iPhone 上积累了太多照片&#xff0c;因此有必要从 iPhone 上删除照片。无论您的设备需要更多空间&#xff0c;还是只是想备份珍贵的记忆以妥善保管&#xff0c;您都可以找到从 iPhone 上拍摄照片的有效方法。您可以选择完成任务的最佳方式。 第 1 部分…...

大模型知识

############################################################## 一、vllm大模型测试参数和原理 tempreature top_p top_k ############################################################## tempreature top_p top_k 作用&#xff1a;总体是控制模型的发散程度、多样…...

微软正式发布 SQL Server 2025 公开预览版,深度集成AI功能

微软在今年的 Build 2025 大会上正式发布了 SQL Server 2025 公开预览版&#xff0c;标志着这一经典数据库产品在 AI 集成、安全性、性能及开发者工具方面的全面升级。 AI 深度集成与创新 原生向量搜索&#xff1a;SQL Server 2025 首次将 AI 功能直接嵌入数据库引擎&#xff…...

git中,给分支打标签

1.创建标签 标签可以是轻量级标签或带注释的标签两种 轻量级标签 git tag <tag-name> 带注释的标签 git tag -a <tag-name> -m "标签信息" 2.查看标签 git tag 查看标签详细信息 git show <tag-name> 3.推送标签到远程仓库 推送指定标签…...

微软 Build 2025:开启 AI 智能体时代的产业革命

在 2025 年 5 月 19 日的微软 Build 开发者大会上&#xff0c;萨提亚・纳德拉以 "我们已进入 AI 智能体时代" 的宣言&#xff0c;正式拉开了人工智能发展的新纪元。这场汇聚了奥特曼、黄仁勋、马斯克三位科技领袖的盛会&#xff0c;不仅发布了 50 余项创新产品&#…...

k8s面试题-ingress

场景&#xff1a;我通过deployment更新pod&#xff0c;ingress是怎么把新的请求流量发送到我新的pod的&#xff1f;是怎么监控到我更新的pod的&#xff1f; 在 Kubernetes 中&#xff0c;Ingress 是一种 API 对象&#xff0c;用于管理外部访问到集群内服务的 HTTP 和 HTTPS 路…...

时间序列预测的迁移学习

在本文中&#xff0c;我们将了解如何将迁移学习应用于时间序列预测&#xff0c;以及如何在多样化的时间序列数据集上训练一次预测模型&#xff0c;之后无需训练即可在不同数据集上进行预测。我们将使用开源 Darts 库&#xff0c;仅用几行代码即可完成所有这些操作。你可以点击此…...

react中运行 npm run dev 报错,提示vite.config.js出现错误 @esbuild/win32-x64

在React项目中运行npm run dev时&#xff0c;如果遇到vite.config.js报错&#xff0c;提示esbuild/win32-x64在另一个平台中被使用&#xff0c;通常是由于依赖冲突或缓存问题导致的。解决方法是删除node_modules文件夹&#xff0c;并重新安装依赖。 如下图&#xff1a; 解决办…...

量子计算模拟:从理论到实践

量子计算作为现代物理学与计算机科学的前沿交叉领域&#xff0c;正逐渐从纯理论研究走向实际应用。本文将介绍一个基于Python的量子计算模拟框架&#xff0c;重点探讨量子比特、量子门操作以及量子态的演化等核心概念&#xff0c;并通过可视化手段直观展示量子态的特性。 量子…...

143.重排链表的尝试

listnode* p0cur,cur->nextq;p0->next有没有改变 ChatGLM 让我们逐步分析这段代码&#xff0c;看看 p0->next 是否发生了改变。 假设我们有一个链表&#xff0c;cur 是当前节点&#xff0c;q 是另一个节点。代码如下&#xff1a; 代码生成完成 C代码 首先&#…...

精准识别记忆细胞!Elabscience PE Anti-Human/Mouse CD44 抗原特异性抗体

概述 CD44 是一种广泛表达的细胞表面黏附分子&#xff0c;参与细胞迁移、炎症反应及肿瘤转移等关键生物学过程。Elabscience 推出的PE Anti-Human/Mouse CD44 Antibody [IM7]&#xff08;货号&#xff1a;E-AB-F1100D&#xff09;是一款高特异性、高灵敏度的流式抗体&#xff…...

OpenCV CUDA模块特征检测与描述------一种基于快速特征点检测和旋转不变的二进制描述符类cv::cuda::ORB

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::ORB 是 OpenCV 库中 CUDA 模块的一部分&#xff0c;它提供了一种基于快速特征点检测和旋转不变的二进制描述符的方法&#xff0c;用于…...

OpenCV CUDA模块特征检测与描述------创建一个 盒式滤波器(Box Filter)函数createBoxFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::createBoxFilter 是 OpenCV CUDA 模块中的一个工厂函数&#xff0c;用于创建一个 盒式滤波器&#xff08;Box Filter&#xff09;&…...

【八股战神篇】Spring高频面试题汇总

专栏简介 Bean 的生命周期了解么? 延伸 谈谈自己对于 Spring IoC 的了解 延伸 什么是动态代理? 延伸 动态代理和静态代理的区别 延伸 Spring AOP的执行流程 延伸 Spring的事务什么情况下会失效? 延伸 专栏简介 八股战神篇专栏是基于各平台共上千篇面经,上万道…...

高阶数据结构——红黑树实现

目录 1.红黑树的概念 1.1 红黑树的规则&#xff1a; 1.2 红黑树的效率 2.红黑树的实现 2.1 红黑树的结构 2.2 红黑树的插入 2.2.1 不旋转只变色&#xff08;无论c是p的左还是右&#xff0c;p是g的左还是右&#xff0c;都是一样的变色处理方式&#xff09; 2.2.2 单旋变色…...

java综合交易所13国语言,股票,区块链,外汇,自带客服系统运营级,有测试

这套pc和H5是一体的&#xff0c;支持测试&#xff0c;目前只有外汇和区块链&#xff0c;某站居然有人卖3.8w&#xff0c;还觉得自己这个价格很好 自带客服系统&#xff0c;虽然是老的&#xff0c;但是可玩性还是很高的&#xff0c;也支持c2c&#xff0c;理财&#xff0c;质押&a…...

六:操作系统虚拟内存之缺页中断

深入理解操作系统&#xff1a;缺页中断 (Page Fault) 的处理流程 在上一篇文章中&#xff0c;我们介绍了虚拟内存和按需调页 (Demand Paging) 的概念。虚拟内存为每个进程提供了巨大的、独立的虚拟地址空间&#xff0c;并通过页表 (Page Table) 将虚拟页面 (Virtual Page) 映射…...

iOS 15.4.1 TrollStore(巨魔商店)安装教程详解:第二篇

&#x1f680; iOS 15.4.1 TrollStore&#xff08;巨魔商店&#xff09;安装教程详解 ✨ 前言&#x1f6e0;️ 如何安装 TrollStore&#xff1f;第一步&#xff1a;打开 Safari 浏览器第二步&#xff1a;选择对应系统版本安装方式第三步&#xff1a;访问地址&#xff0c;下载配…...

【JAVA】比较器Comparator与自然排序(28)

JAVA 核心知识点详细解释 Java中比较器Comparator的概念和使用方法 概念 Comparator 是 Java 中的一个函数式接口,位于 java.util 包下。它用于定义对象之间的比较规则,允许我们根据自定义的逻辑对对象进行排序。与对象的自然排序(实现 Comparable 接口)不同,Comparat…...

bitbar环境搭建(ruby 2.4 + rails 5.0.2)

此博客为武汉大学WA学院网络安全课程&#xff0c;理论课大作业Web环境搭建。 博主搭了2天&#xff01;&#xff01;&#xff01;血泪教训是还是不能太相信ppt上的教程。 一开始尝试了ppt上的教程&#xff0c;然后又转而寻找网络资源 cs155源代码和docker配置&#xff0c;做到…...

Spring Boot接口通用返回值设计与实现最佳实践

一、核心返回值模型设计&#xff08;增强版&#xff09; package com.chat.common;import com.chat.util.I18nUtil; import com.chat.util.TraceUtil; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter;import java.io.Serializable;/*** 功能: 通…...

线上 Linux 环境 MySQL 磁盘 IO 高负载深度排查与性能优化实战

目录 一、线上告警 二、问题诊断 1. 系统层面排查 2. 数据库层面分析 三、参数调优 1. sync_binlog 参数优化 2. innodb_flush_log_at_trx_commit 参数调整 四、其他优化建议 1. 日志文件位置调整 2. 生产环境核心参数配置模板 3. 突发 IO 高负载应急响应方案 五、…...

React--函数组件和类组件

React 中的函数组件和类组件是两种定义组件的方式&#xff0c;它们有以下主要区别&#xff1a; 1. 语法与定义方式 函数组件&#xff1a; 是 JavaScript 函数&#xff0c;接收 props 作为参数&#xff0c;返回 JSX。 const MyComponent (props) > {return <div>Hell…...

GitHub 趋势日报 (2025年05月20日)

本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1virattt/ai-hedge-fundAI对冲基金团队⭐ 1781⭐ 31163Python2public-apis/pub…...

uni.getLocation()和uni.openSetting()

文章目录 环境背景问题分析问题1问题2 uni.getLocation()和uni.openSetting()的区别和联系其它uni.getLocation()的failuni.openSetting()的authSetting对象 参考 环境 Windows 11 专业版HBuilder X 4.65微信开发者工具 Stable 1.06.2412050 背景 在小程序开发中&#xff0c…...

医疗行业数据共享新实践:如何用QuickAPI打通诊疗全流程数据壁垒

在医疗行业&#xff0c;数据的高效流转直接影响诊疗效率和患者体验。某三甲医院在数字化转型中发现&#xff0c;虽然已积累大量核心业务数据&#xff0c;但各科室系统间的数据互通仍存在明显瓶颈——检验科的报告无法实时同步至门诊系统&#xff0c;药房库存数据与采购系统脱节…...

管理会议最佳实践:高效协同与价值最大化

1.会前准备:明确目标与计划 1.1 明确会议目的 1.1.1 必要性评估 开会前需自问是否真的需要开会,若问题可通过邮件、文档或异步沟通解决,则应避免开会,以节省时间和资源。 1.1.2 目标定义 清晰定义会议目标,如决策、信息同步、创意讨论等,并提前告知参与者,使大家明确参…...

万物智联,重塑未来:鸿蒙操作系统的实战突破与生态崛起

鸿蒙操作系统&#xff08;HarmonyOS&#xff09;作为华为自主研发的分布式操作系统&#xff0c;自2019年发布以来&#xff0c;已从技术探索迈入大规模商用阶段。截至2025年&#xff0c;鸿蒙系统不仅成为全球第二大移动操作系统&#xff0c;更在政企数字化、工业制造、金融科技等…...

人工智能路径:技术演进下的职业发展导航

当生成式AI能够自主完成创意设计、商业分析和代码编写时&#xff0c;职业发展的传统路径正在被重新测绘。人工智能路径不再是一条预设的直线&#xff0c;而演变为包含多重可能性的动态网络——未来的职业成功&#xff0c;将取决于在技术变革中持续定位自身价值节点的能力。 一…...

深入理解Java虚拟机之垃圾收集器篇(垃圾回收器的深入解析待完成TODO)

目录 **一. 如何判断对象的存亡**引用计数算法:可达性分析算法: **二. Java中的四种引用****三. 垃圾回收算法****1. 标记 - 清除算法****2. 标记 - 复制算法****3. 标记 - 整理算法****4. 分代收集理论**(了解即可) **四. 十种主流垃圾收集器****3.1 Serial 收集器****3.2 Par…...

牛客网 NC16407 题解:托米航空公司的座位安排问题

牛客网 NC16407 题解&#xff1a;托米航空公司的座位安排问题 题目分析 解题思路 本题可以采用深度优先搜索(DFS)来解决&#xff1a; 从左上角开始&#xff0c;按行优先顺序遍历每个座位对于每个座位&#xff0c;有两种选择&#xff1a; 选择该座位&#xff08;如果满足条件…...

拉普拉斯高斯(LoG)滤波器掩模的注意事项

目录 问题&#xff1a; 解答&#xff1a; 一、高斯函数归一化&#xff1a;消除幅度偏差 1. 归一化的定义 2. 为何必须归一化&#xff1f; 二、拉普拉斯系数和为零&#xff1a;抑制直流项干扰 1. 拉普拉斯算子的特性 2. 系数和不为零的后果 三、直流项如何影响零交叉点&…...

OSPF基础实验-多区域

互联接口、IP地址如下图所示&#xff0c;所有设备均创建Loopback0&#xff0c;其IP地址为10.0.x.x/24&#xff0c;其中x为设备编号。 R1、R3的所有接口以及R2的GE0/0/4接口属于OSPF区域2&#xff0c;R2、R4的Loopback0接口及互联接口属于OSPF区域0&#xff0c;R4、R5的互联接口…...

ERP 与 WMS 对接深度解析:双视角下的业务与技术协同

在企业数字化运营的复杂体系中&#xff0c;ERP&#xff08;企业资源规划&#xff09;与 WMS&#xff08;仓储管理系统&#xff09;的有效对接&#xff0c;已成为优化供应链管理、提升运营效率的关键环节。本文将从 ERP 和 WMS 两个核心视角出发&#xff0c;深度剖析两者对接过程…...

基于 Node.js 的 HTML 转 PDF 服务

这是一个基于 Node.js 开发的 Web 服务&#xff0c;主要功能是将 HTML 内容转换为 PDF 文件。项目使用了 Express 作为 Web 框架&#xff0c;Puppeteer 作为 PDF 生成引擎&#xff0c;提供了简单易用的 API 接口。前端开发人员提供了一个简单而强大的 HTML 转 PDF 解决方案&…...

Java阻塞队列(BlockingQueue)的使用:ArrayBlockingQueue类、LinkedBlockingQueue类

1、阻塞队列的介绍 Java 中的阻塞队列(BlockingQueue)‌ 是多线程编程中用于协调生产者和消费者线程的重要工具,属于 java.util.concurrent 包。它的核心特点是:‌当队列为空时,消费者线程会被阻塞,直到队列中有新元素;当队列满时,生产者线程会被阻塞,直到队列有空闲…...

esp32cmini SK6812 2个方式

1 #include <SPI.h> // ESP32-C系列的SPI引脚 #define MOSI_PIN 7 // ESP32-C3/C6的SPI MOSI引脚 #define NUM_LEDS 30 // LED灯带实际LED数量 - 确保与实际数量匹配&#xff01; #define SPI_CLOCK 10000000 // SPI时钟频率 // 颜色结构体 st…...

2025年 PMP 6月 8月 专题知识

2025年 PMP 6月 8月 专题知识 文章目录 2025年 PMP 6月 8月 专题知识三点估算1. 概念:2. 原理: 决策树1. 概念:2. 步骤: 真题 三点估算 1. 概念: 三点估算常用于估算活动持续时间&#xff08;也可以用于估算成本&#xff09;&#xff1b;源自计划评审技术&#xff08;PERT&am…...

一文理解TCP与UDP

Socket套接字 Socket套接字&#xff0c;是由系统提供用于网络通信的技术&#xff0c;是基于TCP/IP协议的网络通信的基本操作单元。 基于Socket套接字的网络程序开发就是网络编程。 Socket套接字主要针对传输层协议划分为如下三类&#xff1a; 流套接字&#xff1a;使用传输层…...

智能指针RAII

引入&#xff1a;智能指针的意义是什么&#xff1f; RAll是一种利用对象生命周期来控制程序资源&#xff08;如内存、文件句柄、网络连接、互斥量等等&#xff09;的简单技术。 在对象构造时获取资源&#xff0c;接着控制对资源的访问使之在对象的生命周期内始终保持有效&#…...

AI护航化工:《山西省危化品视频智能分析指南》下的视频分析重构安全体系

化工和危化品行业的AI智能视频分析应用&#xff1a;构建安全与效率新范式 一、行业背景与挑战 化工和危化品行业是国民经济的重要支柱&#xff0c;但生产过程涉及高温、高压、易燃易爆等高风险场景。传统安全监管依赖人工巡检和固定监控设备&#xff0c;存在效率低、盲区多、…...

GitHub SSH Key 配置详细教程(适合初学者,Windows版)-学习记录4

GitHub SSH Key 配置详细教程&#xff08;适合初学者&#xff0c;Windows版&#xff09; 本教程适用于在 Windows 系统下&#xff0c;将本地 Git 仓库通过 SSH 方式推送到 GitHub&#xff0c;适合没有配置过 SSH key 的初学者。 1. 检查是否已有 SSH key 打开 Git Bash 或 Po…...

初识Linux · NAT 内网穿透 内网打洞 代理

目录 前言&#xff1a; 内网穿透和打洞 NAPT表 内网穿透 内网打洞 正向/反向代理 前言&#xff1a; 本文算是网络原理的最后一点补充&#xff0c;为什么说是补充呢&#xff0c;因为我们在前面第一次介绍NAT的时候详细介绍的是报文从子网到公网&#xff0c;却没有介绍报文…...

docker-compose使用详解

Docker-Compose 是 Docker 官方提供的容器编排工具&#xff0c;用于简化多容器应用的定义、部署和管理。其核心功能是通过 YAML 配置文件&#xff08;docker-compose.yml&#xff09;定义服务、网络和存储卷&#xff0c;并通过单一命令实现全生命周期的管理。以下从核心原理、安…...

使用计算机视觉实现目标分类和计数!!超详细入门教程

什么是物体计数和分类 在当今自动化和技术进步的时代&#xff0c;计算机视觉作为一项关键工具脱颖而出&#xff0c;在物体计数和分类任务中提供了卓越的功能。 无论是在制造、仓储、零售&#xff0c;还是在交通监控等日常应用中&#xff0c;计算机视觉系统都彻底改变了我们感知…...

并发编程中的对象组合的哲学

文章目录 引言对象组合与安全委托实例封闭技术基于监视器模式的对象访问对象不可变性简化委托原子维度的访问现有容器的并发安全的封装哲学使用继承使用组合小结参考引言 本文将介绍通过封装技术,保证开发者不对整个程序进行分析的情况下,就可以明确一个类是否是线程安全的,…...

03-Web后端基础(Maven基础)

1. 初始Maven 1.1 介绍 Maven 是一款用于管理和构建Java项目的工具&#xff0c;是Apache旗下的一个开源项目 。 Apache 软件基金会&#xff0c;成立于1999年7月&#xff0c;是目前世界上最大的最受欢迎的开源软件基金会&#xff0c;也是一个专门为支持开源项目而生的非盈利性…...