用Node.js施展文檔比對魔法:輕松實現Word文檔差異比較小工具,實現Word差異高亮標注(附完整實戰代碼)

引言:當「找不同」遇上程序員的智慧
你是否經歷過這樣的場景?

法務同事發來合同第8版修改版,卻說不清改了哪里

導師在論文修改稿里標注了十幾處調整,需要逐一核對

團隊協作文檔頻繁更新,版本差異讓人眼花繚亂

傳統的手動比對不僅效率低下,還容易遺漏關鍵修改。今天,我將揭秘如何用30行Node.js代碼,打造一個智能Word文檔差異比對工具,實現:

? 自動識別文本差異
? 智能標注修改痕跡
? 生成專業比對報告

一、安裝所需依賴

npm install docx mammoth diff fs-extra

二、代碼注釋與技術原理詳解

1、完整代碼以及注釋

/*** Word文檔差異比較工具* 本腳本使用Node.js比較兩個Word(.docx)文件的內容差異,并生成帶有顏色標注的比較結果文檔*/const fs = require('fs');
const path = require('path');
const { Document, Paragraph, TextRun, HeadingLevel, Packer } = require('docx');
const mammoth = require('mammoth');
const diff = require('diff');/*** 比較兩個Word文件并生成差異報告* @param {string} file1Path - 第一個Word文件路徑(原始文件)* @param {string} file2Path - 第二個Word文件路徑(修改后的文件)* @param {string} outputPath - 差異報告輸出路徑* * 技術原理:* 1. 使用mammoth庫提取兩個Word文檔的純文本內容* 2. 使用diff庫進行文本差異比較,識別添加、刪除和未更改的部分* 3. 使用docx庫構建新的Word文檔,用不同顏色和樣式標注差異部分*/
async function compareWordFiles(file1Path, file2Path, outputPath) {try {// 提取兩個Word文件的文本內容// mammoth.extractRawText會解析docx文件的XML結構,提取所有文本內容const file1Content = await extractTextFromDocx(file1Path);const file2Content = await extractTextFromDocx(file2Path);// 使用diff庫比較文本差異// diffWords函數會將文本分解為單詞級別的差異,返回一個差異對象數組// 每個差異對象包含value(文本內容)和added/removed標志const differences = diff.diffWords(file1Content, file2Content);// 使用docx庫創建新的Word文檔// Document對象表示整個Word文檔,包含一個或多個sectionsconst doc = new Document({sections: [{properties: {},children: [// 文檔標題new Paragraph({text: "Word文檔差異比較結果",heading: HeadingLevel.HEADING_1,spacing: { after: 200 } // 設置段后間距(單位:twip,1/20磅)}),// 原始文件信息new Paragraph({text: `原文件: ${path.basename(file1Path)}`,spacing: { after: 100 }}),// 修改后文件信息new Paragraph({text: `新文件: ${path.basename(file2Path)}`,spacing: { after: 200 }}),// 插入差異內容段落...generateDiffParagraphs(differences)]}]});// 將Document對象轉換為Buffer并寫入文件// Packer.toBuffer內部使用JSZip庫打包docx文件(本質上是ZIP格式的XML文件集合)const buffer = await Packer.toBuffer(doc);fs.writeFileSync(outputPath, buffer);console.log(`差異比較結果已保存到: ${outputPath}`);} catch (error) {console.error('比較過程中出錯:', error);}
}/*** 從Word文檔中提取純文本內容* @param {string} filePath - Word文件路徑* @returns {Promise<string>} 提取的純文本內容* * 技術原理:* mammoth庫解析docx文件(實際是ZIP壓縮的XML文件),* 遍歷document.xml中的段落和文本節點,拼接成純文本字符串*/
async function extractTextFromDocx(filePath) {const result = await mammoth.extractRawText({ path: filePath });return result.value;
}/*** 根據差異結果生成帶有樣式標注的段落數組* @param {Array} differences - diff庫生成的差異數組* @returns {Array} 包含Paragraph對象的數組* * 技術原理:* 1. 處理diff庫輸出的差異數組,每個部分可能是added/removed/unchanged* 2. 按換行符分割文本,確保每個段落獨立* 3. 為不同差異類型創建不同樣式的TextRun:*    - 新增內容: 藍色(#1800a1)、加粗*    - 刪除內容: 紅色(#FF0000)、刪除線*    - 未更改內容: 黑色(#000000)*/
function generateDiffParagraphs(differences) {const paragraphs = [];let currentParagraph = [];// 遍歷每個差異部分differences.forEach(part => {// 按換行符分割文本,處理多行內容const lines = part.value.split('\n');lines.forEach((line, lineIndex) => {// 跳過空行if (line.trim() === '') return;let textRun;if (part.added) {// 新增內容樣式textRun = new TextRun({text: line,color: '1800a1', // 藍色表示新增bold: true       // 加粗突出顯示});} else if (part.removed) {// 刪除內容樣式textRun = new TextRun({text: line,color: 'FF0000', // 紅色表示刪除strike: true      // 刪除線表示已移除});} else {// 未更改內容樣式textRun = new TextRun({text: line,color: '000000'  // 黑色表示未更改});}// 將文本段添加到當前段落currentParagraph.push(textRun);// 如果不是最后一行,創建新段落if (lineIndex < lines.length - 1) {paragraphs.push(new Paragraph({children: currentParagraph}));currentParagraph = []; // 重置當前段落}});});// 添加最后一個未完成的段落if (currentParagraph.length > 0) {paragraphs.push(new Paragraph({children: currentParagraph}));}return paragraphs;
}// 使用示例
const file1 = path.join(__dirname, './word/dl_v1.docx');
const file2 = path.join(__dirname, './word/js_xg_v1.docx');
const output = path.join(__dirname, './word/comparison_result.docx');// 執行比較
compareWordFiles(file1, file2, output);

2、關鍵技術原理詳解

  1. Word文檔解析:

    • mammoth庫解析.docx文件(實際是ZIP壓縮包),提取其中的document.xml文件內容
    • 解析XML結構,提取所有文本節點,忽略格式、圖片等非文本元素
  2. 差異比較算法:

    • diff庫使用Myers差分算法找出兩個文本序列的最長公共子序列(LCS)
    • diffWords方法進行單詞級別的比較,比字符級比較更符合文檔比較的需求
  3. Word文檔生成:

    • docx庫構建符合Office Open XML標準的Word文檔結構
    • 文檔結構包含段落(Paragraph)、文本塊(TextRun)等元素
    • 顏色使用16進制RGB格式表示(如1800a1表示藍色)
  4. 差異可視化:

    • 新增內容用藍色加粗顯示,便于識別添加的內容
    • 刪除內容用紅色刪除線顯示,表示已移除的內容
    • 保留原始文本的段落結構,確保可讀性
  5. 文件處理:

    • 最終生成的.docx文件實際上是包含多個XML文件的ZIP壓縮包
    • Packer.toBuffer方法將內存中的文檔結構打包成符合標準的.docx文件

結語:讓機器做枯燥的事,讓人做有創意的事
通過這個項目,我們不僅實現了一個實用的文檔比對工具,更演示了如何:
🔧 組合現有工具解決實際問題
🚀 用少量代碼創造高價值產出
🌐 將復雜技術轉化為簡單接口

下次當同事還在用"Ctrl+F"艱難找不同時,你可以優雅地說:“試試我的智能比對工具?”

原創技術博客,轉載請注明出處。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77419.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77419.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77419.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端瀏覽器窗口交互完全指南:從基礎操作到高級控制

瀏覽器窗口交互是前端開發中構建復雜Web應用的核心能力&#xff0c;本文深入探討23種關鍵交互技術&#xff0c;涵蓋從傳統API到最新的W3C提案&#xff0c;助您掌握跨窗口、跨標簽頁的完整控制方案。 一、基礎窗口操作體系 1.1 窗口創建與控制 // 新窗口創建&#xff08;現代瀏…

Git和Gitlab的部署和操作

一。GIT的基本操作 1.GIT的操作和查看內容 [rootmaster ~]# yum install git -y [rootmaster ~]# git config --list&#xff1a;查看所有配置 2.GIT倉庫初始化 [rootmaster ~]# mkdir /gittest&#xff1a;創建目錄 [rootmaster ~]# cd /gittest/&#xff1a;進入目錄 [rootm…

Linux中線程池的簡單實現 -- 線程安全的日志模塊,策略模式,線程池的封裝設計,單例模式,餓漢式單例模式,懶漢式單例模式

目錄 1. 對線程池的理解 1.1 基本概念 1.2 工作原理 1.3 線程池的優點 2. 日志與策略模式 2.1 日志認識 2.2 策略模式 2.2.1 策略模式的概念 2.2.2 工作原理 2.2 自定義日志系統的實現 3. 線程池設計 3.1 簡單線程池的設計 3.2 線程安全的單例模式線程池的設計 3…

量子力學:量子通信

量子通信是利用量子力學原理對信息進行編碼、傳輸和處理的新型通信方式&#xff0c;以下是其詳細介紹及業界發展現狀&#xff1a; 基本原理 量子疊加態 &#xff1a;量子系統可以處于多個狀態的疊加&#xff0c;如光子的偏振方向可以同時處于水平和垂直方向的疊加態&#xff…

企業架構之旅(1):TOGAF 基礎入門

大家好&#xff0c;我是沛哥兒。今天我們簡單聊下TOGAF哈。 文章目錄 一、TOGAF 是什么定義與核心定位發展歷程與行業地位與其他架構框架的區別 二、TOGAF 核心價值企業數字化轉型助力業務與 IT 的協同作用降本增效與風險管控 三、TOGAF 基礎術語解析架構域&#xff08;業務、…

CSS 內容超出顯示省略號

CSS 內容超出顯示省略號 文章目錄 CSS 內容超出顯示省略號**1. 單行文本省略&#xff08;常用&#xff09;****2. 多行文本省略&#xff08;如 2 行&#xff09;****3. 對非塊級元素生效****完整示例****注意事項** 在 CSS 中實現內容超出顯示省略號&#xff0c;主要通過控制文…

路由器重分發(OSPF+RIP),RIP充當翻譯官,OSPF充當翻譯官

路由器重分發&#xff08;OSPFRIP&#xff09; 版本 1 RIP充當翻譯官 OSPF路由器只會OSPF語言&#xff1b;RIP路由器充當翻譯官就要會OSPF語言和RIP語言&#xff1b;則在RIP中還需要將OSPF翻譯成RIPOSPF 把RIP路由器當成翻譯官&#xff0c;OSPF路由器就只需要宣告自己的ip&am…

AlexNet網絡搭建

AlexNet網絡模型搭建 環境準備 首先在某個盤符下創建一個文件夾&#xff0c;就叫AlexNet吧&#xff0c;用來存放源代碼。 然后新建一個python文件&#xff0c;就叫plot.py吧&#xff0c;往里面寫入以下代碼&#xff0c;用于下載數據集&#xff1a; # FashionMNIST里面包含了…

【計算機網絡】網絡基礎概念

&#x1f4da; 博主的專欄 &#x1f427; Linux | &#x1f5a5;? C | &#x1f4ca; 數據結構 | &#x1f4a1;C 算法 | &#x1f152; C 語言 | &#x1f310; 計算機網絡 這是博主計算機網絡的第一篇文章&#xff0c;本文由于是基礎概念了解&#xff0c;引用了大…

在Spring Boot項目中實現Word轉PDF并預覽

在Spring Boot項目中實現Word轉PDF并進行前端網頁預覽&#xff0c;你可以使用Apache POI來讀取Word文件&#xff0c;iText或Apache PDFBox來生成PDF文件&#xff0c;然后通過Spring Boot控制器提供文件下載或預覽鏈接。以下是一個示例實現步驟和代碼&#xff1a; 1. 添加依賴 …

圖解 Redis 事務 ACID特性 |源碼解析|EXEC、WATCH、QUEUE

寫在前面 Redis 通過 MULTI、EXEC、WATCH 等命令來實現事務功能。Redis的事務是將多個命令請求打包&#xff0c;然后一次性、按照順序的執行多個命令的機制&#xff0c;并且在事務執行期間&#xff0c;服務器不會中斷事務而該去執行其他客戶端的命令請求。 就像下面這樣&#…

LeetCode --- 446 周賽

題目列表 3522. 執行指令后的得分 3523. 非遞減數組的最大長度 3524. 求出數組的 X 值 I 3525. 求出數組的 X 值 II 一、執行指令后的得分 照著題目要求進行模擬即可&#xff0c;代碼如下 // C class Solution { public:long long calculateScore(vector<string>&…

山東大學軟件學院項目實訓-基于大模型的模擬面試系統-前端美化滾動條問題

模擬面試界面左側底部 通過檢查工具定位到其所在的位置&#xff1a; 直接對該組件進行美化&#xff1a; <!-- AI面試官列表 --><div class"ai-interviewer-section" v-show"activeTab interviewer"><el-scrollbar class"no-horizont…

git版本回退 | 遠程倉庫的回退 (附實戰Demo)

目錄 前言1. 基本知識2. Demo3. 彩蛋 前言 &#x1f91f; 找工作&#xff0c;來萬碼優才&#xff1a;&#x1f449; #小程序://萬碼優才/r6rqmzDaXpYkJZF 爬蟲神器&#xff0c;無代碼爬取&#xff0c;就來&#xff1a;bright.cn 本身暫存區有多個文件&#xff0c;但手快了&…

什么事Nginx,及使用Nginx部署vue項目(非服務器Nginx壓縮包版)

什么是 Nginx? Nginx(發音為 “engine-x”)是一個高性能的 HTTP 和反向代理服務器,也是一個 IMAP/POP3/SMTP 代理服務器。它以其高性能、高并發處理能力和低資源消耗而聞名。以下是 Nginx 的主要特性和用途: 主要特性 高性能和高并發 Nginx 能夠處理大量并發連接,適合高…

第十六周藍橋杯2025網絡安全賽道

因為只會web&#xff0c;其他方向都沒碰過&#xff0c;所以只出了4道 做出來的&#xff1a; ezEvtx 找到一個被移動的文件&#xff0c;疑似被入侵 提交flag{confidential.docx}成功解出 flag{confidential.docx} Flowzip 過濾器搜索flag找到flag flag{c6db63e6-6459-4e75-…

高性能的開源網絡入侵檢測和防御引擎:Suricata介紹

一、Debian下使用Suricata 相較于Windows&#xff0c;Linux環境對Suricata的支持更加完善&#xff0c;操作也更為便捷。 1. 安裝 Suricata 在Debian系統上&#xff0c;你可以通過包管理器 apt 輕松安裝 Suricata。 更新軟件包列表: sudo apt update安裝 Suricata: sudo apt …

IP-address-space

導航 (返回頂部) 1. IPv4地址分配表 1.2 IPv4 專用地址注冊表1.3 各國IPv4地址分配列表 2. IPv6地址分配表 2.1 IANA IPv6 專用地址注冊表2.2 IPv6 多播地址分配 1. IPv4地址分配表1.2 IPv4 專用地址注冊表1.3 各國IPv4地址分配列表 2. IPv6地址分配表2.1 IANA IPv6 專用地址…

Ubuntu使用war包部署Jenkins并通過systemcl管理

目錄 一、當前系統環境 二、安裝Java 二、安裝Jenkins 三、使用systemctl管理 一、當前系統環境 操作系統&#xff1a;ubuntu 24.04 Jenkins版本&#xff1a;2.506 格式&#xff1a;war JDK版本&#xff1a;OpenJDK_17 二、安裝Java 1.下載jdk安裝包 # wget下載 wget …

牛客 verilog入門 VIP

1、輸出1 答案&#xff1a; timescale 1ns/1nsmodule top_module(output wire one );assign one 1b1; endmodule 2、wire連線 答案&#xff1a; timescale 1ns/1nsmodule wire0(input wire in0,output wire out1 );assign out1 in0; endmodule 3、多wire連線 timescale 1…