Node.js匹配文件夾所有文件關(guān)鍵字的完整教程
一、場(chǎng)景需求分析
典型應(yīng)用場(chǎng)景:
- 前端接口冗余:檢測(cè)接口是否使用
- 前端項(xiàng)目國(guó)際化:檢測(cè)翻譯詞庫(kù)是否已全部使用
- 代碼規(guī)范檢查:驗(yàn)證廢棄 API 是否仍存在引用
- 文檔完整性驗(yàn)證:確認(rèn)知識(shí)庫(kù)詞條是否都有對(duì)應(yīng)文檔
二、技術(shù)棧說(shuō)明
| 技術(shù) | 版本 | 作用 |
|---|---|---|
| Node.js | >=14.x | 運(yùn)行環(huán)境 |
| xlsx | ^0.18.5 | Excel 文件處理 |
| fs/promises | 內(nèi)置 | 文件系統(tǒng)操作 |
| path | 內(nèi)置 | 路徑處理 |
安裝依賴:
npm install xlsx
三、核心代碼解析
1. Excel讀取模塊
const xlsx = require("xlsx");
function readExcelRows(filePath) {
const workbook = xlsx.readFile(filePath);
const sheetName = workbook.SheetNames[0];
const sheet = workbook.Sheets[sheetName];
// header:1 表示保留二維數(shù)組結(jié)構(gòu)
const rows = xlsx.utils.sheet_to_json(sheet, { header: 1 });
return { workbook, sheetName, rows };
}
注意:sheet_to_json 的 header 參數(shù)決定輸出格式:
header:1→ 二維數(shù)組(保留原始行列結(jié)構(gòu))header:["col1","col2"]→ 對(duì)象數(shù)組(自動(dòng)映射字段)
2. 目錄遍歷模塊
async function getAllFilesContent(dirPath, fileList = []) {
return new Promise((resolve, reject) => {
fs.readdir(dirPath, async (err, files) => {
if (err) return reject(err);
for (const file of files) {
const fullPath = path.join(dirPath, file);
const stats = fs.statSync(fullPath);
if (stats.isDirectory()) {
if (!excludedDirs.includes(file)) {
await getAllFilesContent(fullPath, fileList);
}
} else if (stats.isFile()) {
try {
const content = fs.readFileSync(fullPath, "utf8");
fileList.push({ path: fullPath, content });
} catch (err) {
console.error(`讀取文件失敗: ${fullPath}`);
}
}
}
resolve(fileList);
});
});
}
最佳實(shí)踐建議:
- 使用
fs.statSync判斷文件類型 - 排除
node_modules等無(wú)關(guān)目錄 - 添加錯(cuò)誤處理防止程序崩潰
3. 匹配檢測(cè)邏輯
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const keyword = row[1]; // 取第二列數(shù)據(jù)
if (typeof keyword === "string") {
const matched = allFiles.some((file) =>
file.content.includes(keyword)
);
if (!matched) {
row[4] = "是"; // 在第五列標(biāo)記
}
}
}
性能優(yōu)化思路:
- 使用正則表達(dá)式預(yù)編譯
- 增加防抖機(jī)制處理超長(zhǎng)文本
- 支持批量處理多個(gè)工作表
四、完整代碼
const fs = require("fs");
const path = require("path");
const xlsx = require("xlsx");
const excludedDirs = ["node_modules", "public"];
// 讀取 Excel 所有行(保留結(jié)構(gòu))
function readExcelRows(filePath) {
const workbook = xlsx.readFile(filePath);
const sheetName = workbook.SheetNames[0];
const sheet = workbook.Sheets[sheetName];
const rows = xlsx.utils.sheet_to_json(sheet, { header: 1 }); // 保持?jǐn)?shù)組結(jié)構(gòu)
return { workbook, sheetName, rows };
}
// 獲取目錄下所有文件內(nèi)容
async function getAllFilesContent(dirPath, fileList = []) {
return new Promise((resolve, reject) => {
fs.readdir(dirPath, async (err, files) => {
if (err) return reject(err);
for (const file of files) {
const fullPath = path.join(dirPath, file);
const stats = fs.statSync(fullPath);
if (stats.isDirectory()) {
if (!excludedDirs.includes(file)) {
await getAllFilesContent(fullPath, fileList);
}
} else if (stats.isFile()) {
try {
const content = fs.readFileSync(fullPath, "utf8");
fileList.push({ path: fullPath, content });
} catch (err) {
console.error(`讀取文件失敗: ${fullPath}`);
}
}
}
resolve(fileList);
});
});
}
// 主函數(shù)
async function main() {
const excelPath = "./data.xlsx"; // 替換成你的 Excel 文件路徑
const targetDir1 = ""; // 替換成你要查找的文件夾路徑
const targetDir2 = "";// 替換成你要查找的文件夾路徑,可選多個(gè)路徑
// 1. 讀取 Excel 原始行數(shù)據(jù)
const { workbook, sheetName, rows } = readExcelRows(excelPath);
console.log(`?? 共讀取 ${rows.length} 行`);
// 2. 獲取兩個(gè)目錄的所有文件內(nèi)容
const files1 = await getAllFilesContent(targetDir1);
const files2 = await getAllFilesContent(targetDir2);
const allFiles = [...files1, ...files2];
console.log(`?? 共讀取 ${allFiles.length} 個(gè)文件`);
// 3. 遍歷 Excel 每一行,檢查第2列關(guān)鍵詞是否被文件匹配
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const keyword = row[1]; // 第二列
if (typeof keyword === "string") {
const matched = allFiles.some((file) => file.content.includes(keyword));
if (!matched) {
row[4] = "是"; // 第5列寫入“是”
}
}
}
// 4. 寫回新的 Excel 文件
const newSheet = xlsx.utils.aoa_to_sheet(rows);
const newWorkbook = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(newWorkbook, newSheet, sheetName);
xlsx.writeFile(newWorkbook, "./test.xlsx");
console.log(
"? 處理完成,未匹配的關(guān)鍵詞已在第5列標(biāo)記“是”,結(jié)果已保存為 keywords_result.xlsx"
);
}
main();
到此這篇關(guān)于Node.js匹配文件夾所有文件關(guān)鍵字的完整教程的文章就介紹到這了,更多相關(guān)Node.js匹配文件夾文件關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從零開始學(xué)習(xí)Node.js系列教程之設(shè)置HTTP頭的方法示例
這篇文章主要介紹了Node.js設(shè)置HTTP頭的方法,詳細(xì)分析了常見(jiàn)HTTP頭的功能、原理及相關(guān)設(shè)置操作技巧,需要的朋友可以參考下2017-04-04
Node.js?連接?MySql?統(tǒng)計(jì)組件屬性的使用情況解析
這篇文章主要為大家介紹了Node.js?連接?MySql?統(tǒng)計(jì)組件屬性的使用情況解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
node實(shí)現(xiàn)socket鏈接與GPRS進(jìn)行通信的方法
這篇文章主要介紹了node實(shí)現(xiàn)socket鏈接與GPRS進(jìn)行通信的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
nodejs?express實(shí)現(xiàn)中間件
這篇文章主要為大家介紹了nodejs?express實(shí)現(xiàn)中間件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Node.js 多線程實(shí)戰(zhàn)小結(jié)
在?Node.js?的世界中,多線程技術(shù)一直是一個(gè)受到廣泛關(guān)注的領(lǐng)域,本文主要介紹了Node.js 多線程實(shí)戰(zhàn)小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
利用Node.js了解與測(cè)量HTTP所花費(fèi)的時(shí)間詳解
這篇文章主要給大家介紹了關(guān)于利用Node.js了解與測(cè)量HTTP所花費(fèi)的時(shí)間的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09
基于Node.js實(shí)現(xiàn)nodemailer郵件發(fā)送
Nodemailer 是一個(gè)簡(jiǎn)單易用的 Node.JS 郵件發(fā)送模塊(通過(guò) SMTP,sendmail,或者 Amazon SES),支持 unicode,你可以使用任何你喜歡的字符集。Nodemailer是一個(gè)簡(jiǎn)單易用的Node.js郵件發(fā)送組件,需要的朋友可以參考下2016-01-01
Node.js與MySQL交互操作及其注意事項(xiàng)
這篇文章給大家主要介紹了Node.js與MySQL交互操作及其注意事項(xiàng),非常的詳細(xì),有相同需求的小伙伴可以參考下2016-10-10
從零開始學(xué)習(xí)Node.js系列教程五:服務(wù)器監(jiān)聽(tīng)方法示例
這篇文章主要介紹了Node.js服務(wù)器監(jiān)聽(tīng)方法,結(jié)合實(shí)例形式分析了nodejs事件監(jiān)聽(tīng)相關(guān)操作技巧,需要的朋友可以參考下2017-04-04

