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

告别复制粘贴!NQ-Assistant:一键将 DeepSeek/ChatGPT/Claude 回复导出为精美 Word 文档


一、问题背景

1.1 遇到了什么痛点?

在日常使用 DeepSeek、ChatGPT、Claude 等 AI 工具撰写报告时,我反复遇到同一个问题:

  1. AI 输出的 Markdown 格式(表格、代码块、数学公式)在网页上排版完美
  2. 复制到 Word 后格式全部丢失——表格变成纯文本、代码块失去高亮、LaTeX 公式变成乱码
  3. AI 的思考过程搜索引用编号(如-14-15[5](url))混入正文,需要手动删除
  4. 切换不同 AI 平台时,每个平台的操作方式不同,无法统一处理

核心矛盾:AI 大幅提升了内容生成效率,但"从 AI 输出到可用文档"这最后一公里,全靠手动。

1.2 现有方案为什么不够?

方案问题
直接复制粘贴格式全丢,引用编号混入
AI 平台自带的导出仅少数平台有,且功能简陋
第三方 Markdown 编辑器仍需手动搬运,无法自动清洗
截图转 Word无法编辑,图片模糊

1.3 本文要解决什么

构建一个浏览器扩展(Manifest V3),自动在 AI 对话页面注入捕获按钮,点击后将 AI 回复清洗、转换为标准 Markdown 并渲染预览,最终导出为 Word 文档。全过程一句话:点按钮 → 编辑 → 导出。


二、方案设计

2.1 整体架构

┌─────────────────────────────────────────────────────────┐ │ NQ-Assistant 架构 │ │ │ │ AI 网页(DeepSeek/ChatGPT/Claude/Kimi/豆包) │ │ │ │ │ ▼ content.js(注入按钮 + DOM 提取) │ │ │ │ │ ▼ background.js(消息中转 + chrome.storage 持久化) │ │ │ │ │ ▼ sidepanel.js(markdown-it 渲染 + 编辑 + 导出) │ │ │ │ │ ▼ Word 文档(HTML-DOC 格式,WPS/Word 原生兼容) │ └─────────────────────────────────────────────────────────┘

2.2 为什么选择这个架构?

决策点选择原因
扩展类型Manifest V3 Side Panel侧边栏不遮挡网页,可边对话边预览
Markdown 渲染markdown-it(而非 marked/showdown)浏览器兼容性最好,表格/代码块支持完整
Word 导出HTML-DOC(而非 docx.js)css+html 嵌入,Word/WPS 原生打开,无需额外库
存储chrome.storage.localManifest V3 不支持 localStorage,且 storage 支持跨设备同步
依赖策略全部本地打包零网络请求,避免 CDN 被墙(国内用户友好)

2.3 关键风险与应对

⚠️风险 1:各 AI 平台的 DOM 结构不同,且随时可能更新
应对:使用平台检测 + 可配置选择器,每个平台独立配置messagemarkdown的选择器

⚠️风险 2element.innerHTML直接展示在侧栏会有 css 冲突
应对:预览走 Markdown→HTML 渲染(保证样式一致性),导出保留原始 HTML(保证格式 100% 保真)


三、核心实现

3.1 多平台 DOM 提取

每个 AI 平台的网页结构不同。通过平台检测 + 选择器配置实现统一接口:

// content.js — 平台自动检测与选择器配置constPLATFORMS={deepseek:{host:'chat.deepseek.com',message:'.ds-message',// 消息容器markdown:'.ds-markdown',// Markdown 渲染容器think:'.ds-think-content, [class*="think"]'},chatgpt:{host:'chatgpt.com',message:'[data-message-author-role="assistant"]',markdown:'.markdown, [class*="prose"]',think:'[class*="think"], [class*="reasoning"]'},claude:{/* ... */},kimi:{/* ... */},doubao:{/* ... */}};// 运行时自动检测functiondetectPlatform(){consthost=window.location.hostname;for(const[key,cfg]ofObject.entries(PLATFORMS)){if(host.includes(cfg.host.replace('https://','')))return{key,...cfg};}}

3.2 HTML 清洗管线

从 DOM 到可用的 Markdown 需要经过多层清洗。这是整个工具的核心逻辑:

// content.js — 内容提取管线functionextractContent(el){constclone=el.cloneNode(true);// 第1层:移除思考过程 DOM 节点removeThinking(clone);// → 去掉 .ds-think-content 等思考区块// 第2层:移除 UI 元素(按钮、图标、工具栏)removeUIElements(clone);// → 去掉复制、下载按钮和代码块工具栏// 第3层:移除引用链接(上标数字、citation 类元素)removeCitationLinks(clone);// → 去掉 <sup>1</sup>、[-5](url) 等引用// 第4层:保存清洗后的 HTML(导出用,100% 保真)consthtml=clone.innerHTML.trim();// 第5层:HTML → Markdown(预览和编辑用)constmd=elementToMarkdown(clone);// → <h3> → ###, <table> → |---|, <code> → ``````等return{html,md};}

