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

【前端】:单 HTML 去除 Word 批注

在现代办公中,.docx 文件常用于文档编辑,但其中的批注(注释)有时需要在分享或归档前被去除。本文将从原理出发,深入剖析如何在纯前端环境下实现对 .docx 文件注释的移除,并提供完整的实现源码。最后,我们还将说明如何将 fflate.min.js 内嵌到项目中,实现零外部依赖。


一、原理解析

1. .docx 本质

  • .docx 文件其实是一个 ZIP 压缩包。将其扩展名改为 .zip 并解压后,能看到包含多个 XML 文件和资源文件的目录结构。常用目录有:
    • word/document.xml:主文档内容
    • word/comments.xml:存储批注内容
    • word/_rels/document.xml.rels:定义文档与资源(如批注)之间的关系

2. 去除注释的思路

  • 删除批注文件:移除 word/comments.xml
  • 删除关系引用:在 word/_rels/document.xml.rels 中,删除指向批注的 <Relationship ... Type=".../comments" .../> 节点。
  • 清理文档标记:在 word/document.xml 中,删除 <w:commentRangeStart><w:commentRangeEnd><w:commentReference> 等与批注相关的标记。

3. 纯前端技术栈

  • ZIP 操作:使用 JavaScript 库(如 fflate)在浏览器环境完成解压与压缩,避免服务器依赖。
  • 文件下载:利用浏览器原生的 Blob 与 URL API 生成下载链接。
  • 交互体验:拖拽或点击上传区,自动触发处理与下载。

二、完整源码(依赖版本)

