Java Word占位符替换:Apache POI与docx4j选型及跨run处理避坑指南
1. 为什么“替换Word占位符”这件事远比想象中麻烦做过Java后端的人几乎都绕不开一个需求生成一份格式规范的Word文档。合同、通知书、报表、简历、项目验收单业务方给过来的永远是一个排版精美的.docx模板里面写着${userName}、{{date}}、#amount#这类占位符然后要求程序把数据填进去输出一份“看起来跟手工做的一模一样”的文件。第一次接到这种需求很多人的第一反应是不就是字符串替换吗把docx当zip解开找到document.xml读出来replace一下再塞回去收工。我当年也是这么想的直到被现实按在地上摩擦了好几轮。问题在于Word文档的底层结构根本不是“一段连续的文本”。你在Word里看到的一行${userName}在document.xml里可能被拆成了好几个w:rrun节点中间还夹杂着拼写检查标记、语言属性、字体切换、修订记录。比如${user在一个run里Name}在另一个run里你直接对整个XML字符串做替换根本匹配不到。更坑的是模板里如果有表格、页眉页脚、文本框、批注占位符可能散落在header1.xml、footer1.xml、footnotes.xml等好几个部件里只处理document.xml必然漏掉。所以这个需求的核心难点从来不是“替换”这个动作而是如何在保留原有格式的前提下准确地定位并替换跨节点、跨部件的占位符。这也是为什么社区里反复出现两个名字Apache POI和docx4j。它们代表了两种截然不同的技术路线选错了后面全是坑选对了很多问题会迎刃而解。这篇内容我打算把这两条路线彻底讲透它们各自的底层模型是什么、什么场景该用哪个、跨run占位符到底怎么处理、页眉页脚和表格怎么覆盖、性能上有什么差异以及我在实际项目里踩过的那些“文档能打开但格式全乱”“替换后字体变了”“循环表格行不会复制”的真实问题。如果你正在做或者即将做Word模板填充这篇可以当作一份避坑地图来用。2. 先搞懂docx的“零件结构”否则选型全靠猜2.1 docx本质是一个装着XML的压缩包不管用POI还是docx4j第一步都得建立正确的心理模型一个.docx文件就是一个ZIP包把后缀改成.zip解压你会看到这样的目录结构word/ document.xml // 正文主体 header1.xml // 页眉 footer1.xml // 页脚 footnotes.xml // 脚注 styles.xml // 样式定义 numbering.xml // 编号定义 media/ // 图片资源 [Content_Types].xml正文里你看到的每一个字符都藏在document.xml的w:t标签里而w:t又被w:rrun包裹w:r再往上归w:pparagraph管。run是格式的最小单位——同一段文字里只要字体、字号、颜色、加粗有任何一处不同Word就会把它拆成多个run。这就解释了那个经典现象模板里明明写的是${name}代码里document.xml打开一看却是w:rw:t${na/w:t/w:r w:rw:tme}/w:t/w:r为什么会被拆开因为你在Word里编辑的时候可能中途改过字体或者输入法切换导致Word自动分段甚至只是光标移动过Word就悄悄拆了run。这是Word的正常行为不是bug但对做替换的程序来说就是灾难。2.2 占位符可能藏在哪些“角落”很多人只处理document.xml结果测试时发现正文替换成功了但页眉里的公司名没变、表格里的金额没变、页脚页码旁边的日期没变。原因就是占位符散落在多个部件里。我整理了一张常见位置对照表占位符位置所在XML部件容易漏掉的原因正文段落document.xml基本都会处理页眉header1.xml等常被忽略页脚footer1.xml等常被忽略表格单元格document.xml内跨run问题更严重文本框document.xml内结构特殊遍历易漏脚注/尾注footnotes.xml几乎没人处理批注comments.xml特殊场景才需要提示一个docx里可能有多个header和footer首页不同、奇偶页不同命名是header1.xml、header2.xml……处理时要用通配匹配不能写死。理解了这层结构你就能明白任何“读字符串直接replace”的方案都是不可靠的因为你要面对的是树形结构而不是纯文本。接下来看POI和docx4j分别怎么应对这个树。3. Apache POI的XWPF模型轻量、直接但跨run要自己动手3.1 POI处理docx的核心类Apache POI对.docx的支持集中在XWPF系列类里常用的几个XWPFDocument整个文档对象入口。XWPFParagraph段落。XWPFRun段落里的run真正装文本的地方。XWPFTable/XWPFTableRow/XWPFTableCell表格三件套。XWPFHeader/XWPFFooter页眉页脚。POI的API设计很“Java”直观、上手快。替换正文占位符的基本思路是遍历所有段落遍历段落里所有run拿到文本做替换。但正如前面说的占位符可能跨run所以不能逐个run替换必须先把整段的文本拼起来判断再回填。3.2 跨run占位符的处理合并-替换-回填这是POI方案里最核心的一段逻辑我把它拆成三步讲清楚。第一步把段落里所有run的文本拼成一个完整字符串。用paragraph.getText()就能拿到整段文本它内部会把所有run的w:t拼起来。这一步解决了“占位符被拆开”的定位问题。第二步在完整字符串上做正则匹配找出所有占位符及其位置。比如用\$\{([^}])\}匹配${xxx}格式。第三步把替换后的文本重新写回run。这里有个关键取舍如果占位符恰好落在单个run里直接改那个run的文本最安全格式完全不动如果跨了多个run就得把第一个run的文本设成替换结果然后把后续涉及的run文本清空。public void replaceInParagraph(XWPFParagraph paragraph, MapString, String data) { ListXWPFRun runs paragraph.getRuns(); if (runs null || runs.isEmpty()) return; // 拼接整段文本同时记录每个字符属于哪个run StringBuilder fullText new StringBuilder(); Listint[] runRanges new ArrayList(); // [start, end, runIndex] for (int i 0; i runs.size(); i) { String t runs.get(i).text(); if (t null) t ; int start fullText.length(); fullText.append(t); runRanges.add(new int[]{start, fullText.length(), i}); } String text fullText.toString(); Matcher matcher Pattern.compile(\\$\\{([^}])\\}).matcher(text); if (!matcher.find()) return; // 从后往前替换避免位置偏移 Listint[] matches new ArrayList(); matcher.reset(); while (matcher.find()) { matches.add(new int[]{matcher.start(), matcher.end()}); } for (int i matches.size() - 1; i 0; i--) { int[] m matches.get(i); String key text.substring(m[0] 2, m[1] - 1); String value data.getOrDefault(key, ); // 找到覆盖该区间的run把值写进第一个其余清空 boolean first true; for (int[] range : runRanges) { if (range[1] m[0] || range[0] m[1]) continue; XWPFRun run runs.get(range[2]); if (first) { run.setText(value, 0); first false; } else { run.setText(, 0); } } } }这段代码有几个细节值得说。从后往前替换是因为替换会改变字符串长度如果从前往后后面匹配到的位置就全乱了。run.setText(value, 0)的第二个参数是位置索引传0表示从第一个字符开始覆盖这样能保留run本身的格式属性字体、颜色等只是换了文字内容。3.3 POI方案的边界表格行复制和图片替换是硬伤POI在纯文本替换上够用但遇到两个场景就很吃力。第一个是动态表格行。业务需求经常是“模板里有一行明细数据有N条就复制N行”。POI的XWPFTable没有现成的“复制行”API你得手动new一个XWPFTableRow然后逐个单元格、逐个run去复制样式和内容代码又长又容易丢格式。我见过有人为了复制一行写了上百行代码最后还是字体对不上。第二个是图片占位符。如果模板里${logo}位置要插入一张图片POI需要你手动创建XWPFRun、调用addPicture、处理图片关系ID还要保证图片尺寸和原占位符位置协调。能做但繁琐。所以POI的定位很清晰结构简单、以文本替换为主的场景它是最轻量的选择。依赖小、上手快、不引入额外概念。但一旦涉及复杂表格、图片、内容控件就该考虑docx4j了。4. docx4j的JAXB模型重但能啃硬骨头4.1 docx4j的底层是完整的OOXML对象树docx4j走的是另一条路它用JAXB把整个OOXML规范映射成了Java对象。你操作的WordprocessingMLPackage本质上就是document.xml那棵树的完整Java镜像。每个w:r对应一个R对象每个w:p对应一个P对象层级关系和XML一模一样。这个设计带来的最大好处是你能对文档结构做任何操作包括复制任意节点、深度遍历、修改任意属性。POI做不到的“复制表格行”在docx4j里就是把一个Tr对象深拷贝一份插到原位置后面几行代码搞定。代价是学习曲线陡。你得理解ObjectFactory、JAXBElement、ContentAccessor这些概念还得知道getContent()返回的列表里混着P、Tbl、R各种类型遍历时要instanceof判断。第一次用docx4j的人大概率会被JAXBElement的泛型绕晕。4.2 用docx4j做文本替换的标准姿势docx4j官方提供了一个工具类TextUtils专门用来处理跨run的文本替换这是它比POI省心的地方WordprocessingMLPackage pkg WordprocessingMLPackage.load(new File(template.docx)); MapString, String replacements new HashMap(); replacements.put(userName, 张三); replacements.put(date, 2024-01-01); TextUtils.replaceText(pkg, replacements); pkg.save(new File(output.docx));TextUtils.replaceText内部会自动处理跨run的情况把分散在多个R里的文本合并后再替换。这比POI手写合并逻辑省事得多。但要注意它的替换粒度是整个文档级别如果你的占位符有特殊格式要求比如替换后要保留某种样式可能需要自己扩展。4.3 表格行复制docx4j真正的主场动态表格是docx4j最能体现价值的地方。假设模板里有一个明细表表头下面有一行${itemName}、${qty}、${price}数据有5条需要生成5行。思路是找到表格对象Tbl。定位到模板行Tr通常是表头后的第一行。对每条数据深拷贝一份Tr替换其中的占位符插入到表格中。删除原始模板行。Tbl table findTable(pkg); ListTr rows table.getContent().stream() .filter(o - o instanceof Tr).map(o - (Tr) o) .collect(Collectors.toList()); Tr templateRow rows.get(1); // 假设第0行是表头 int insertIndex table.getContent().indexOf(templateRow); for (int i 0; i dataList.size(); i) { Tr newRow XmlUtils.deepCopy(templateRow); // 在新行里替换占位符 replaceInRow(newRow, dataList.get(i)); table.getContent().add(insertIndex i, newRow); } table.getContent().remove(templateRow);XmlUtils.deepCopy是关键它保证了新行和模板行的结构、样式完全一致。替换占位符时遍历新行里的所有R对象用TextUtils或自己写的逻辑处理即可。这套流程在POI里要费很大劲在docx4j里就是“拷贝-替换-插入”三步。4.4 docx4j的“重”体现在哪里天下没有免费的午餐。docx4j的代价是依赖体积大引入docx4j会带进来一堆JAXB、XML相关依赖打包后jar包明显变大。内存占用高整个文档树都在内存里处理几十MB的大文档时要注意堆内存。API偏底层很多操作要直接面对OOXML的类名比如CTSectPr、CTPPr不熟悉规范的人会懵。版本兼容docx4j不同版本对JDK和JAXB的要求不一样JDK 11以上要额外引入JAXB实现否则启动就报ClassNotFoundException。注意如果你的项目跑在JDK 11用docx4j前务必确认JAXB依赖是否齐全这是新手最容易卡住的地方报错信息还特别不直观。5. 两条路线的正面PK一张表看清怎么选讲完两边该做决断了。我把实际项目里最关心的几个维度拉出来对比对比维度Apache POIdocx4j学习成本低API直观高需懂OOXML依赖体积小大跨run文本替换需手写合并逻辑TextUtils直接支持表格行复制困难需手动复制样式简单deepCopy即可图片替换繁琐相对方便页眉页脚处理支持需单独遍历支持遍历headerPart大文档性能较好一般内存占用高社区活跃度高中适合场景简单文本填充复杂结构、动态表格、图片我的选型经验是这样的如果模板结构固定、只做文本替换、没有动态行用POI轻量省心如果涉及动态表格、图片插入、复杂格式保留直接上docx4j别在POI上硬扛。我见过团队为了用POI实现动态表格写了几百行复制样式的代码维护成本极高最后重构换成docx4j代码量砍掉一大半。还有一个折中方案用POI读取和保存用docx4j处理复杂结构。但两者对象模型不通用转换起来也麻烦一般不推荐混用除非你有明确的性能瓶颈需要POI来兜底。6. 页眉页脚、表格、文本框那些“替换不到”的坑怎么填6.1 页眉页脚必须单独遍历这是最高频的漏替换问题。POI里页眉页脚不在document.getParagraphs()里要单独拿for (XWPFHeader header : doc.getHeaderList()) { for (XWPFParagraph p : header.getParagraphs()) { replaceInParagraph(p, data); } } for (XWPFFooter footer : doc.getFooterList()) { for (XWPFParagraph p : footer.getParagraphs()) { replaceInParagraph(p, data); } }docx4j里则是遍历headerPart和footerPart思路类似。关键是要意识到它们和正文是平级的独立部件不能指望一次遍历全覆盖。6.2 表格单元格里的段落要递归处理表格里的文本在XWPFTableCell的段落里而单元格还可能嵌套表格。所以处理表格不能只遍历doc.getTables()要递归public void processTable(XWPFTable table, MapString, String data) { for (XWPFTableRow row : table.getRows()) { for (XWPFTableCell cell : row.getTableCells()) { for (XWPFParagraph p : cell.getParagraphs()) { replaceInParagraph(p, data); } for (XWPFTable nested : cell.getTables()) { processTable(nested, data); // 递归嵌套表格 } } } }漏掉递归嵌套表格里的占位符就永远替换不了。6.3 文本框是“隐藏关卡”文本框Text Box在OOXML里是画布结构POI的getParagraphs()默认拿不到里面的段落。需要用底层XML遍历找到w:txbxContent节点再处理。这个场景不常见但一旦模板里有文本框不处理就是明显的bug。docx4j在这方面稍好因为它的对象树更完整但同样需要专门遍历。提示拿到模板后先别急着写代码用解压工具打开docx把每个XML部件都搜一遍占位符列个清单。这样能提前发现占位符到底藏在哪避免写完代码才发现漏了页眉。7. 实测中的性能与格式问题几个真实教训7.1 替换后字体变了多半是run合并的锅前面讲跨run替换时我把替换结果写进第一个run清空后续run。如果第一个run的字体和后续run不一致替换后的文字就会用第一个run的字体视觉上和原来不一样。解决办法是替换前先确认占位符涉及的run格式是否一致如果不一致要么统一格式要么把替换结果按原run边界拆分回填。后者复杂但格式最保真适合对格式要求极高的合同类文档。7.2 大文档批量生成的内存问题docx4j把整个文档加载进内存如果一次生成几百份文档每份都new一个WordprocessingMLPackage内存会飙升。我的做法是模板只加载一次复用同一个package对象每次生成时deepCopy一份再操作。这样避免了重复解析模板的开销。POI同理XWPFDocument也可以复用模板流。7.3 并发下的线程安全XWPFDocument和WordprocessingMLPackage都不是线程安全的。多线程环境下要么每个线程独立加载模板要么用ThreadLocal缓存。我踩过一次坑多个线程共享一个document对象做替换结果生成的文档内容串了排查了半天才发现是并发写同一个对象。7.4 占位符格式不统一导致的匹配失败模板作者可能一会儿写${name}一会儿写{{name}}一会儿写#name#。代码里如果只匹配一种另一种就漏了。建议在项目规范里强制统一占位符格式或者在替换前用正则同时匹配多种格式。我一般推荐${}因为它和大多数模板引擎一致不容易和正文内容冲突。8. 一套可直接复用的替换工具设计思路把前面的经验收拢一下我通常会封装一个工具类对外只暴露一个方法传入模板路径、数据Map、输出路径内部自动处理正文、页眉、页脚、表格、嵌套表格。核心设计要点统一入口WordTemplateFiller.fill(template, data, output)。递归遍历正文段落、表格含嵌套、页眉页脚全部覆盖。跨run替换用“拼接-匹配-回填”三步法从后往前替换。格式保真优先写回单个run跨run时尽量保留首个run格式。异常兜底占位符找不到对应数据时替换为空字符串还是保留原样做成可配置。数据Map的key就是占位符里的名字value是替换值。对于动态表格可以约定一个特殊key比如items对应一个List工具内部识别后走表格复制逻辑。这样业务代码只需要准备数据不用关心底层是POI还是docx4j。如果你用的是docx4j工具类内部可以直接调TextUtils.replaceText处理文本再单独处理表格复制如果用POI就把前面那段合并替换逻辑封装进去。两条路线可以共用同一套对外接口底层实现按需切换这对后期维护很友好。最后分享一个我用了很久的调试技巧替换完成后不要只看生成的文档能不能打开一定要用解压工具再搜一遍占位符关键字。如果还能搜到${说明有地方漏替换了比肉眼翻文档靠谱得多。这个习惯帮我提前发现过好几次页眉漏替换的问题。

