Node.js中XLSX库的实践使用指南

简介

XLSX是一个功能强大的JavaScript库,用于读取、写入和操作Excel文件。本文将通过实际项目案例,展示如何在Node.js环境中使用XLSX库来处理Excel文件,并将其转换为JSON格式。

项目背景

在日常开发中,我们经常需要处理Excel文件中的数据,比如从Excel表格中提取数据并转换为JSON格式用于前端展示或数据库存储。本项目演示了如何读取包含地址信息的Excel文件,并将其转换为结构化的JSON数据。

环境准备

1. 安装依赖

bash 复制代码
npm install xlsx
# 或者使用pnpm
pnpm add xlsx

2. 项目结构

bash 复制代码
xlsToJson/
├── data/              # 输出的JSON文件目录
├── index.js          # 主要处理逻辑
├── package.json      # 项目配置
└── xfs_tt.xlsx       # 待处理的Excel文件

核心代码实现

javascript 复制代码
const XLSX = require("xlsx");
const fs = require("fs");
const path = require("path");

// 读取 XLSX 文件
const workbook = XLSX.readFile("./xfs_tt.xlsx");

workbook.SheetNames.forEach((sheetName) => {
  const worksheet = workbook.Sheets[sheetName];
  const jsonData = XLSX.utils.sheet_to_json(worksheet).map((row) => {
    return {
      name: row.名称.toString() || null,
      did: row.did || null,
      address: row.地址 || null,
      area: row.区域 || null,
    };
  });

  fs.writeFileSync(
    path.resolve(__dirname, `./data/${sheetName}.json`),
    JSON.stringify(jsonData),
    "utf-8"
  );
});

代码详解

1. 读取Excel文件

javascript 复制代码
const workbook = XLSX.readFile("./xfs_tt.xlsx");

使用XLSX.readFile()方法读取Excel文件,返回一个工作簿对象。

2. 遍历工作表

javascript 复制代码
workbook.SheetNames.forEach((sheetName) => {
  // 处理每个工作表
});

Excel文件可能包含多个工作表,通过SheetNames属性获取所有工作表名称并遍历处理。

3. 转换为JSON

javascript 复制代码
const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet);

使用XLSX.utils.sheet_to_json()将工作表数据转换为JSON格式。

4. 数据映射和清理

javascript 复制代码
.map((row) => {
  return {
    name: row.名称.toString() || null,
    did: row.did || null,
    address: row.地址 || null,
    area: row.区域 || null,
  };
});

对原始数据进行映射,统一字段名称,并进行数据类型转换和空值处理。

5. 保存JSON文件

javascript 复制代码
fs.writeFileSync(
  path.resolve(__dirname, `./data/${sheetName}.json`),
  JSON.stringify(jsonData),
  "utf-8"
);

将处理后的JSON数据保存到文件系统中。

扩展功能

1. 错误处理

javascript 复制代码
const XLSX = require("xlsx");
const fs = require("fs");
const path = require("path");

try {
  // 检查文件是否存在
  if (!fs.existsSync("./xfs_tt.xlsx")) {
    throw new Error("Excel文件不存在");
  }

  // 确保输出目录存在
  const dataDir = path.resolve(__dirname, "./data");
  if (!fs.existsSync(dataDir)) {
    fs.mkdirSync(dataDir, { recursive: true });
  }

  const workbook = XLSX.readFile("./xfs_tt.xlsx");
  
  workbook.SheetNames.forEach((sheetName) => {
    try {
      const worksheet = workbook.Sheets[sheetName];
      const jsonData = XLSX.utils.sheet_to_json(worksheet).map((row) => {
        return {
          name: row.名称 ? row.名称.toString() : null,
          did: row.did || null,
          address: row.地址 || null,
          area: row.区域 || null,
        };
      });

      const outputPath = path.resolve(__dirname, `./data/${sheetName}.json`);
      fs.writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), "utf-8");
      
      console.log(`✅ 成功处理工作表: ${sheetName}`);
      console.log(`📁 输出文件: ${outputPath}`);
      console.log(`📊 数据条数: ${jsonData.length}`);
    } catch (error) {
      console.error(`❌ 处理工作表 ${sheetName} 时出错:`, error.message);
    }
  });
} catch (error) {
  console.error("❌ 程序执行出错:", error.message);
}

2. 数据验证