将以下内容保存为 remove_comments.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Remove DOCX Comments</title><style>html, body { margin: 0; height: 100%; display: flex; align-items: center; justify-content: center; background: #f5f5f5; } #drop-zone { width: 320px; height: 200px; border: 2px dashed #bbb; border-radius: 8px; background: white; display: flex; align-items: center; justify-content: center; text-align: center; padding: 16px; cursor: pointer; transition: border-color 0.3s; } #drop-zone.dragover { border-color: #333; }</style>
</head>
<body><div id="drop-zone"><div><p>拖拽或点击上传 DOCX 文件</p><p style="font-size: 0.9em; color: #666;">上传后自动去除注释并下载</p></div><input type="file" id="file-input" accept=".docx" style="display: none;" /></div><script src="https://cdn.jsdelivr.net/npm/fflate@0.7.4/umd/index.js"></script><script>const dropZone = document.getElementById('drop-zone'), fileInput = document.getElementById('file-input');// 点击上传区域触发文件选择dropZone.addEventListener('click', () => fileInput.click());fileInput.addEventListener('change', e => handleFile(e.target.files[0]));// 拖拽事件处理['dragenter', 'dragover'].forEach(evn => dropZone.addEventListener(evn, e => { e.preventDefault(); dropZone.classList.add('dragover'); }));['dragleave', 'drop'].forEach(evn => dropZone.addEventListener(evn, e => { e.preventDefault(); dropZone.classList.remove('dragover'); }));dropZone.addEventListener('drop', e => handleFile(e.dataTransfer.files[0]));// 处理上传的文件async function handleFile(file) {if (!file || !file.name.endsWith('.docx')) return alert('请选择 .docx 文件');try {const buf = new Uint8Array(await file.arrayBuffer()), files = fflate.unzipSync(buf);// 删除注释文件delete files['word/comments.xml'];// 清理关系文件中的注释引用const relsPath = 'word/_rels/document.xml.rels';if (files[relsPath]) { let rels = fflate.strFromU8(files[relsPath]); rels = rels.replace(/<Relationship[^>]*Type="[^"]*comments[^"]*"[^>]*\/?>/g, ''); files[relsPath] = fflate.strToU8(rels); }// 清理正文中的注释标记const docPath = 'word/document.xml';if (files[docPath]) { let doc = fflate.strFromU8(files[docPath]); doc = doc.replace(/<w:commentRangeStart[^>]*\/>/g, '').replace(/<w:commentRangeEnd[^>]*\/>/g, '').replace(/<w:commentReference[^>]*\/>/g, ''); files[docPath] = fflate.strToU8(doc); }// 重新压缩并下载修改后的文件const newZip = fflate.zipSync(files), blob = new Blob([newZip], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = file.name.replace(/\\.docx$/, '') + '-no-comments.docx';document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(a.href);} catch (err) {console.error(err); alert('处理文件失败,请确认文件格式');}}</script>
</body>
</html>

三、如何去除外部依赖,实现离线使用

若你希望完全离线使用此工具,可以将 fflate.min.js 内联到 HTML 中,而非通过 <script src=...> 引入。

  1. 打开 CDN 链接:https://unpkg.com/fflate@0.7.4/umd/index.js
  2. 复制该页面内容(即 fflate 的 UMD 构建版本)
  3. 替换上面 HTML 文件中的:
<script src="https://unpkg.com/fflate@0.7.4/umd/index.js"></script>

为:

<script>
// 粘贴 fflate.min.js 的内容在此处(即 var fflate = {...})
</script>

这样,即使在无网络环境中,也可在浏览器本地运行该工具。

相关文章:

【前端】:单 HTML 去除 Word 批注

在现代办公中&#xff0c;.docx 文件常用于文档编辑&#xff0c;但其中的批注&#xff08;注释&#xff09;有时需要在分享或归档前被去除。本文将从原理出发&#xff0c;深入剖析如何在纯前端环境下实现对 .docx 文件注释的移除&#xff0c;并提供完整的实现源码。最后&#x…...

解决 PicGo 上传 GitHub图床及Marp中Github图片编译常见难题指南

[目录] 0.行文概述 1.PicGo图片上传失败 2.*关于在Vscode中Marp图片的编译问题* 3.总结与启示行文概述 写作本文的动机是本人看到了Awesome Marp&#xff0c;发现使用 Markdown \texttt{Markdown} Markdown做PPT若加持一些 CSS , JavaScript \texttt{CSS},\texttt{JavaScript} …...

软考 系统架构设计师系列知识点之杂项集萃(59)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;58&#xff09; 第96题 假设关系模式R(U, F)&#xff0c;属性集U{A, B, C}&#xff0c;函数依赖集F{A->B, B->C}。若将其分解为p{R1(U1, F1), R2(U2, F2)&#xff0c;其中U1{A, B}, U2{A, …...

python使用matplotlib画图

【README】 plot画图有两种方法&#xff1a;包括 plt.plot(), ax.plot()-画多个子图 &#xff0c;其中ax表示某个坐标轴; 【1】画单个图 import matplotlib # 避免兼容性问题&#xff1a;明确指定 matplotlib 使用兼容的后端&#xff0c;TkAgg 或 Agg matplotlib.use(TkAgg) …...

鸿蒙OSUniApp 开发实时聊天页面的最佳实践与实现#三方框架 #Uniapp

使用 UniApp 开发实时聊天页面的最佳实践与实现 在移动应用开发领域&#xff0c;实时聊天功能已经成为许多应用不可或缺的组成部分。本文将深入探讨如何使用 UniApp 框架开发一个功能完善的实时聊天页面&#xff0c;从布局设计到核心逻辑实现&#xff0c;带领大家一步步打造专…...

upload-labs通关笔记-第5关 文件上传之.ini绕过

目录 一、ini文件绕过原理 二、源码审计 三、渗透实战 1、查看提示 2、制作.user.ini文件 &#xff08;1&#xff09;首先创建一个文本文件 &#xff08;2&#xff09;保存文件名为.user.ini 2、制作jpg后缀脚本 &#xff08;1&#xff09;创建一个文本文件 &#xf…...

ssti模板注入学习

ssti模板注入原理 ssti模板注入是一种基于服务器的模板引擎的特性和漏洞产生的一种漏洞&#xff0c;通过将而已代码注入模板中实现的服务器的攻击 模板引擎 为什么要有模板引擎 在web开发中&#xff0c;为了使用户界面与业务数据&#xff08;内容&#xff09;分离而产生的&…...

填涂颜色(bfs)

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言​📝 含泪播种的人一定能含笑收获! 题目描述 由数字 0 0 0 组成的方阵中,有一任意形状的由数字 1 1 1 构成的闭合圈。现…...

ros1+docker环境快速搭建

快速使用python 解析ros1的bag消息ros这个东西可以说安装起来非常麻烦的&#xff0c;费时费力&#xff0c;很可能还安装不成功&#xff0c;特别是我的环境是ubuntu22.04 &#xff0c;官方都不支持安装ros1。因此一个可行且快速的方法是使用别人配置好的ros的docker环境 一、下…...

vscode extention踩坑记

# npx vsce package --allow-missing-repository --no-dependencies #耗时且不稳定 npx vsce package --allow-missing-repository #用这行 code --install-extension $vsixFileName --force我问ai&#xff1a;为什么我的.vsix文件大了那么多 ai答&#xff1a;因为你没有用 --n…...

GpuGeek全栈AI开发实战:从零构建企业级大模型生产管线(附完整案例)

目录 背景一、算力困境&#xff1a;AI开发者的「三重诅咒」1.1 硬件成本黑洞‌1.2 资源调度失衡‌1.3 环境部署陷阱‌ 二、三大核心技术突破GpuGeek的破局方案2.1 ‌分时切片调度引擎&#xff08;Time-Slicing Scheduler&#xff09;‌2.2 ‌异构计算融合架构2.3 ‌AI资产自动化…...

【TroubleShoot】禁用Unity Render Graph API 兼容模式

使用Unity 6时新建了项目&#xff0c;有一个警告提示&#xff1a; The project currently uses the compatibility mode where the Render Graph API is disabled. Support for this mode will be removed in future Unity versions. Migrate existing ScriptableRenderPasses…...

数据库字段唯一性修复指南:从设计缺陷到规范实现

数据库字段唯一性修复指南&#xff1a;从设计缺陷到规范实现 一、问题背景 表结构设计缺陷&#xff1a; sys_user 表未对 dingtalk_user_id&#xff08;钉钉用户ID&#xff09;字段设置唯一性约束&#xff0c;导致数据重复&#xff0c;引发以下问题&#xff1a; 系统稳定性风…...

DataX从Mysql导数据到Hive分区表案例

0、下载DataX并解压到对应目录 DataX安装包&#xff0c;开箱即用&#xff0c;无需配置。 https://datax-opensource.oss-cn-hangzhou.aliyuncs.com/202308/datax.tar.gz 相关参考文档 https://github.com/alibaba/DataX/blob/master/hdfswriter/doc/hdfswriter.md 1、Hive分区…...

高性能编程相关

​​​​​​​常见高性能编程技巧&#xff1a; 一&#xff0c;系统级性能优化&#xff1a;从系统架构设计考虑&#xff0c;例如消息队列&#xff0c;模块分成分级&#xff0c;IO读写带宽等 二&#xff0c;算法级性能优化&#xff1a;时间和空间优化 三&#xff0c;代码级性能优…...

vulnhub靶场——secarmy

靶机&#xff1a;secarmy靶机&#xff0c;IP地址为192.168.230.18 攻击&#xff1a;kali&#xff0c;IP地址为192.168.230.134 靶机和攻击机都采用VMware虚拟机&#xff0c;都采用NAT模式 端口扫描&#xff1a; nmap 192.168.230.18 -O -A -p- --reason -sV 21/tcp (ftp): 开…...

labview硬件采集

(1)硬件的描述 &#xff08;2&#xff09;实验步骤1&#xff1a; &#xff08;3&#xff09;实验步骤2 库名/路径的选择要使用32位的开发资料 &#xff08;4&#xff09;实验步骤3 &#xff08;5&#xff09;实验步骤4 找到DoSetV12() 设置返回类型 设置chan 设置state labv…...

openfeign与dubbo调用下载excel实践

一、前言 openfeign和dubbo均是rpc框架 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;框架 是一种允许程序像调用本地方法一样调用远程服务器上函数的技术。它隐藏了底层网络通信的复杂性&#xff0c;让开发者可以专注于业务逻辑&#xff0c;实现…...

ISP有感自发

一、黑电平 由于传感器&#xff0c;即便在无光的情况下&#xff0c;依然会产生微小的暗电流&#xff0c;这些暗电流可能是噪点会影响后期的调试。因此&#xff0c;我们便将这些电流处理为0&#xff0c;成为纯黑的颜色。可以在源头消除这些误差。 如何矫正黑电平&#xff1a; …...

web 自动化之 PO 设计模式详解

文章目录 一、什么是 POM二、如何基于 POM 进行自动化框架架构&#xff1f;1、base 层封装2、pageobjects 层封装3、TestCases 层封装 三、元素和方法分离&数据分离1、哪些部分可以进行分离2、示例代码 四、总结 一、什么是 POM POM page object model 页面对象模型 WEB 自…...

NVMe简介1

它分为两部分&#xff0c;这里是第一部分。 NVM Express&#xff08;NVMe&#xff09;是一种高性能、可扩展的接口协议&#xff0c;用于通过PCI express&#xff08;PCIe&#xff09;总线&#xff0c;实现主机软件与NVM设备之间的通信。目前&#xff0c;由于NVMe SSD相比于SATA…...

【python机器学习】Day 25 异常处理

知识点&#xff1a; 异常处理机制debug过程中的各类报错try-except机制try-except-else-finally机制 在即将进入深度学习专题学习前&#xff0c;我们最后差缺补漏&#xff0c;把一些常见且重要的知识点给他们补上&#xff0c;加深对代码和流程的理解。 借助ai写代码的时候&…...

数学建模初等模型应用

一、目的 掌握初等模型的建模方法,对简单的初等模型能借助Matlab工具软件进行辅助建模、求解和检验。 二、实验内容与设计思想&#xff08;设计思路、主要代码分析&#xff09; 1、预测鱼的质量 &#xff08;1&#xff09;设计思路&#xff1a;使用线性回归模型预测鱼的质量…...

占位符读取标准输入缓冲区规则

1、如果标准输入缓冲区中的前若干个字符都是空白字符&#xff0c;%s&#xff0c;%d&#xff0c;%f都能直接跳过并且从第一个非空白字符开始读取&#xff0c;但%c不能&#xff0c;而是直接读取。 2、%s遇到空白字符时停止&#xff0c;不会读取遇到的空白字符。 3、%d遇到非数字…...

【MCP教程系列】SpringBoot 搭建基于 Spring AI 的 SSE 模式 MCP 服务

原文地址&#xff1a;https://developer.aliyun.com/article/1662946 在当今快速发展的AI技术背景下&#xff0c;如何高效地集成模型能力成为开发者关注的重点。本文将手把手教你如何基于 Spring AI 搭建支持 SSE&#xff08;Server-Sent Events&#xff09;模式的 MCP 服务 相…...

【kafka】kafka概念,使用技巧go示例

1. Kafka基础概念 1.1 什么是Kafka&#xff1f; Kafka是一个分布式流处理平台&#xff0c;用于构建实时数据管道和流式应用。核心特点&#xff1a; 高吞吐量&#xff1a;每秒可处理百万级消息持久化存储&#xff1a;消息按Topic分区存储在磁盘分布式架构&#xff1a;支持水平…...

利用散点图探索宇航员特征与太空任务之间的关系

利用散点图探索宇航员特征与太空任务之间的关系 import matplotlib.pyplot as plt import numpy as np import pandas as pdfrom flexitext import flexitext from matplotlib.patches import FancyArrowPatchplt.rcParams.update({"font.family": "Corbel&quo…...

Ubuntu 命令行显示中文输出信息

Ctrl Alt T 打开终端命令行, 输入命令: sudo apt-get install language-pack-zh-hans安装中文语言支持包 sudo apt-get install language-pack-zh-hans-base配置环境变量 sudo vim /etc/profile进入文件后&#xff0c;按下 a 进入编辑模式&#xff0c;shift ↓ \downarr…...

Linux文件编程——read函数与lseek函数

一、read函数 在 Linux 文件编程中&#xff0c;read 函数是一个系统调用&#xff0c;用于从文件描述符&#xff08;File Descriptor&#xff09;指向的文件或设备中读取数据到缓冲区。它是 Unix/Linux 系统编程中实现底层 I/O 操作的核心函数之一。以下是 read 函数的详细使用…...

[思维模式-38]:看透事物的关系:什么是事物的关系?事物之间的关系的种类?什么是因果关系?如何通过数学的方式表达因果关系?

一、什么是事物的关系&#xff1f; 事物的关系是指不同事物之间存在的各种联系和相互作用&#xff0c;它反映了事物之间的相互依存、相互影响、相互制约等特性。以下从不同维度为你详细阐述&#xff1a; 1、关系的类型 因果关系 定义&#xff1a;一个事件&#xff08;原因&a…...