You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器环境下JavaScript读写Excel文件报错求助

问题解决:浏览器环境下用SheetJS修改本地Excel文件

核心问题分析

  • 浏览器安全限制:XLSX.readFile("students.xlsx")直接读取本地固定路径文件会失败——浏览器出于安全策略,不允许JavaScript直接访问本地文件系统的指定路径文件,这是同源策略的强制限制。
  • require未定义:require("xlsx")是Node.js的模块加载语法,浏览器环境没有这个机制,必须通过<script>标签引入SheetJS库。
  • SheetJS API误用:SheetJS的worksheet对象没有addRow方法(这是ExcelJS的API),需要先将工作表转成JSON数组,添加数据后再转回工作表格式。

解决方案1:纯前端上传+修改+下载

浏览器无法直接修改本地文件,所以流程为:用户先上传原Excel文件,前端读取并修改数据,最后让用户下载更新后的文件。

完整代码

<!-- 引入SheetJS库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.9/xlsx.full.min.js"></script>

<!-- 文件上传控件 -->
<input type="file" id="excelFile" accept=".xlsx,.xls">

<!-- 表单区域 -->
<form>
  <input type="text" id="fullname" placeholder="姓名">
  <input type="text" id="grade" placeholder="年级">
  <input type="date" id="birthdate">
  <textarea id="address" placeholder="地址"></textarea>
  <input type="tel" id="phonenumber" placeholder="手机号">
  <button type="button" id="save">保存数据</button>
</form>

<script>
let workbook = null; // 存储读取后的工作簿
let originalFileName = "students.xlsx"; // 默认文件名

// 监听文件上传,加载原Excel数据
document.getElementById('excelFile').addEventListener('change', function(e) {
  const file = e.target.files[0];
  if (!file) return;
  originalFileName = file.name;
  
  const reader = new FileReader();
  reader.onload = function(event) {
    const data = new Uint8Array(event.target.result);
    workbook = XLSX.read(data, { type: 'array' });
    alert("原Excel文件已加载,可添加数据");
  };
  reader.readAsArrayBuffer(file);
});

// 保存按钮点击事件
document.getElementById('save').addEventListener('click', async function saveStudent() {
  const XLSX = window.XLSX;
  
  // 校验是否已加载原文件
  if (!workbook) {
    alert("请先上传原Excel文件");
    return;
  }

  // 获取并校验表单数据
  const fullname = document.getElementById('fullname').value.trim();
  const grade = document.getElementById('grade').value.trim();
  const birthdate = document.getElementById('birthdate').value.trim();
  const address = document.getElementById('address').value.trim();
  const phonenumber = document.getElementById('phonenumber').value.trim();

  if (!fullname || !grade || !birthdate || !address || !phonenumber) {
    alert('请填写所有信息');
    return;
  }

  // 读取工作表并转成JSON数组
  const worksheet = workbook.Sheets["Sheet1"];
  const jsonData = XLSX.utils.sheet_to_json(worksheet);
  
  // 添加新数据
  jsonData.push({
    fullname,
    grade,
    birthdate: new Date(birthdate).toLocaleDateString(),
    address,
    phonenumber
  });

  // 将更新后的JSON转回工作表,替换原工作簿中的Sheet1
  const newWorksheet = XLSX.utils.json_to_sheet(jsonData);
  workbook.Sheets["Sheet1"] = newWorksheet;

  // 生成并下载更新后的文件
  XLSX.writeFile(workbook, originalFileName);

  // 清空表单
  clearInputs();
});

// 清空表单函数
function clearInputs() {
  document.getElementById('fullname').value = '';
  document.getElementById('grade').value = '';
  document.getElementById('birthdate').value = '';
  document.getElementById('address').value = '';
  document.getElementById('phonenumber').value = '';
}
</script>

解决方案2:后端配合实现直接修改文件

如果需要直接修改固定路径的本地/服务器文件,必须通过后端语言(如Node.js)处理文件读写,前端通过API发送请求。

后端代码(Node.js)

const express = require('express');
const XLSX = require('xlsx');
const cors = require('cors');
const app = express();

app.use(cors()); // 解决跨域问题
app.use(express.json());

const filePath = './students.xlsx'; // 服务器上的Excel文件路径

// 添加新学生接口
app.post('/api/add-student', (req, res) => {
  const { fullname, grade, birthdate, address, phonenumber } = req.body;

  // 读取原Excel文件
  const workbook = XLSX.readFile(filePath);
  const worksheet = workbook.Sheets["Sheet1"];
  const jsonData = XLSX.utils.sheet_to_json(worksheet);
  
  // 追加新数据
  jsonData.push({ fullname, grade, birthdate, address, phonenumber });
  
  // 将更新后的数据写回文件
  const newWorksheet = XLSX.utils.json_to_sheet(jsonData);
  workbook.Sheets["Sheet1"] = newWorksheet;
  XLSX.writeFile(workbook, filePath);

  res.json({ success: true, msg: "数据已成功添加" });
});

app.listen(3000, () => console.log('服务器运行在 http://localhost:3000'));

前端代码修改

document.getElementById('save').addEventListener('click', async function saveStudent() {
  // 获取表单数据
  const fullname = document.getElementById('fullname').value.trim();
  const grade = document.getElementById('grade').value.trim();
  const birthdate = document.getElementById('birthdate').value.trim();
  const address = document.getElementById('address').value.trim();
  const phonenumber = document.getElementById('phonenumber').value.trim();

  if (!fullname || !grade || !birthdate || !address || !phonenumber) {
    alert('请填写所有信息');
    return;
  }

  try {
    // 发送请求到后端接口
    const response = await fetch('http://localhost:3000/api/add-student', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ fullname, grade, birthdate, address, phonenumber })
    });
    
    const result = await response.json();
    if (result.success) {
      alert("数据已成功写入Excel文件");
      clearInputs();
    }
  } catch (error) {
    console.error('请求失败:', error);
    alert("添加失败,请检查服务器状态");
  }
});

// 清空表单函数不变
function clearInputs() {
  document.getElementById('fullname').value = '';
  document.getElementById('grade').value = '';
  document.getElementById('birthdate').value = '';
  document.getElementById('address').value = '';
  document.getElementById('phonenumber').value = '';
}

内容的提问来源于stack exchange,提问作者Mm Yy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:07:04