相关新闻

SAP-PP替代物料完全手册:策略、配置与MRP消耗顺序避坑指南

SAP-PP替代物料完全手册:策略、配置与MRP消耗顺序避坑指南

简介:这份手册面向SAP-PP模块顾问、生产计划员及物料管理相关人员,系统讲解替代物料与后继物料的配置逻辑与实操方法,帮助解决生产过程中物料短缺、切换与按比例消耗等常见难题。资源包内含1个docx文档,大小约871KB,以…

2026/10/13 12:41:45 阅读更多 →
测试工程师面试题:底层能力分析与高效准备指南

测试工程师面试题:底层能力分析与高效准备指南

如果把测试工程师的面试题当成一份题库来背,基本就输了一半。这几年我接触过不少准备面试的朋友,也看过很多测试工程师/测试开发岗位的面试题合集,大家普遍的做法是刷题、背答案、记八股,结果面试官换一种问法,立刻就原…

2026/10/13 12:41:45 阅读更多 →
鲲鹏云ARM架构Hadoop集群部署实验全流程拆解

鲲鹏云ARM架构Hadoop集群部署实验全流程拆解

简介:《鲲鹏云大数据实验docx》是一份面向云计算与大数据初学者的实验报告,完整记录了在华为云鲲鹏环境下从零搭建Hadoop集群的全过程。报告从购买弹性云服务器与对象存储服务开始,介绍如何获取AK/SK认证密钥,并逐步完成OpenJDK安…