为什么分两层(html + md)?

  • html:保留 AI 网页的原始渲染效果,导出时直接嵌入 Word,排版 100% 还原
  • md:转换为 Markdown 后预览和编辑,格式统一且易于修改

3.3 HTML → Markdown 转换

这是最复杂的一环。AI 网页将 Markdown 渲染为 HTML,我们需要逆向还原:

// content.js — DOM 元素到 Markdown 语法的转换functionelementToMarkdown(el){constchildren=Array.from(el.children);if(children.length===0)returngetText(el);letmd='';for(constchildofchildren){consttag=child.tagName.toLowerCase();consttext=getText(child);switch(tag){case'h1':md+='\n# '+text+'\n';break;case'h2':md+='\n## '+text+'\n';break;case'h3':md+='\n### '+text+'\n';break;case'p':md+='\n'+processInline(child)+'\n';break;case'pre':md+=processCode(child);break;case'ul':md+=processList(child,false);break;case'ol':md+=processList(child,true);break;case'table':md+=processTable(child);break;case'blockquote':md+='\n> '+text.replace(/\n/g,'\n> ')+'\n';break;// ... 更多标签处理}}returnmd.replace(/\n{3,}/g,'\n\n').trim();}

3.4 引用编号清理

DeepSeek 搜索模式会在文中插入引用编号,格式多变:

原始: "追溯到1912年-14-15,被评为国家级一流本科专业-15-29。" 清洗: "追溯到1912年,被评为国家级一流本科专业。"

需要处理-14-15-29[-5][-5](url)等多种格式,同时保护真正的年份范围(1912-1920):

