《纯前端实现 Excel 导入导出:基于 SheetJS 的完整实战》

📘 《纯前端实现 Excel 导入导出:基于 SheetJS 的完整实战》

关键词:SheetJS、Excel、前端导入导出、数据处理、文件解析
适用场景:后台管理系统、企业报表、CRM、ERP、财务数据导入、数据可视化前置处理


1️⃣ 为什么纯前端实现 Excel 导入导出这么重要?

在大量后台系统中,经常会遇到这些需求:

  • ✔ 客户希望上传一份 Excel 数据 批量导入系统
  • ✔ 管理员需要批量导出报表,用于财务 / 销售分析
  • ✔ 产品要求前端直接展示 Excel 内容,例如数据大屏展示
  • ✔ 避免服务端压力,不希望每次导入导出都走后端解析

因此,「纯前端解析 Excel」变得非常重要,而 SheetJS(xlsx)作为最强大的 Excel JS 库,几乎成了标配。


2️⃣ SheetJS(xlsx)是什么?


👉 一个浏览器 + Node 通用的 Excel 解析库,支持格式:

  • .xlsx
  • .xls
  • .csv
  • .xlsm
  • .ods

支持功能:

  • 导入 Excel → JSON
  • JSON → 导出 Excel
  • 多 Sheet 创建
  • 单元格格式 / 样式
  • 表头合并
  • 下载本地文件

3️⃣ 项目初始化(Vue/React/原生JS均支持)

这里以 Vue3 + Vite 为例。

安装 SheetJS:

bash 复制代码
npm install xlsx

4️⃣ Excel 导入功能:上传 → 解析 JSON → 渲染表格

📌 Step 1:实现文件选择

html 复制代码
<input type="file" @change="handleFileUpload" accept=".xlsx,.xls" />

📌 Step 2:解析 Excel 文件为 JSON

javascript 复制代码
import * as XLSX from 'xlsx';

const handleFileUpload = (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();

  reader.onload = (event) => {
    const data = event.target.result;
    const workbook = XLSX.read(data, { type: "binary" });

    // 读取第一张表
    const sheetName = workbook.SheetNames[0];
    const sheet = workbook.Sheets[sheetName];

    // Excel → JSON
    const jsonData = XLSX.utils.sheet_to_json(sheet);
    console.log("解析结果:", jsonData);
  };

  reader.readAsBinaryString(file);
};

输出示例:

json 复制代码
[
  {"姓名":"张三","年龄":22,"部门":"研发部"},
  {"姓名":"李四","年龄":25,"部门":"产品部"}
]

你可以直接渲染到表格:

html 复制代码
<table>
  <tr>
    <th v-for="key in Object.keys(jsonData[0])">{{ key }}</th>
  </tr>

  <tr v-for="row in jsonData">
    <td v-for="value in row">{{ value }}</td>
  </tr>
</table>

5️⃣ Excel 导出:JSON → 下载 Excel 文件

使用 SheetJS 将 JS 数组导出为 Excel:

javascript 复制代码
const exportExcel = () => {
  const ws = XLSX.utils.json_to_sheet(jsonData);
  const wb = XLSX.utils.book_new();

  XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

  XLSX.writeFile(wb, "导出结果.xlsx");
};

适用于:

  • 批量数据导出
  • 报表输出
  • 后台列表导出

6️⃣ 导入导出完整 Demo(可直接复制使用)

vue 复制代码
<template>
  <div>
    <h2>Excel 导入导出 Demo</h2>

    <input type="file" @change="handleFileUpload" />
    <button @click="exportExcel">导出 Excel</button>

    <table v-if="jsonData.length">
      <tr>
        <th v-for="key in keys">{{ key }}</th>
      </tr>
      <tr v-for="row in jsonData">
        <td v-for="value in Object.values(row)">{{ value }}</td>
      </tr>
    </table>
  </div>
</template>

<script setup>
import { ref } from "vue";
import * as XLSX from "xlsx";

const jsonData = ref([]);
const keys = ref([]);

const handleFileUpload = (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();

  reader.onload = (event) => {
    const data = event.target.result;
    const workbook = XLSX.read(data, { type: "binary" });

    const sheet = workbook.Sheets[workbook.SheetNames[0]];
    jsonData.value = XLSX.utils.sheet_to_json(sheet);

    keys.value = Object.keys(jsonData.value[0] || {});
  };

  reader.readAsBinaryString(file);
};

const exportExcel = () => {
  const ws = XLSX.utils.json_to_sheet(jsonData.value);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

  XLSX.writeFile(wb, "导出结果.xlsx");
};
</script>

7️⃣ 常见业务增强点(企业项目最常用)

场景 做法
表头重命名 设置 Header map
数据校验(id 必填) 解析 JSON 后做校验
表格样式 使用 cell.s 表达式
导出多 Sheet book_append_sheet() 多次调用
表头合并 ws['!merges']
大文件导入优化 使用 XLSX.stream

8️⃣ 可能踩坑点(非常实用)

❌ 文件太大导致浏览器卡顿(解决:Worker + Streaming)

❌ 合并单元格读取错误(解决:cell.w + merges)

❌ 日期格式变成数字(解决:cellDates: true

❌ 中文表头乱码(解决:binary + UTF-8)


9️⃣ 总结

本文提供了:

  • ✔ Excel 导入
  • ✔ Excel 导出
  • ✔ JSON 转表格
  • ✔ 完整 Demo
  • ✔ 企业应用增强点

可以直接复制到 CSDN 作为一篇完整教程。

相关推荐
摸鱼的春哥2 分钟前
Agent教程15:认识LangChain(中),状态机思维
前端·javascript·后端
明月_清风8 分钟前
告别遮挡:用 scroll-padding 实现优雅的锚点跳转
前端·javascript
明月_清风11 分钟前
原生 JS 侧边栏缩放:从 DOM 监听到底层优化
前端·javascript
万少9 小时前
HarmonyOS 开发必会 5 种 Builder 详解
前端·harmonyos
橙序员小站11 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
炫饭第一名14 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
王晓枫14 小时前
flutter接入三方库运行报错:Error running pod install
前端·flutter
符方昊14 小时前
React 19 对比 React 16 新特性解析
前端·react.js
ssshooter14 小时前
又被 Safari 差异坑了:textContent 拿到的值居然没换行?
前端
曲折14 小时前
Cesium-气象要素PNG色斑图叠加
前端·cesium