javascript 复制代码
function validateRow(row) {
  const errors = [];
  
  if (!row.名称) {
    errors.push("名称字段不能为空");
  }
  
  if (!row.地址) {
    errors.push("地址字段不能为空");
  }
  
  return errors;
}

// 在数据映射时使用
const jsonData = XLSX.utils.sheet_to_json(worksheet)
  .filter((row, index) => {
    const errors = validateRow(row);
    if (errors.length > 0) {
      console.warn(`第${index + 2}行数据验证失败:`, errors);
      return false;
    }
    return true;
  })
  .map((row) => {
    // ... 数据映射逻辑
  });

3. 支持多种输出格式

javascript 复制代码
function saveData(data, fileName, format = 'json') {
  const outputDir = path.resolve(__dirname, "./data");
  
  switch (format) {
    case 'json':
      fs.writeFileSync(
        path.join(outputDir, `${fileName}.json`),
        JSON.stringify(data, null, 2),
        "utf-8"
      );
      break;
    case 'csv':
      const csv = data.map(row => 
        Object.values(row).map(val => `"${val}"`).join(',')
      ).join('\n');
      const header = Object.keys(data[0]).map(key => `"${key}"`).join(',');
      fs.writeFileSync(
        path.join(outputDir, `${fileName}.csv`),
        header + '\n' + csv,
        "utf-8"
      );
      break;
    default:
      throw new Error(`不支持的输出格式: ${format}`);
  }
}

性能优化建议

1. 大文件处理

对于大型Excel文件,可以考虑流式处理:

javascript 复制代码
const stream = XLSX.stream.read_workbook("./large_file.xlsx", {
  type: "file",
  sheets: ["Sheet1"], // 只处理指定的工作表
});

stream.on('worksheet', (ws, props) => {
  console.log(`正在处理工作表: ${props.name}`);
});

2. 内存管理

javascript 复制代码
// 处理完成后释放内存
workbook = null;
if (global.gc) {
  global.gc();
}

常见问题和解决方案

1. 中文编码问题

确保输出文件使用UTF-8编码:

javascript 复制代码
fs.writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), "utf-8");

2. 空值处理

javascript 复制代码
name: row.名称 ? row.名称.toString().trim() : null,

3. 数字格式处理

javascript 复制代码
// 处理可能是数字的字符串
did: row.did ? String(row.did).trim() : null,

运行项目

  1. 确保项目目录下有xfs_tt.xlsx文件
  2. 运行命令:
bash 复制代码
node index.js
  1. 检查data目录下生成的JSON文件

实际应用场景

  1. 数据迁移: 将Excel中的历史数据迁移到数据库
  2. 数据清洗: 统一数据格式,去除无效数据
  3. API数据源: 为前端应用提供JSON格式的数据
  4. 报表生成: 将数据库数据导出为Excel格式

总结

XLSX库为JavaScript开发者提供了强大的Excel文件处理能力。通过本文的实践案例,我们学习了:

  1. 如何读取Excel文件
  2. 如何处理多个工作表
  3. 如何进行数据映射和清理
  4. 如何添加错误处理和数据验证
  5. 性能优化的最佳实践

这个项目展示了从Excel到JSON的完整数据处理流程,可以作为类似项目的基础模板。

相关资源

相关推荐
牧码岛11 小时前
服务端之NestJS接口响应message编写规范详解、写给前后端都舒服的接口、API提示信息标准化
服务器·后端·node.js·nestjs
嚴寒1 天前
Node 版本管理还在手动重装全局包?这个方案让你效率翻倍
node.js
你的人类朋友2 天前
【Node】单线程的Node.js为什么可以实现多线程?
前端·后端·node.js
HoJunjie2 天前
macOS sequoia 15.7.1 源码安装node14,并加入nvm管理教程
macos·node.js
做运维的阿瑞3 天前
Windows 环境下安装 Node.js 和 Vue.js 框架完全指南
前端·javascript·vue.js·windows·node.js
你的人类朋友3 天前
【Node】Node.js 多进程与多线程:Cluster 与 Worker Threads 入门
前端·后端·node.js
谢尔登3 天前
【Nest】日志记录
javascript·中间件·node.js
HWL56793 天前
输入框内容粘贴时   字符净化问题
前端·vue.js·后端·node.js
. . . . .4 天前
Node.js 的替代品Bun
node.js