1. 安装依赖

首先安装 xlsx 库:

npm install xlsx
# 或
yarn add xlsx

2. 基础实现代码

方案 1:通过 <input type="file"> 上传并读取
<template>
  <div>
    <input type="file" @change="handleFileUpload" accept=".xlsx, .xls" />
    <button @click="readExcel">读取Excel</button>
    <div v-if="excelData.length">
      <h3>读取到的数据:</h3>
      <pre>{{ excelData }}</pre>
    </div>
  </div>
</template>

<script>
import * as XLSX from "xlsx";

export default {
  data() {
    return {
      file: null,
      excelData: [],
    };
  },
  methods: {
    // 1. 获取上传的文件
    handleFileUpload(event) {
      this.file = event.target.files[0];
    },

    // 2. 读取Excel数据
    readExcel() {
      if (!this.file) return alert("请先选择文件!");

      const reader = new FileReader();
      reader.onload = (e) => {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, { type: "array" });

        // 获取第一个工作表
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];

        // 转换为JSON数据
        this.excelData = XLSX.utils.sheet_to_json(worksheet);
      };
      reader.readAsArrayBuffer(this.file);
    },
  },
};
</script>

方案 2:拖拽上传(更友好)

<template>
  <div 
    @drop.prevent="handleDrop"
    @dragover.prevent
    class="drop-area"
  >
    拖拽Excel文件到此处或点击上传
    <input type="file" @change="handleFileUpload" accept=".xlsx, .xls" />
  </div>
</template>

<script>
import * as XLSX from "xlsx";

export default {
  methods: {
    handleDrop(e) {
      const file = e.dataTransfer.files[0];
      this.parseExcel(file);
    },
    handleFileUpload(e) {
      this.parseExcel(e.target.files[0]);
    },
    parseExcel(file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        const data = XLSX.read(e.target.result, { type: "binary" });
        const jsonData = XLSX.utils.sheet_to_json(data.Sheets[data.SheetNames[0]]);
        console.log("Excel数据:", jsonData);
        // 这里可以提交到后端或处理数据
      };
      reader.readAsBinaryString(file);
    },
  },
};
</script>

<style>
.drop-area {
  border: 2px dashed #ccc;
  padding: 20px;
  text-align: center;
}
</style>

3. 高级功能

自定义数据处理
// 读取时指定表头(假设第一行是标题)
const options = { header: 1 }; // 或 { header: ["列1", "列2"] }
const jsonData = XLSX.utils.sheet_to_json(worksheet, options);

读取多个工作表

workbook.SheetNames.forEach(sheetName => {
  const sheetData = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
  console.log(sheetName, sheetData);
});

 写入Excel(导出)

 

const newWorkbook = XLSX.utils.book_new();
const newWorksheet = XLSX.utils.json_to_sheet([
  { name: "张三", age: 20 },
  { name: "李四", age: 25 }
]);
XLSX.utils.book_append_sheet(newWorkbook, newWorksheet, "Sheet1");
XLSX.writeFile(newWorkbook, "导出数据.xlsx");

4. 注意事项

  1. 文件类型兼容性

    • 支持 .xlsx.xls.csv

  2. 大文件处理

    • 如果文件很大(>10MB),建议分片读取或使用 Web Worker 避免页面卡顿。

  3. 安全过滤

    • 对读取的数据做校验,避免恶意文件攻击。

  4. 移动端适配

    • 部分安卓设备可能需额外处理文件类型。

实例:

获取excel表头

getExcelTitle(file).then(async title => {
    // 判断是否有重复表头
    if (new Set(title).size !== title.length) {
      message.error('提交表格时,请确保表头唯一,严禁重复。');
      loading.value = false;
    } else if (props?.isWebImport) {
      await readExcel(file, title);
    } else {
      excelFile.value = file;
      fileName.value = file.name;
      status.value = MODAL_STATUS.MATCH_FORM;
      excelTitles.value = title;
      getColumnSchemeList();
    }
  }).catch(e => {
    console.log(e);
    message.error('文件解析失败,可能已被加密或格式不受支持,请检查后重试。');
  }).finally(() => {
    loading.value = false;
  });

读取excel的数据 

async function readExcel(file, importTitle) {
  excelData.value = [];
  const workbook = new ExcelJS.Workbook();
  await workbook.xlsx.load(file).then(res => {
    const worksheet = workbook.worksheets[0];
    if (worksheet.rowCount - 1 > 1000) {
      message.error('一次导入不能大于1000条记录。');
      loading.value = false;
    } else {
      status.value = MODAL_STATUS.MATCH_FORM;
      excelFile.value = file;
      fileName.value = file.name;
      status.value = MODAL_STATUS.MATCH_FORM;
      excelTitles.value = importTitle;
      // 获取模版列表
      // getColumnSchemeList();
      worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
        const rowData = [];
        for (let i = 0; i < importTitle.length; i++) {
          const cell = row.getCell(i + 1);
          if (cell.type === ExcelJS.ValueType.Formula) {
            rowData.push(cell.result);
          } else if (cell.type === ExcelJS.ValueType.RichText) {
            rowData.push((cell.value.richText || []).map(v => v.text).join(''));
          } else if (cell.type === ExcelJS.ValueType.Hyperlink) {
            rowData.push(cell.value.text);
          } else if (cell.type === ExcelJS.ValueType.Null) {
            rowData.push('');
          } else if (cell.type === ExcelJS.ValueType.Error) {
            rowData.push(cell.value.error);
          } else if (cell.type === ExcelJS.ValueType.Date && cell.value) {
            rowData.push(dayjs.utc(cell.value).format('YYYY-MM-DD HH:mm:ss'));
          } else {
            rowData.push(cell.value);
          }
        }
        excelData.value.push(rowData);
      });
    }
  });
}

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