效率党必藏! JavaScript 自动化脚本,覆盖文件管理、天气查询、通知提醒(含详细 demo)

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),粘贴代码并修改sourceDirbackupDir为实际路径。
  • 运行方式 :在终端执行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)。
  • 注意事项 :若备份目录不存在,脚本会报错,建议在函数开头添加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 // 预定发送时间
);

使用说明与优化建议

  • 前置准备

    1. 执行npm init -y初始化项目(生成package.json)。

    2. 安装依赖:npm install nodemailer dotenvdotenv用于管理环境变量)。

    3. 在项目根目录创建.env文件,写入敏感信息:

      env 复制代码
      EMAIL_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.watchAPI,能实时监听指定目录的文件事件,并输出详细的变化信息。

核心代码

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)对"子目录变化"的监听支持有限,若需监控多级目录,可使用第三方库chokidarnpm 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') // 可选:自定义提示音路径
);

使用说明与优化建议

  • 前置准备
    1. 安装依赖:npm install node-notifier(若需点击通知打开链接,额外安装npm install open)。
    2. 通知图标(可选):准备一张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);

使用说明与优化建议

  • 安全提示
    1. 首次使用务必设置isDryRun = true,先模拟清理(只打印待删除文件),确认无重要文件后再改为false执行实际删除。
    2. 避免直接清理系统目录(如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. 文本文件翻译脚本:快速实现多语言转换

工作中常需要翻译英文文档、产品说明,或把中文内容翻译成其他语言。这个脚本基于免费的LibreTranslateAPI,支持将文本文件从一种语言翻译为另一种语言(如英文→中文、中文→西班牙语),无需手动复制粘贴到翻译工具,高效且免费。

核心代码

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.pdfchapter2.pdf)。
    • 按修改时间排序:适合需要优先合并最新编辑的PDF场景(如最新的发票排在前面)。
    • 自定义顺序:可传入排序函数,如按文件大小、按特定关键词(如"封面""正文""附录")排序。
  • 大型PDF处理 :若合并的PDF文件较多或体积较大,建议确保Node.js内存充足(可通过node --max-old-space-size=4096 merge-pdfs.js增加内存限制)。

9. 批量重命名文件脚本:规范文件命名,提升管理效率

下载的图片、视频或文档常存在命名混乱的问题(如IMG_20240515.jpg未命名文件1.pdf),不利于查找与管理。这个脚本能按指定前缀和序号批量重命名文件(如report_001.pdfreport_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. 天气数据抓取脚本:实时获取城市天气信息

出门前查看天气、安排出差时了解目的地气候,都需要实时天气数据。这个脚本基于OpenWeatherMapAPI,支持通过城市名获取当前天气(温度、天气状况、湿度等),并以清晰的格式输出,还可扩展为"定时推送天气到邮箱"的功能。

核心代码

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密钥获取
    1. 访问OpenWeatherMap官网注册账号。
    2. 登录后,在"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库,将名言与背景图合成,生成可分享的图片。
相关推荐
龙在天4 分钟前
npm run dev 做了什么❓小白也能看懂
前端
hellokai1 小时前
React Native新架构源码分析
android·前端·react native
li理1 小时前
鸿蒙应用开发完全指南:深度解析UIAbility、页面与导航的生命周期
前端·harmonyos
去伪存真1 小时前
因为rolldown-vite比vite打包速度快, 所以必须把rolldown-vite在项目中用起来🤺
前端
KubeSphere1 小时前
Kubernetes v1.34 重磅发布:调度更快,安全更强,AI 资源管理全面进化
前端
码出极致2 小时前
支付平台资金强一致实践:基于 Seata TCC+DB 模式的余额扣减与渠道支付落地案例
后端·面试
wifi歪f2 小时前
🎉 Stenciljs,一个Web Components框架新体验
前端·javascript
1024小神2 小时前
如何快速copy复制一个网站,或是将网站本地静态化访问
前端
掘金一周2 小时前
DeepSeek删豆包冲上热搜,大模型世子之争演都不演了 | 掘金一周 8.28
前端·人工智能·后端
moyu842 小时前
前端存储三剑客:Cookie、LocalStorage 与 SessionStorage 全方位解析
前端