2026/10/13 12:40:44 阅读更多 →

最新新闻

RabbitMQ从0到1:核心模型、生产实践与高频问题排查指南

RabbitMQ从0到1:核心模型、生产实践与高频问题排查指南

如果你手头有个项目需要在系统里传递消息,十有八九会想到RabbitMQ。但很多人装完、跑个Hello World就算“会用”了,等遇到连接失败、消息丢失、谁该消费谁不该消费、甚至admin账号没法创建virtual host时,才发现自己其实并不理解它。这篇就从…

2026/10/13 13:13:23 阅读更多 →
CANN全面开源:异构计算架构如何让性能调优不再靠猜

CANN全面开源:异构计算架构如何让性能调优不再靠猜

1. 先搞清楚CANN是什么,以及“开源开放”为什么是一条难走但必须走的路 很多做AI开发的同行,第一次听到CANN这个缩写,是在跑模型的时候拿到一张报错截图,或者是在某个加速卡的性能优化文档里。CANN的全称是异构计算架构&#xff0…

2026/10/13 13:13:23 阅读更多 →
Python+微信小程序+AI:从零搭建对话式健康风险评估系统

Python+微信小程序+AI:从零搭建对话式健康风险评估系统

最近半年我一直泡在一个“Python 微信小程序 AI健康问诊”的个人项目里。起因很简单:家里人经常在小程序里看各种健康问答,但问题描述得零零散散,得到的回答又是通用模板,根本没结合个人的基础情况。我就想,能不能自…