functionstripCitations(md){// 1. 移除 "-数字-数字"(如 -14-15)md=md.replace(/[\-–—]\d{1,3}[\-–—]\d{1,3}/g,'');// 2. 移除 "-数字"(保护年份 1912-1920)md=md.replace(/([\-–—])\s*(\d{1,3})(?=[,。;\n]|$)/g,(match,dash,num)=>{constctx=/* 检查上下文是否为年份 */;if(isYearRange(ctx))returnmatch;// 保留年份return'';// 移除引用});// 3. 移除 "[-5](url)" 和 "[5]" 格式md=md.replace(/\[-?\d{1,3}([,\-]\d{1,3})*\]\([^)]*\)/g,'');md=md.replace(/\s*\[-?\d{1,3}([,\-]\d{1,3})*\]/g,'');returnmd;}

3.5 数学公式处理

AI 网页使用 KaTeX 将 LaTeX 渲染为 HTML。提取时需要还原:

// content.js — KaTeX HTML → $...$ / $$...$$functionconvertKatexToLatex(root){root.querySelectorAll('.katex').forEach(katexEl=>{// 从 <annotation encoding="application/x-tex"> 提取原始 LaTeXconstannotation=katexEl.querySelector('annotation[encoding="application/x-tex"]');if(annotation){constlatex=annotation.textContent.trim();constisDisplay=katexEl.closest('.katex-display')!==null;constwrapper=isDisplay?'\n$$\n'+latex+'\n$$\n':'$'+latex+'$';// 替换 KaTeX 元素为文本节点katexEl.parentNode.replaceChild(document.createTextNode(wrapper),katexEl);}});}

在侧栏渲染时,需要区分"真正的数学公式"和"解释性文字中的示例":

// sidepanel.js — 智能数学公式检测letp=md.replace(/\$\$([\s\S]+?)\$\$/g,(_,m)=>/[\\\^_{}]/.test(m)// 含有 LaTeX 符号??'<div class="math-block">'+esc(m)+'</div>'// → 公式:'<code>$$'+esc(m)+'$$</code>'// → 代码示例);

3.6 导出管线

导出使用msg.html(清洗后的原始 HTML),确保 Word 中排版与网页一致:

// sidepanel.js — 导出functiongetExportHTML(msgs,tpl){constbodyHtml=msgs.map((m,i)=>{constrendered=m.html||renderMarkdown(m.content);// html 优先returnrendered+(i<msgs.length-1?'<div class="page-break"></div>':'');}).join('\n');return`<!DOCTYPE html><html lang="zh-CN"> <head><meta charset="UTF-8"><title>NQ-Assistant</title> <style>${getExportCSS(tpl)}</style></head> <body>${bodyHtml}</body></html>`;}

四、验证效果

4.1 测试环境

项目配置
浏览器Edge 126 / Chrome 126
操作系统Windows 11
测试平台DeepSeek R1、ChatGPT 4o、Claude 3.5 Sonnet、Kimi、豆包
测试内容含表格/代码块/LaTeX公式/多级标题的 AI 回复

4.2 测试结果

测试项DeepSeekChatGPTClaudeKimi豆包
按钮注入
表格保留
代码块保留
数学公式
思考过程过滤N/AN/A
引用编号清理
Word 导出

4.3 边界与局限

  • DOM 结构变化风险:各平台可能随时更新前端代码,导致选择器失效。可通过更新PLATFORMS配置修复
  • 复杂表格:跨行/跨列的合并单元格可能不完全保留
  • 图片:AI 生成的图片引用可能因跨域无法导出

4.4 项目展示


五、安装与使用

5.1 获取代码

gitclone https://github.com/NQLOVELSJ/NQ_Assitant.git

5.2 加载到浏览器

  1. 打开edge://extensions(或chrome://extensions
  2. 开启「开发人员模式」
  3. 点击「加载解压缩的扩展」→ 选择项目文件夹
  4. 工具栏出现图标 ✅

5.3 使用

  1. 打开任意支持的 AI 平台,正常对话
  2. AI 回复下方出现📋 预览按钮
  3. 点击 → 侧边栏捕获
  4. 编辑、排序、选模板 →📄 导出所选 Word
  5. 快捷键Ctrl+E快速导出

六、总结

本文从实际痛点出发,完整介绍了如何构建一个跨平台 AI 回复导出工具。核心思路是:DOM 清洗 → 多层过滤 → 双轨输出(Markdown 预览 + HTML 导出)

这个方案的适用边界:

  • ✅ 适用于需要从 AI 对话中提取格式化内容的场景
  • ✅ 核心清洗逻辑可复用到其他浏览器扩展
  • ⚠️ 依赖各平台 DOM 结构的稳定性,需定期维护选择器

📦 GitHub:https://github.com/NQLOVELSJ/NQ_Assitant
📄 License:MIT


本文所有代码均为 NQ-Assistant 项目实际代码,可直接运行验证。

http://www.gsyq.cn/news/1541828.html

相关文章:

  • 音乐自由之路:3分钟掌握Unlock-Music,解锁你的数字音乐收藏
  • BLUPs与收缩效应:混合模型中个体预测的智能校准
  • 2026济南化工原料销售公司 实测测评 - LYL仔仔
  • 厂区厕所定制怎么选?资深从业者解答核心问题 - 奔跑123
  • K-means聚类实战:从肘部法则失效到业务可解释的完整链路
  • 2026年 缠绕机厂家推荐排行榜:托盘/在线/自动缠绕机及薄膜裹包机优质品牌深度解析与选购指南 - 企业推荐官【官方】
  • 揭秘PyWxDump 4.0:如何破解微信数据解析的四大技术壁垒
  • AI公司介绍:每个老板都应该准备一份AI能读懂的公司介绍 - 招财兔数字员工
  • 近五成学子顺利深造!就业学生超半数入职国企!东北大学资源与土木工程学院解锁多元未来 - 品牌2026
  • Claude Code CLI无缝切换Gemini 2.5 Pro实战指南
  • 中年转行数据科学家:用行业经验撬动真实项目
  • 喜马拉雅VIP音频下载难题破解:这款跨平台工具如何安全保存你的付费内容?
  • 寄重货怎么便宜?试试这招省一半运费 - 快递物流资讯
  • 返聘协议起草律师事务所:退休返聘协议怎么写?北京专业律所协议起草与风险防范 - 品牌2026
  • Android Camera开发:从HAL_PIXEL_FORMAT到ImageFormat的映射与实战解析
  • Python自动化异常值检测与处理实战:IQR、Isolation Forest与多策略融合
  • 如何用AMD显卡玩转AI绘画?ComfyUI-Zluda终极配置指南
  • 2026年 上海气动打包机厂家/品牌推荐榜:高效捆扎与稳定性能优选方案及联系渠道指南 - 企业推荐官【官方】
  • 2026年 PP打包带厂家推荐排行榜:高韧性打包带/耐撕打包带/环保PP打包带源头厂家及品牌深度解析 - 企业推荐官【官方】
  • 5个步骤轻松掌握Bodymovin扩展面板:After Effects动画导出终极指南
  • 2026泉州废不锈钢回收公司 真实测评 - LYL仔仔
  • 2026年6月箱包五金厂家TOP8推荐 专业配件助力品质升级 - 资讯报道
  • 破局与重塑:凯撒旅业三大核心引擎驱动文旅新未来 - 品牌2026
  • AI与数据科学内容创作的职业底线:忠于原料,拒绝编造
  • 知识产权归属协议律师事务所:研发成果归谁?北京专业律所知识产权归属协议指南 - 品牌2026
  • 欧富洛宋式美学FAS级北美黑胡桃木全实木家具:以宋韵极简重新定义高端东方雅居 - 优选案例分享
  • AI获客基本功:未来一年,实体企业必须补上的AI获客课 - 招财兔数字员工
  • 2026年合肥GEO优化公司推荐:AI搜索趋势权威评测,涵盖专业服 - 资讯报道
  • GEO复盘机制:每周一次GEO复盘,比盲目发布更重要 - 招财兔数字员工
  • 2026大型厂区化验室COD检测仪选型全解析 连华科技专业适配推荐参考 - 水质分析仪器---高工