JavaScript脚本,轻松自动化你的日常任务
在日常工作与学习中,我们常常会被文件备份、邮件发送、格式转换等重复性任务占用大量时间。而JavaScript(尤其是基于Node.js的脚本)凭借其强大的生态与便捷的文件、网络操作能力,能成为自动化这些任务的高效工具。本文将分享11个经过实践验证的JavaScript实用脚本,涵盖文件管理、通知提醒、数据抓取等多个场景,每个脚本均附带完整代码、使用说明及优化建议,帮你彻底解放双手,聚焦更核心的工作。
1. 自动文件备份脚本:再也不怕重要文件丢失
无论是工作文档、项目代码还是个人照片,重要文件的丢失都可能带来巨大麻烦。这个脚本能将指定源目录的所有文件批量复制到备份目录,确保你始终拥有文件的最新版本。结合定时任务(如Linux的cron或Windows的任务计划),还能实现"无人值守"的自动备份。
核心代码
javascript
// 引入Node.js内置的文件系统与路径处理模块
const fs = require('fs');
const path = require('path');
/**
* 自动备份文件函数
* @param {string} sourceFolder - 源文件目录路径(需替换为实际路径)
* @param {string} backupFolder - 备份目录路径(需替换为实际路径)
*/
function backupFiles(sourceFolder, backupFolder) {
// 读取源目录下的所有文件/文件夹
fs.readdir(sourceFolder, (err, files) => {
// 若读取目录时出错(如路径不存在),直接抛出错误
if (err) throw new Error(`读取源目录失败:${err.message}`);
// 遍历每个文件,执行复制操作
files.forEach((file) => {
// 拼接完整的源文件路径与备份路径
const sourcePath = path.join(sourceFolder, file);
const backupPath = path.join(backupFolder, file);
// 复制文件(覆盖已存在的备份文件)
fs.copyFile(sourcePath, backupPath, (err) => {
if (err) {
console.error(`备份文件 ${file} 失败:${err.message}`);
} else {
console.log(`✅ 成功备份:${file}`);
}
});
});
});
}
// 配置源目录与备份目录(请根据你的实际需求修改这两个路径)
const sourceDir = '/Users/your-name/Documents/重要工作文档'; // 示例:Mac下的工作文档目录
const backupDir = '/Volumes/移动硬盘/工作文档备份'; // 示例:移动硬盘的备份目录
// 执行备份操作
backupFiles(sourceDir, backupDir);
使用说明与优化建议
- 前置准备 :无需额外安装依赖(基于Node.js内置模块),直接创建
.js
文件(如file-backup.js
),粘贴代码并修改sourceDir
和backupDir
为实际路径。 - 运行方式 :在终端执行
node file-backup.js
即可手动触发备份。 - 定时备份配置 :
- Linux/Mac用户:通过
crontab -e
添加定时任务,例如0 2 * * * node /path/to/file-backup.js
(每天凌晨2点自动备份)。 - Windows用户:通过"控制面板→管理工具→任务计划程序",新建任务并设置触发时间与执行命令(
node.exe C:\path\to\file-backup.js
)。
- Linux/Mac用户:通过
- 注意事项 :若备份目录不存在,脚本会报错,建议在函数开头添加
fs.existsSync(backupFolder) || fs.mkdirSync(backupFolder, { recursive: true })
(自动创建不存在的备份目录)。
2. 预定电子邮件脚本:精准定时发送,告别"忘记发送"
工作中常需要在特定时间发送邮件(如凌晨的报表、会议前的提醒),但手动等待发送既低效又容易遗忘。这个脚本基于nodemailer
库,支持设置任意未来时间,自动触发邮件发送,且通过环境变量存储敏感信息(如邮箱密码),避免安全风险。
核心代码
javascript
// 引入邮件发送库nodemailer(需提前安装:npm install nodemailer)
const nodemailer = require('nodemailer');
// 引入dotenv库(可选,用于加载环境变量,避免硬编码敏感信息)
require('dotenv').config();
/**
* 预定电子邮件发送函数
* @param {string} toEmail - 收件人邮箱地址(如:"user@example.com")
* @param {string} subject - 邮件主题
* @param {string} body - 邮件正文(支持纯文本或HTML格式)
* @param {number} sendTime - 发送时间的时间戳(毫秒级,如:Date.now() + 60000 表示1分钟后发送)
*/
function sendScheduledEmail(toEmail, subject, body, sendTime) {
// 计算当前时间到发送时间的延迟(毫秒)
const delay = sendTime - Date.now();
// 若延迟为负(即发送时间已过),提示错误并终止
if (delay < 0) {
console.error('❌ 错误:预定的发送时间已过期,请设置未来的时间');
return;
}
// 延迟指定时间后执行邮件发送
setTimeout(() => {
// 配置邮件发送器(以Gmail为例,其他邮箱需调整service或host)
const transporter = nodemailer.createTransport({
service: 'gmail', // 邮箱服务提供商(如:"qq"、"163",或手动指定host: "smtp.163.com")
auth: {
user: process.env.EMAIL_USER, // 发件人邮箱(从环境变量读取,避免硬编码)
pass: process.env.EMAIL_PASS, // 邮箱授权码(非登录密码,需在邮箱设置中开启SMTP并获取)
},
});
// 配置邮件内容
const mailOptions = {
from: `"你的名称" <${process.env.EMAIL_USER}>`, // 发件人信息(格式:"名称 <邮箱>")
to: toEmail, // 收件人邮箱(多个收件人用逗号分隔:"a@example.com,b@example.com")
subject: subject, // 邮件主题
text: body, // 纯文本正文(若需HTML正文,可添加html: "<h1>HTML内容</h1>")
};
// 发送邮件
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error(`❌ 邮件发送失败:${error.message}`);
} else {
console.log(`✅ 邮件已成功发送!响应信息:${info.response}`);
}
});
}, delay);
}
// ------------------- 使用示例 -------------------
// 1. 设置发送时间:10秒后发送(Date.now()获取当前时间戳,加10000毫秒=10秒)
const scheduledTime = Date.now() + 10000;
// 2. 调用函数发送邮件(替换为你的实际需求)
sendScheduledEmail(
'recipient@example.com', // 收件人邮箱
'项目进度提醒', // 邮件主题
'您好!提醒您本周项目进度需在周五前提交,感谢配合!', // 邮件正文
scheduledTime // 预定发送时间
);
使用说明与优化建议
-
前置准备 :
-
执行
npm init -y
初始化项目(生成package.json
)。 -
安装依赖:
npm install nodemailer dotenv
(dotenv
用于管理环境变量)。 -
在项目根目录创建
.env
文件,写入敏感信息:envEMAIL_USER=your-email@gmail.com # 你的发件人邮箱 EMAIL_PASS=your-app-password # 邮箱授权码(非登录密码,Gmail需开启2FA后生成应用专用密码)
-
-
邮箱配置注意事项 :
- Gmail:需开启"两步验证",并生成"应用专用密码"(登录Gmail后,在"账户设置→安全"中配置)。
- 国内邮箱(如QQ、163):需在邮箱设置中开启"SMTP服务",并获取对应的授权码。
-
扩展功能 :可添加"附件发送"功能(在
mailOptions
中添加attachments: [{ filename: 'report.pdf', path: '/path/to/report.pdf' }]
)。
3. 目录监控脚本:实时跟踪文件变化
在团队协作中,共享文件夹的文件修改、新增或删除需要及时感知;开发时,也常需要监控代码目录的变化以自动触发构建。这个脚本基于Node.js的fs.watch
API,能实时监听指定目录的文件事件,并输出详细的变化信息。
核心代码
javascript
const fs = require('fs');
const path = require('path');
/**
* 监控目录变化函数
* @param {string} pathToWatch - 待监控的目录路径(需替换为实际路径)
*/
function monitorFolder(pathToWatch) {
// 验证目录是否存在
if (!fs.existsSync(pathToWatch)) {
throw new Error(`待监控的目录不存在:${pathToWatch}`);
}
console.log(`📊 已开始监控目录:${pathToWatch}`);
console.log('----------------------------------------');
// 监听目录变化(支持rename和change两种事件)
fs.watch(pathToWatch, (eventType, filename) => {
// eventType:事件类型(rename=文件新增/删除/重命名;change=文件内容修改)
// filename:发生变化的文件名(部分系统可能返回undefined,需处理)
if (!filename) {
console.log(`⚠️ 检测到目录变化,但未获取到文件名`);
return;
}
// 拼接完整的文件路径
const filePath = path.join(pathToWatch, filename);
// 获取当前时间(用于日志记录)
const currentTime = new Date().toLocaleString();
// 根据事件类型输出不同的日志
switch (eventType) {
case 'rename':
// 检查文件是否存在(存在=新增/重命名,不存在=删除)
const fileExists = fs.existsSync(filePath);
console.log(`[${currentTime}] 📝 ${fileExists ? '新增/重命名文件' : '删除文件'}:${filename}`);
break;
case 'change':
console.log(`[${currentTime}] 🔄 修改文件内容:${filename}`);
break;
default:
console.log(`[${currentTime}] ⚠️ 未知事件类型:${eventType},涉及文件:${filename}`);
}
});
}
// 配置待监控的目录(替换为你的实际目录,如共享文档或项目代码目录)
const targetFolder = '/Users/your-name/Shared/团队共享文件';
// 启动监控
monitorFolder(targetFolder);
使用说明与优化建议
- 运行方式 :保存为
folder-monitor.js
,执行node folder-monitor.js
,脚本会持续运行并输出目录变化日志(按Ctrl+C
终止)。 - 典型用例 :
- 监控团队共享文件夹,及时发现同事上传的新文件或修改的文档。
- 配合前端项目:监控
src
目录,当代码文件修改时,自动触发webpack
构建(需额外集成构建工具)。
- 局限性 :
fs.watch
在部分系统(如Windows)对"子目录变化"的监听支持有限,若需监控多级目录,可使用第三方库chokidar
(npm install chokidar
),其兼容性更强且支持递归监听。
4. 图像转PDF脚本:批量生成扫描件或电子相册
工作中常需要将多张扫描的图片(如合同、发票)合并为一个PDF文件,方便归档与分享;生活中也可能需要将旅行照片整理成电子相册。这个脚本基于pdfkit
库,能自动读取指定目录的所有图片(支持JPG/PNG格式),按顺序插入PDF并生成最终文件。
核心代码
javascript
const fs = require('fs');
const path = require('path');
// 引入PDF生成库pdfkit(需安装:npm install pdfkit)
const PDFDocument = require('pdfkit');
/**
* 批量将图像转换为PDF文件
* @param {string} imageFolder - 存放图像的目录路径(需替换为实际路径)
* @param {string} outputPDF - 生成的PDF文件路径(如:"output.pdf")
*/
function imagesToPDF(imageFolder, outputPDF) {
// 验证图像目录是否存在
if (!fs.existsSync(imageFolder)) {
throw new Error(`图像目录不存在:${imageFolder}`);
}
// 创建PDF文档实例
const doc = new PDFDocument({
size: 'A4', // PDF页面尺寸(可选:'A3'/'Letter'/'Legal'等)
margin: 20 // 页面边距(避免图片紧贴边缘)
});
// 创建写入流,用于将PDF内容写入文件
const writeStream = fs.createWriteStream(outputPDF);
doc.pipe(writeStream); // 将PDF文档与写入流关联
// 读取图像目录下的所有文件,并筛选出图片文件
fs.readdir(imageFolder, (err, files) => {
if (err) throw new Error(`读取图像目录失败:${err.message}`);
// 筛选JPG/JPEG/PNG格式的文件(不区分大小写)
const imageFiles = files.filter(file =>
/\.(jpg|jpeg|png)$/i.test(path.extname(file))
);
if (imageFiles.length === 0) {
console.warn('⚠️ 图像目录中未找到任何JPG/PNG文件');
doc.end(); // 关闭PDF文档
return;
}
console.log(`📷 找到 ${imageFiles.length} 张图片,开始生成PDF...`);
// 遍历每张图片,插入到PDF中
imageFiles.forEach((file, index) => {
const imagePath = path.join(imageFolder, file);
// 除第一张图片外,其余图片均新增一页(避免多图挤在同一页)
if (index !== 0) {
doc.addPage(); // 新增PDF页面
}
// 将图片插入当前页面(配置自适应尺寸与居中显示)
doc.image(imagePath, {
fit: [550, 750], // 图片最大尺寸(适配A4页面,避免超出边界)
align: 'center', // 水平居中
valign: 'center' // 垂直居中
});
// 在图片下方添加文件名(可选,便于识别图片来源)
doc.moveDown(2) // 向下移动2行距离
.fontSize(10)
.text(`图片来源:${file}`, { align: 'center' });
});
// 结束PDF文档生成
doc.end();
});
// 监听写入流完成事件(提示PDF生成成功)
writeStream.on('finish', () => {
console.log(`✅ PDF生成完成!文件路径:${path.resolve(outputPDF)}`);
});
// 监听写入流错误事件(捕获生成过程中的异常)
writeStream.on('error', (err) => {
console.error(`❌ PDF生成失败:${err.message}`);
});
}
// ------------------- 使用示例 -------------------
const imageDir = '/Users/your-name/Desktop/扫描件'; // 存放扫描图片的目录
const outputPath = '/Users/your-name/Desktop/扫描件合集.pdf'; // 生成的PDF路径
imagesToPDF(imageDir, outputPath);
使用说明与优化建议
- 前置准备 :执行
npm install pdfkit
安装依赖,确保图像目录中的图片格式为JPG或PNG(若需支持其他格式,可先通过图像工具转换)。 - 优化方向 :
- 图片排序:脚本默认按文件名排序,若需按"修改时间"排序,可通过
fs.stat
获取文件修改时间后再排序。 - 压缩图片:若图片体积过大导致PDF文件臃肿,可先使用
sharp
库(npm install sharp
)批量压缩图片,再执行转PDF操作。
- 图片排序:脚本默认按文件名排序,若需按"修改时间"排序,可通过
- 典型场景:扫描合同后生成统一的PDF文件、将手机拍摄的纸质文档图片整理为可打印的PDF、制作旅行照片电子相册等。
5. 桌面通知提醒脚本:重要事项不再错过
工作中的会议、待办事项,生活中的约会、提醒,都可能因忙碌而遗忘。这个脚本基于node-notifier
库,支持设置未来时间,在指定时刻弹出系统桌面通知(支持Windows、Mac、Linux),并可配置提示音,确保你不会错过任何重要事项。
核心代码
javascript
// 引入桌面通知库(需安装:npm install node-notifier)
const notifier = require('node-notifier');
const path = require('path');
/**
* 桌面通知提醒函数
* @param {string} title - 通知标题(如:"会议提醒")
* @param {string} message - 通知内容(如:"下午3点项目会议")
* @param {number} notificationTime - 通知触发时间(毫秒级时间戳)
* @param {string} [soundPath] - 提示音路径(可选,支持mp3/wav格式)
*/
function desktopNotifier(title, message, notificationTime, soundPath) {
// 计算延迟时间(当前时间到通知时间的差值)
const delay = notificationTime - Date.now();
// 处理延迟为负的情况(通知时间已过)
if (delay < 0) {
console.error('❌ 错误:通知时间已过期,请设置未来的时间');
return;
}
console.log(`⏰ 已预约通知:【${title}】,将在 ${new Date(notificationTime).toLocaleString()} 提醒`);
// 延迟指定时间后触发通知
setTimeout(() => {
// 配置通知选项
const notificationOptions = {
title: title, // 通知标题
message: message, // 通知内容(支持换行,用\n分隔)
icon: path.join(__dirname, 'reminder-icon.png'), // 通知图标(可选,替换为你的图标路径)
sound: soundPath ? soundPath : true, // 提示音(true表示使用系统默认提示音)
wait: true, // 点击通知后才关闭(避免被忽略)
};
// 发送桌面通知
notifier.notify(notificationOptions, (err, response) => {
if (err) {
console.error(`❌ 通知发送失败:${err.message}`);
} else {
console.log(`✅ 通知已发送!用户响应:${response}`);
}
});
// 监听通知的点击事件(可选,如点击后打开相关文件/链接)
notifier.on('click', () => {
console.log(`👆 用户点击了【${title}】通知`);
// 示例:点击通知后打开浏览器访问指定链接(需引入open库:npm install open)
// const open = require('open');
// open('https://docs.google.com/document/d/xxx'); // 如打开会议文档
});
}, delay);
}
// ------------------- 使用示例 -------------------
// 1. 设置通知时间:15秒后触发(Date.now() + 15000毫秒)
const remindTime = Date.now() + 15000;
// 2. 调用函数发送预约通知
desktopNotifier(
'团队会议提醒', // 通知标题
'📅 下午3点在会议室A召开项目进度会议\n📎 请提前准备上周进度报告', // 通知内容(支持换行)
remindTime, // 通知时间
// path.join(__dirname, 'reminder-sound.mp3') // 可选:自定义提示音路径
);
使用说明与优化建议
- 前置准备 :
- 安装依赖:
npm install node-notifier
(若需点击通知打开链接,额外安装npm install open
)。 - 通知图标(可选):准备一张PNG格式的图标文件(建议尺寸256x256),放在脚本同级目录,修改
icon
路径为实际文件名。
- 安装依赖:
- 系统兼容性 :
- Mac:通知会显示在右上角,支持提示音;
- Windows:通知显示在右下角(操作中心),需确保"通知"权限已开启;
- Linux:依赖
libnotify-bin
,需先执行sudo apt-get install libnotify-bin
安装。
- 扩展场景:可结合"日历API"(如Google Calendar)获取日程,自动生成通知;或配合"待办事项列表",到期自动提醒。
6. 自动清理旧文件脚本:释放磁盘空间,告别文件堆积
电脑使用时间久了,下载目录、日志目录常会堆积大量过期文件(如1个月前的安装包、半年前的日志),占用宝贵的磁盘空间。这个脚本能自动扫描指定目录,删除超过设定天数的文件,帮你定期"断舍离",保持磁盘整洁。
核心代码
javascript
const fs = require('fs');
const path = require('path');
/**
* 自动清理旧文件函数
* @param {string} folder - 待清理的目录路径(需替换为实际路径)
* @param {number} days - 过期天数(超过此天数的文件将被删除)
* @param {boolean} [dryRun=false] - 模拟清理(true=只打印要删除的文件,不实际删除)
*/
function cleanOldFiles(folder, days, dryRun = false) {
// 验证目录是否存在
if (!fs.existsSync(folder)) {
throw new Error(`待清理的目录不存在:${folder}`);
}
// 计算"过期时间点"(当前时间 - 天数×毫秒数)
const now = Date.now();
const cutoffTime = now - days * 24 * 60 * 60 * 1000; // 1天=24h×60min×60s×1000ms
console.log(`🗑️ 开始清理目录:${folder}`);
console.log(`⏳ 清理规则:删除超过 ${days} 天未修改的文件`);
console.log(`📅 过期时间点:${new Date(cutoffTime).toLocaleString()}`);
console.log(`🔍 正在扫描文件...`);
// 读取目录下的所有文件/文件夹
fs.readdir(folder, (err, files) => {
if (err) throw new Error(`读取清理目录失败:${err.message}`);
// 存储待删除的文件列表(用于最终统计)
const filesToDelete = [];
// 遍历每个文件,检查是否过期
files.forEach((file) => {
const filePath = path.join(folder, file);
// 获取文件的状态信息(如修改时间、是否为目录)
fs.stat(filePath, (err, stat) => {
if (err) {
console.error(`⚠️ 获取文件 ${file} 状态失败:${err.message}`);
return;
}
// 跳过目录(只删除文件,不删除子目录)
if (stat.isDirectory()) {
console.log(`📁 跳过目录:${file}`);
return;
}
// 检查文件修改时间是否早于过期时间点
const fileModifyTime = stat.mtime.getTime();
if (fileModifyTime < cutoffTime) {
filesToDelete.push(file);
// 若不是模拟清理,则执行删除操作
if (!dryRun) {
fs.unlink(filePath, (err) => {
if (err) {
console.error(`❌ 删除文件 ${file} 失败:${err.message}`);
} else {
console.log(`✅ 已删除过期文件:${file}(最后修改时间:${new Date(fileModifyTime).toLocaleString()})`);
}
});
} else {
// 模拟清理:只打印,不删除
console.log(`📝 模拟删除:${file}(最后修改时间:${new Date(fileModifyTime).toLocaleString()})`);
}
}
});
});
// 扫描完成后输出统计信息(延迟1秒,确保文件状态读取完成)
setTimeout(() => {
console.log('----------------------------------------');
console.log(`🔚 扫描完成!共发现 ${filesToDelete.length} 个过期文件`);
if (dryRun) {
console.log(`ℹ️ 提示:当前为模拟清理模式,未实际删除文件。若需执行删除,请将dryRun设为false。`);
}
}, 1000);
});
}
// ------------------- 使用示例 -------------------
const targetDir = '/Users/your-name/Downloads'; // 待清理目录(如下载目录)
const expireDays = 30; // 清理超过30天的文件
const isDryRun = true; // 先执行模拟清理(确认无误后改为false)
// 执行清理(首次使用建议先模拟,避免误删重要文件)
cleanOldFiles(targetDir, expireDays, isDryRun);
使用说明与优化建议
- 安全提示 :
- 首次使用务必设置
isDryRun = true
,先模拟清理(只打印待删除文件),确认无重要文件后再改为false
执行实际删除。 - 避免直接清理系统目录(如
C:\Windows
或/usr
),防止误删系统文件导致崩溃。
- 首次使用务必设置
- 定时清理 :结合Linux的cron或Windows的任务计划,设置每月1日自动清理下载目录(如
0 0 1 * * node /path/to/clean-old-files.js
)。 - 扩展功能 :可添加"白名单"功能(如
const whitelist = ['important-file.txt', 'backup.zip']
),跳过无需删除的关键文件。
7. 文本文件翻译脚本:快速实现多语言转换
工作中常需要翻译英文文档、产品说明,或把中文内容翻译成其他语言。这个脚本基于免费的LibreTranslate
API,支持将文本文件从一种语言翻译为另一种语言(如英文→中文、中文→西班牙语),无需手动复制粘贴到翻译工具,高效且免费。
核心代码
javascript
const fs = require('fs');
const path = require('path');
// 引入HTTP请求库axios(需安装:npm install axios)
const axios = require('axios');
/**
* 翻译文本函数(基于LibreTranslate免费API)
* @param {string} text - 待翻译的文本内容
* @param {string} sourceLang - 源语言(如:"en"=英文,"zh"=中文,"es"=西班牙语)
* @param {string} targetLang - 目标语言(同上)
* @returns {Promise<string>} 翻译后的文本
*/
async function translateText(text, sourceLang = 'en', targetLang = 'zh') {
try {
// 发送POST请求到LibreTranslate API(免费,无需API密钥)
const response = await axios.post('https://libretranslate.de/translate', {
q: text, // 待翻译文本
source: sourceLang, // 源语言
target: targetLang, // 目标语言
format: 'text', // 文本格式(支持"text"或"html")
});
// 返回翻译后的文本
return response.data.translatedText;
} catch (err) {
throw new Error(`翻译失败:${err.response?.data?.error || err.message}`);
}
}
/**
* 翻译文本文件(批量处理整个文件)
* @param {string} inputPath - 输入文本文件路径(如:"original.txt")
* @param {string} outputPath - 输出翻译文件路径(如:"translated-zh.txt")
* @param {string} sourceLang - 源语言
* @param {string} targetLang - 目标语言
*/
async function translateTextFile(inputPath, outputPath, sourceLang, targetLang) {
// 验证输入文件是否存在
if (!fs.existsSync(inputPath)) {
throw new Error(`输入文件不存在:${inputPath}`);
}
console.log(`🌐 开始翻译文件:${inputPath}`);
console.log(`📋 翻译方向:${sourceLang} → ${targetLang}`);
try {
// 1. 读取输入文件的文本内容(支持UTF-8编码)
const originalText = fs.readFileSync(inputPath, 'utf8');
console.log(`📖 成功读取输入文件,文本长度:${originalText.length} 字符`);
// 2. 调用翻译函数处理文本
const translatedText = await translateText(originalText, sourceLang, targetLang);
// 3. 将翻译后的文本写入输出文件
fs.writeFileSync(outputPath, translatedText, 'utf8');
console.log(`✅ 翻译完成!输出文件路径:${path.resolve(outputPath)}`);
} catch (err) {
console.error(`❌ 翻译文件失败:${err.message}`);
}
}
// ------------------- 使用示例 -------------------
// 示例1:将英文文件翻译成中文
translateTextFile(
'/Users/your-name/Documents/product-en.txt', // 输入英文文件
'/Users/your-name/Documents/product-zh.txt', // 输出中文文件
'en', // 源语言:英文
'zh' // 目标语言:中文
);
// 示例2:将中文文件翻译成西班牙语(需将sourceLang改为"zh",targetLang改为"es")
// translateTextFile(
// '/Users/your-name/Documents/notes-zh.txt',
// '/Users/your-name/Documents/notes-es.txt',
// 'zh',
// 'es'
// );
使用说明与优化建议
- API说明 :
LibreTranslate
是免费开源的翻译API,无需注册密钥,适合小型翻译需求(单请求文本长度有限制,若翻译大文件需分割文本)。若需更高稳定性与更长文本支持,可改用Google Translate API(需注册并获取API密钥,收费但额度较低时免费)。 - 支持语言 :
LibreTranslate
支持20+种语言,常见语言代码:英文(en)、中文(zh)、西班牙语(es)、法语(fr)、德语(de)、日语(ja)等。 - 大文件处理:若输入文件过大(如超过5000字符),可添加"文本分割"逻辑,将文本按段落或句子分割后逐段翻译,最后合并结果。
8. 多PDF合并脚本:一键整合分散的PDF文档
工作中常需要将多个分散的PDF文件(如项目报告的各个章节、多份发票)合并为一个完整文件,方便分享与打印。这个脚本基于pdf-merger-js
库,支持批量读取指定目录的所有PDF,按顺序合并为一个文件,且支持自定义合并顺序。
核心代码
javascript
const fs = require('fs');
const path = require('path');
// 引入PDF合并库(需安装:npm install pdf-merger-js)
const PDFMerger = require('pdf-merger-js');
/**
* 批量合并PDF文件
* @param {string} pdfFolder - 存放待合并PDF的目录路径
* @param {string} outputPDF - 合并后的输出PDF路径
* @param {function} [sortFn] - 自定义排序函数(可选,用于调整PDF合并顺序)
*/
async function mergePDFs(pdfFolder, outputPDF, sortFn) {
// 验证PDF目录是否存在
if (!fs.existsSync(pdfFolder)) {
throw new Error(`PDF目录不存在:${pdfFolder}`);
}
// 1. 读取目录下的所有PDF文件
const files = fs.readdirSync(pdfFolder);
// 筛选出后缀为.pdf的文件(不区分大小写)
let pdfFiles = files.filter(file =>
path.extname(file).toLowerCase() === '.pdf'
);
// 若未找到PDF文件,抛出错误
if (pdfFiles.length === 0) {
throw new Error(`PDF目录中未找到任何PDF文件:${pdfFolder}`);
}
// 2. 按自定义规则排序(默认按文件名升序,可选传入sortFn调整顺序)
if (sortFn && typeof sortFn === 'function') {
pdfFiles.sort(sortFn);
} else {
// 默认按文件名升序排序(如:1.pdf → 2.pdf → 3.pdf)
pdfFiles.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
}
console.log(`📄 找到 ${pdfFiles.length} 个待合并PDF文件`);
console.log(`🔀 合并顺序:${pdfFiles.join(' → ')}`);
// 3. 创建PDF合并实例
const merger = new PDFMerger();
try {
// 遍历PDF文件,添加到合并队列
for (const file of pdfFiles) {
const pdfPath = path.join(pdfFolder, file);
// 验证文件是否为有效PDF(避免目录或非PDF文件)
if (fs.statSync(pdfPath).isFile()) {
await merger.add(pdfPath); // 添加PDF到合并队列
console.log(`✅ 已添加:${file}`);
}
}
// 4. 执行合并并保存到输出文件
await merger.save(outputPDF);
console.log(`🎉 PDF合并完成!输出路径:${path.resolve(outputPDF)}`);
} catch (err) {
throw new Error(`PDF合并失败:${err.message}`);
}
}
// ------------------- 使用示例 -------------------
// 示例1:默认按文件名升序合并(如:chapter1.pdf → chapter2.pdf)
const pdfDir = '/Users/your-name/Documents/项目报告章节'; // 待合并PDF目录
const outputPath = '/Users/your-name/Documents/项目报告-完整版.pdf'; // 输出路径
// 执行合并(默认排序)
mergePDFs(pdfDir, outputPath)
.catch(err => console.error(`❌ 操作失败:${err.message}`));
// 示例2:按"文件修改时间"排序(最新修改的PDF排在前面)
// mergePDFs(
// pdfDir,
// outputPath,
// (a, b) => {
// // 获取两个文件的修改时间
// const timeA = fs.statSync(path.join(pdfDir, a)).mtime.getTime();
// const timeB = fs.statSync(path.join(pdfDir, b)).mtime.getTime();
// return timeB - timeA; // 降序排序(最新的在前)
// }
// ).catch(err => console.error(`❌ 操作失败:${err.message}`));
使用说明与优化建议
- 前置准备 :安装依赖
npm install pdf-merger-js
,确保待合并的PDF文件无损坏(若某文件损坏,会导致合并失败,需先修复或移除该文件)。 - 排序需求 :
- 按文件名排序:适合文件命名有规律的场景(如
chapter1.pdf
、chapter2.pdf
)。 - 按修改时间排序:适合需要优先合并最新编辑的PDF场景(如最新的发票排在前面)。
- 自定义顺序:可传入排序函数,如按文件大小、按特定关键词(如"封面""正文""附录")排序。
- 按文件名排序:适合文件命名有规律的场景(如
- 大型PDF处理 :若合并的PDF文件较多或体积较大,建议确保Node.js内存充足(可通过
node --max-old-space-size=4096 merge-pdfs.js
增加内存限制)。
9. 批量重命名文件脚本:规范文件命名,提升管理效率
下载的图片、视频或文档常存在命名混乱的问题(如IMG_20240515.jpg
、未命名文件1.pdf
),不利于查找与管理。这个脚本能按指定前缀和序号批量重命名文件(如report_001.pdf
、report_002.pdf
),支持自定义前缀、序号位数,且能保留文件原始扩展名。
核心代码
javascript
const fs = require('fs');
const path = require('path');
/**
* 批量重命名文件函数
* @param {string} folder - 待重命名文件所在的目录路径
* @param {string} prefix - 新文件名的前缀(如:"image" → "image_001.jpg")
* @param {number} [startIndex=1] - 起始序号(默认从1开始)
* @param {number} [digitLength=3] - 序号位数(默认3位,如:001、002)
* @param {string[]} [excludeExts=[]] - 排除的文件扩展名(如:['.txt'],不重命名txt文件)
*/
function batchRename(folder, prefix, startIndex = 1, digitLength = 3, excludeExts = []) {
// 验证目录是否存在
if (!fs.existsSync(folder)) {
throw new Error(`待重命名的目录不存在:${folder}`);
}
// 读取目录下的所有文件(不包含子目录)
fs.readdir(folder, (err, files) => {
if (err) throw new Error(`读取目录失败:${err.message}`);
// 过滤掉目录,只保留文件
const fileList = files.filter(file =>
fs.statSync(path.join(folder, file)).isFile()
);
if (fileList.length === 0) {
console.warn('⚠️ 目录中未找到任何文件,无需重命名');
return;
}
console.log(`📁 开始批量重命名目录:${folder}`);
console.log(`📋 重命名规则:${prefix}_[序号].扩展名(序号从${startIndex}开始,共${digitLength}位)`);
console.log(`🚫 排除的扩展名:${excludeExts.length > 0 ? excludeExts.join(', ') : '无'}`);
console.log('----------------------------------------');
// 遍历文件,执行重命名
fileList.forEach((oldFileName, index) => {
// 1. 获取文件原始扩展名(如:.jpg、.pdf)
const ext = path.extname(oldFileName).toLowerCase();
// 2. 检查是否需要排除该扩展名
if (excludeExts.includes(ext)) {
console.log(`⚠️ 排除文件:${oldFileName}(扩展名${ext}在排除列表中)`);
return;
}
// 3. 计算当前文件的序号(起始序号 + 索引)
const currentIndex = startIndex + index;
// 用0填充序号,确保位数统一(如:1 → 001,10 → 010)
const paddedIndex = String(currentIndex).padStart(digitLength, '0');
// 4. 拼接新文件名(前缀 + 序号 + 原始扩展名)
const newFileName = `${prefix}_${paddedIndex}${ext}`;
// 5. 拼接旧路径与新路径
const oldPath = path.join(folder, oldFileName);
const newPath = path.join(folder, newFileName);
// 6. 避免新文件名与现有文件冲突
if (fs.existsSync(newPath) && oldPath !== newPath) {
console.error(`❌ 重命名失败:${newFileName} 已存在,跳过 ${oldFileName}`);
return;
}
// 7. 执行重命名操作
fs.rename(oldPath, newPath, (err) => {
if (err) {
console.error(`❌ 重命名 ${oldFileName} 失败:${err.message}`);
} else {
console.log(`✅ 重命名成功:${oldFileName} → ${newFileName}`);
}
});
});
});
}
// ------------------- 使用示例 -------------------
// 示例1:批量重命名下载的图片(前缀"vacation_photo",序号3位,排除.txt文件)
batchRename(
'/Users/your-name/Downloads/旅行照片', // 待重命名目录
'vacation_photo', // 文件名前缀
1, // 起始序号
3, // 序号位数(001~999)
['.txt'] // 排除.txt文件(不重命名文本文件)
);
// 示例2:重命名项目文档(前缀"project_report",序号2位,从10开始)
// batchRename(
// '/Users/your-name/Documents/项目文档',
// 'project_report',
// 10, // 起始序号10 → 10、11、12...
// 2, // 序号位数(01~99,10 → 10,11 → 11)
// [] // 不排除任何扩展名
// );
使用说明与优化建议
- 关键参数说明 :
prefix
:根据文件类型命名(如图片用image
,文档用document
),便于识别。digitLength
:序号位数建议根据文件数量设置(如100个文件用3位,避免100 → 00100的问题)。excludeExts
:用于保留目录中的关键文件(如README.txt
,避免被误重命名)。
- 避免冲突:脚本会检查新文件名是否已存在,若存在则跳过该文件,防止覆盖现有文件。
- 扩展功能 :可添加"按文件类型分类重命名"(如图片用
image_xxx
,PDF用pdf_xxx
),通过判断ext
来动态设置prefix
。
10. 天气数据抓取脚本:实时获取城市天气信息
出门前查看天气、安排出差时了解目的地气候,都需要实时天气数据。这个脚本基于OpenWeatherMap
API,支持通过城市名获取当前天气(温度、天气状况、湿度等),并以清晰的格式输出,还可扩展为"定时推送天气到邮箱"的功能。
核心代码
javascript
const axios = require('axios');
/**
* 获取指定城市的当前天气信息
* @param {string} city - 城市名称(如:"New York"、"Beijing")
* @param {string} apiKey - OpenWeatherMap API密钥(需自行注册获取)
* @param {string} [units=metric] - 温度单位(metric=摄氏度,imperial=华氏度)
* @param {string} [lang=zh_cn] - 语言(zh_cn=中文,en=英文)
*/
async function getWeather(city, apiKey, units = 'metric', lang = 'zh_cn') {
// 验证API密钥是否存在(需用户自行注册获取)
if (!apiKey) {
throw new Error('请提供OpenWeatherMap API密钥(注册地址:https://openweathermap.org/)');
}
try {
// 调用OpenWeatherMap API获取天气数据
const response = await axios.get('https://api.openweathermap.org/data/2.5/weather', {
params: {
q: city, // 城市名
appid: apiKey, // API密钥
units: units, // 温度单位
lang: lang // 响应语言
}
});
// 提取关键天气数据(从API响应中筛选有用信息)
const weatherData = response.data;
const { temp, feels_like, humidity, pressure } = weatherData.main; // 温度、体感温度、湿度、气压
const { description, icon } = weatherData.weather[0]; // 天气状况描述、图标
const { speed } = weatherData.wind; // 风速
const { country } = weatherData.sys; // 国家代码
const sunriseTime = new Date(weatherData.sys.sunrise * 1000).toLocaleTimeString(); // 日出时间
const sunsetTime = new Date(weatherData.sys.sunset * 1000).toLocaleTimeString(); // 日落时间
// 格式化输出天气信息
console.log(`🌤️ ${city}, ${country} 当前天气`);
console.log('----------------------------------------');
console.log(`天气状况:${description.charAt(0).toUpperCase() + description.slice(1)}`); // 首字母大写
console.log(`当前温度:${temp} °C(体感温度:${feels_like} °C)`);
console.log(`湿度:${humidity}% | 气压:${pressure} hPa | 风速:${speed} m/s`);
console.log(`日出时间:${sunriseTime} | 日落时间:${sunsetTime}`);
console.log('----------------------------------------');
// 返回完整天气数据(便于后续扩展,如写入文件或发送邮件)
return weatherData;
} catch (err) {
// 处理API调用错误(如城市不存在、API密钥无效)
const errorMsg = err.response?.data?.message || err.message;
throw new Error(`获取天气失败:${errorMsg}`);
}
}
// ------------------- 使用示例 -------------------
// 1. 替换为你的OpenWeatherMap API密钥(免费注册获取:https://openweathermap.org/api)
const apiKey = 'your-openweathermap-api-key';
// 2. 获取指定城市的天气(示例:北京)
getWeather('Beijing', apiKey)
.then(() => console.log('✅ 天气数据获取完成'))
.catch(err => console.error(`❌ 操作失败:${err.message}`));
// 3. 获取其他城市天气(示例:纽约,英文输出,华氏度)
// getWeather('New York', apiKey, 'imperial', 'en')
// .then(() => console.log('✅ Weather data retrieved successfully'))
// .catch(err => console.error(`❌ Failed: ${err.message}`));
使用说明与优化建议
- API密钥获取 :
- 访问OpenWeatherMap官网注册账号。
- 登录后,在"API Keys"页面生成免费API密钥(免费版支持每小时60次请求,足够个人使用)。
- 扩展功能 :
- 定时推送:结合"自动发送邮件脚本",每天早上8点将天气信息发送到邮箱。
- 多城市查询:传入城市数组(如
['Beijing', 'Shanghai', 'Guangzhou']
),批量获取多个城市天气。 - 天气图标:API返回的
icon
字段可用于拼接图标URL(如https://openweathermap.org/img/wn/${icon}@2x.png
),在控制台或前端页面显示天气图标。
11. 随机名言生成脚本:获取灵感,点缀你的工作环境
工作疲劳时,一句励志或富有哲理的名言能带来灵感与动力。这个脚本基于quotable
免费API,支持随机获取名言、作者信息,可用于终端美化、桌面壁纸生成,或集成到项目中作为欢迎语。
核心代码
javascript
const axios = require('axios');
/**
* 获取随机名言(支持筛选标签、作者)
* @param {string[]} [tags=[]] - 筛选标签(如:["inspirational", "life"],励志、人生主题)
* @param {string} [author=undefined] - 筛选作者(如:"Albert Einstein",只获取该作者的名言)
* @returns {Promise<object>} 名言对象(包含content=名言内容,author=作者,tags=标签)
*/
async function getRandomQuote(tags = [], author = undefined) {
try {
// 构建API请求参数
const params = {};
// 若有标签筛选,拼接标签参数(多个标签用逗号分隔)
if (tags.length > 0) params.tags = tags.join(',');
// 若有作者筛选,添加作者参数
if (author) params.author = author;
// 调用quotable API获取随机名言(免费,无需API密钥)
const response = await axios.get('https://api.quotable.io/random', { params });
const quote = response.data;
// 格式化输出名言(带样式,便于阅读)
console.log('========================================');
console.log(`"${quote.content}"`);
console.log(`\n--- ${quote.author}`);
if (quote.tags.length > 0) {
console.log(`\n主题:${quote.tags.map(tag => `#${tag}`).join(' ')}`);
}
console.log('========================================');
// 返回名言对象(便于后续扩展,如写入文件、生成图片)
return quote;
} catch (err) {
const errorMsg = err.response?.data?.message || err.message;
throw new Error(`获取名言失败:${errorMsg}`);
}
}
// ------------------- 使用示例 -------------------
// 示例1:获取任意随机名言(无筛选)
console.log('🎯 获取任意随机名言:');
getRandomQuote()
.then(() => console.log('✅ 名言获取完成'))
.catch(err => console.error(`❌ 操作失败:${err.message}`));
// 示例2:获取"励志"主题的名言(标签筛选)
// console.log('\n🎯 获取励志主题名言:');
// getRandomQuote(['inspirational'])
// .then(() => console.log('✅ 名言获取完成'))
// .catch(err => console.error(`❌ 操作失败:${err.message}`));
// 示例3:获取爱因斯坦的名言(作者筛选)
// console.log('\n🎯 获取爱因斯坦的名言:');
// getRandomQuote([], 'Albert Einstein')
// .then(() => console.log('✅ 名言获取完成'))
// .catch(err => console.error(`❌ 操作失败:${err.message}`));
使用说明与优化建议
- API特点 :
quotable
是免费开源的名言API,无需注册密钥,包含数千条来自不同作者的名言,支持按主题、作者、长度筛选。 - 支持标签 :常见标签包括
inspirational
(励志)、life
(人生)、love
(爱情)、success
(成功)、happiness
(幸福)等,完整标签列表可查看quotable文档。 - 扩展场景 :
- 终端启动名言:在
.bashrc
(Linux/Mac)或profile.ps1
(Windows PowerShell)中添加node /path/to/random-quote.js
,每次打开终端自动显示一句名言。 - 名言图片生成:结合
sharp
库,将名言与背景图合成,生成可分享的图片。
- 终端启动名言:在