2026/10/13 13:13:23 阅读更多 →
若依集成EasyExcel实战:告别手写POI,搞定复杂表头与大数据导出

若依集成EasyExcel实战:告别手写POI,搞定复杂表头与大数据导出

从写下第一行导出代码到最后彻底放弃手写 POI,大概花了我整整两周时间。彼时我们的若依后台管理系统刚好需要一批新的报表导出功能,领导给了个听起来特别简单的要求:把数据导成 Excel,表头要好看点,列宽自动适应&#…

2026/10/13 13:13:23 阅读更多 →
AI产品经理的五种分化:从模型微调到行业落地,你适合哪一类?

AI产品经理的五种分化:从模型微调到行业落地,你适合哪一类?

最近好几个朋友来找我聊转行,说想往AI产品经理方向走,结果翻了一圈招聘JD直接懵了:同一个岗位名称,有的要求懂Transformer、懂模型微调,有的只要会画原型写PRD,有的甚至要跟着销售跑客户。这到底是一个岗位…

2026/10/13 13:13:23 阅读更多 →
Mars版Eclipse绿色版配置指南:JAVA_HOME、Tomcat与避坑要点

Mars版Eclipse绿色版配置指南:JAVA_HOME、Tomcat与避坑要点

简介:这是一份Eclipse JEE Mars R的Windows 64位官方绿色版压缩包,面向Java企业级与Web开发者,针对J2EE项目开发与调试环境而封装。版本基于2015年6月30日发布的Mars R正式版,解压后免安装即可运行,省去安装向导与手动…

2026/10/13 13:12:22 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →