最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript前端讀取Excel文件的實戰(zhàn)指南

 更新時間:2025年09月25日 10:09:53   作者:夏曦安  
在前端開發(fā)中,JavaScript通過js-xlsx庫實現(xiàn)Excel文件的解析與數(shù)據(jù)提取,支持從用戶上傳的.xlsx文件中讀取內(nèi)容并轉(zhuǎn)換為JavaScript可操作的數(shù)據(jù)結(jié)構(gòu),本文介紹該庫的基本使用流程,需要的朋友可以參考下

簡介:在前端開發(fā)中,JavaScript通過“js-xlsx”庫實現(xiàn)Excel文件的解析與數(shù)據(jù)提取,支持從用戶上傳的.xlsx文件中讀取內(nèi)容并轉(zhuǎn)換為JavaScript可操作的數(shù)據(jù)結(jié)構(gòu)。本文介紹該庫的基本使用流程,包括安裝、文件讀取、工作表解析、數(shù)據(jù)轉(zhuǎn)換與處理,并提供完整示例代碼,適用于需要在前端實現(xiàn)Excel數(shù)據(jù)處理的應(yīng)用場景。

1. 前端讀取Excel文件的需求背景

隨著Web應(yīng)用功能的不斷拓展,前端直接處理Excel文件的需求日益增長。在數(shù)據(jù)導(dǎo)入、報表預(yù)覽、用戶信息上傳等業(yè)務(wù)場景中,Excel因其結(jié)構(gòu)清晰、操作便捷,成為企業(yè)數(shù)據(jù)交互的重要載體。傳統(tǒng)做法是將文件上傳至后端處理,但這種方式增加了 服務(wù)器負擔,響應(yīng)速度受限。隨著JavaScript技術(shù)的成熟,特別是在File API和相關(guān)庫(如js-xlsx)的支持下,瀏覽器端讀取和解析Excel文件已成為現(xiàn)實。這不僅提升了應(yīng)用響應(yīng)速度,也優(yōu)化了用戶體驗,為前端工程師帶來了全新的技術(shù)挑戰(zhàn)與實踐機會。

2. js-xlsx庫簡介與安裝方法

2.1 js-xlsx庫概述

2.1.1 什么是js-xlsx

js-xlsx 是一個由SheetJS開發(fā)的開源JavaScript庫,用于在前端或Node.js環(huán)境中讀寫Excel文件(支持 .xls .xlsx 格式)。該庫功能強大,支持多種Excel格式的解析與生成,能夠?qū)xcel文件轉(zhuǎn)換為JSON、CSV、HTML等結(jié)構(gòu)化數(shù)據(jù)格式,廣泛應(yīng)用于Web應(yīng)用中的數(shù)據(jù)導(dǎo)入導(dǎo)出場景。

其核心優(yōu)勢在于:

  • 純JavaScript實現(xiàn) ,無需依賴任何其他庫(如jQuery)。
  • 跨平臺兼容 ,支持瀏覽器端與Node.js環(huán)境。
  • 輕量級 ,壓縮后體積小,適合嵌入到生產(chǎn)環(huán)境。
  • 豐富的API接口 ,可靈活處理Excel中的Sheet、Cell、樣式、公式等內(nèi)容。

2.1.2 js-xlsx的核心功能

以下是 js-xlsx 的核心功能模塊及其作用:

功能模塊功能描述
XLSX.readFile 讀取本地Excel文件(支持同步與異步)
XLSX.utils.aoa_to_sheet 將二維數(shù)組轉(zhuǎn)換為工作表對象
XLSX.utils.sheet_to_json 將Sheet對象轉(zhuǎn)換為JSON數(shù)組
XLSX.write 生成Excel文件并支持下載或?qū)懭隢ode.js流
XLSX.SSF 提供單元格格式化與解析功能
XLSX.utils.encode_cell 將行列索引轉(zhuǎn)換為Excel單元格地址(如 A1、B2 等)

此外, js-xlsx 還支持多種格式的導(dǎo)出,包括CSV、HTML表格、ODS等。其靈活性使其成為前端Excel操作的首選庫之一。

2.2 js-xlsx的安裝與引入方式

2.2.1 使用npm安裝js-xlsx

對于使用模塊化構(gòu)建工具(如Webpack、Vite、Rollup等)的現(xiàn)代前端項目,推薦使用npm方式安裝:

npm install xlsx

安裝完成后,在JavaScript文件中通過 import 引入:

import * as XLSX from 'xlsx';

注意 :部分構(gòu)建工具可能需要額外配置,例如在Vue或React項目中確保  xlsx  被正確打包。

示例代碼:讀取并解析Excel文件

import * as XLSX from 'xlsx';

function handleFile(file) {
  const reader = new FileReader();
  reader.onload = function(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];
    const json = XLSX.utils.sheet_to_json(worksheet);
    console.log(json);
  };
  reader.readAsArrayBuffer(file);
}

代碼邏輯說明
1. 使用  FileReader  讀取用戶上傳的Excel文件。
2. 通過  XLSX.read  將文件內(nèi)容轉(zhuǎn)換為  workbook  對象。
3. 獲取第一個工作表并通過  sheet_to_json  轉(zhuǎn)換為JSON格式。

2.2.2 在HTML中直接引入CDN鏈接

對于不使用模塊化構(gòu)建的簡單項目或靜態(tài)頁面,可以通過CDN引入 js-xlsx

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>

此方式無需任何構(gòu)建步驟,直接在瀏覽器中使用全局變量 XLSX

示例代碼:HTML中使用CDN引入并讀取Excel

<input type="file" id="excel-file" accept=".xlsx, .xls" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script>
  document.getElementById('excel-file').addEventListener('change', function(e) {
    const file = e.target.files[0];
    const reader = new FileReader();
    reader.onload = function(evt) {
      const data = new Uint8Array(evt.target.result);
      const workbook = XLSX.read(data, { type: 'array' });
      const sheetName = workbook.SheetNames[0];
      const sheet = workbook.Sheets[sheetName];
      const jsonData = XLSX.utils.sheet_to_json(sheet);
      console.log(jsonData);
    };
    reader.readAsArrayBuffer(file);
  });
</script>

代碼邏輯說明
1. 監(jiān)聽文件選擇框的  change  事件,獲取文件對象。
2. 使用  FileReader  讀取文件內(nèi)容。
3. 使用  XLSX.read  解析文件為工作簿對象。
4. 提取第一個工作表,并轉(zhuǎn)換為JSON數(shù)組。

2.2.3 模塊化開發(fā)中的導(dǎo)入方式

在使用模塊化框架(如Vue、React、Angular)時,建議使用 import 方式引入 xlsx ,以便更好地管理依賴與打包體積。

Vue項目示例:
<template>
  <input type="file" @change="handleFileUpload" accept=".xlsx, .xls" />
</template>

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

export default {
  methods: {
    handleFileUpload(event) {
      const file = event.target.files[0];
      const reader = new FileReader();
      reader.onload = (e) => {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, { type: 'array' });
        const sheetName = workbook.SheetNames[0];
        const sheet = workbook.Sheets[sheetName];
        const jsonData = XLSX.utils.sheet_to_json(sheet);
        console.log(jsonData);
      };
      reader.readAsArrayBuffer(file);
    }
  }
}
</script>

代碼邏輯說明
1. 在Vue組件中綁定文件上傳事件。
2. 使用  XLSX  庫讀取Excel文件并解析為JSON。
3. 打印解析結(jié)果到控制臺。

2.3 js-xlsx的兼容性與注意事項

2.3.1 瀏覽器兼容性分析

js-xlsx 支持現(xiàn)代瀏覽器和IE11(部分功能需polyfill)。以下為兼容性表格:

瀏覽器兼容性備注
Chrome? 完全支持最新版本兼容性最佳
Firefox? 完全支持需啟用部分實驗性功能(如  FileReaderSync  )
Safari? 完全支持iOS Safari 也支持
Edge? 完全支持版本需 ≥ Edge 12
IE11?? 部分支持需引入polyfill處理  ArrayBuffer  、  TypedArray 
Mobile Safari? 完全支持包括iOS 9及以上
Android Browser? 完全支持Android 4.4及以上

兼容性建議
- 對于IE11環(huán)境,建議引入  xlsx.core.min.js  并使用  FileReader  polyfill。
- 使用  XLSX.set_cptable  以支持中文字符的正確解析。

2.3.2 常見問題及解決方案

問題1:讀取文件時提示 Not a valid zip 錯誤

原因 :上傳的文件格式不被支持或文件損壞。

解決方案
- 檢查文件是否為 .xls .xlsx 格式。
- 確保文件未損壞,嘗試使用Excel重新保存文件。
- 使用 try-catch 捕獲異常:

try {
  const workbook = XLSX.read(data, { type: 'array' });
} catch (error) {
  console.error("Excel文件解析失?。?, error);
}

問題2:讀取中文內(nèi)容亂碼

原因 js-xlsx 默認不處理字符編碼,某些Excel文件可能包含非UTF-8編碼。

解決方案
使用 cptable 插件處理編碼轉(zhuǎn)換:

import * as XLSX from 'xlsx';
import cptable from 'xlsx/dist/cpexcel.full.js';

XLSX.set_cptable(cptable);

function handleFile(file) {
  const reader = new FileReader();
  reader.onload = function(e) {
    const data = new Uint8Array(e.target.result);
    const workbook = XLSX.read(data, { type: 'array' });
    const sheet = workbook.Sheets[workbook.SheetNames[0]];
    const json = XLSX.utils.sheet_to_json(sheet);
    console.log(json);
  };
  reader.readAsArrayBuffer(file);
}

問題3:處理大文件時卡頓或崩潰

原因 js-xlsx 是同步解析庫,處理大文件時可能阻塞主線程。

解決方案
- 使用 Web Worker 異步處理大文件解析。
- 分頁讀取或限制讀取的Sheet數(shù)量。
- 前端提示用戶上傳文件大小限制。

流程圖:js-xlsx文件讀取流程

graph TD
    A[用戶選擇Excel文件] --> B[通過FileReader讀取文件]
    B --> C{判斷文件類型}
    C -->| .xls | D[XLSX.read解析文件]
    C -->| .xlsx | D
    D --> E[獲取Workbook對象]
    E --> F[獲取SheetNames數(shù)組]
    F --> G[訪問指定Sheet對象]
    G --> H[XLSX.utils.sheet_to_json轉(zhuǎn)換數(shù)據(jù)]
    H --> I[輸出JSON數(shù)組]

該流程圖清晰地展示了 js-xlsx 從文件選擇到最終數(shù)據(jù)解析的完整流程,有助于開發(fā)者理解其工作原理。

本章內(nèi)容完整地介紹了 js-xlsx 的基本概念、安裝方式及兼容性問題,為后續(xù)章節(jié)深入解析Excel數(shù)據(jù)結(jié)構(gòu)和處理邏輯打下了堅實基礎(chǔ)。

3. 使用XLSX.readFile讀取Excel文件

在前端開發(fā)中,處理Excel文件已成為一種常見需求,尤其在數(shù)據(jù)導(dǎo)入、報表展示等場景中。 XLSX.readFile js-xlsx (也稱 SheetJS )庫提供的一個核心方法,用于從本地文件系統(tǒng)讀取 Excel 文件。本章將詳細介紹如何結(jié)合 HTML5 的 input 元素獲取用戶上傳的文件對象,并使用 XLSX.readFile 方法進行讀取,同時對讀取后的數(shù)據(jù)結(jié)構(gòu)進行初步解析。

3.1 通過input元素獲取文件對象

在 Web 應(yīng)用中,用戶通常通過 <input type="file"> 元素上傳文件。HTML5 提供了 File API ,使前端可以訪問用戶選擇的本地文件內(nèi)容。

3.1.1 HTML5中File API的基礎(chǔ)知識

HTML5 的 File API 是一組用于處理本地文件的接口,主要包括:

  • File :表示一個文件對象。
  • FileList :表示一組 File 對象,通常由 <input type="file"> 元素返回。
  • FileReader :用于異步讀取文件內(nèi)容。

使用這些 API,前端可以訪問用戶上傳的文件內(nèi)容,并將其傳遞給 js-xlsx 進行解析。

3.1.2 事件監(jiān)聽與文件讀取

我們可以為 <input type="file"> 元素綁定 change 事件監(jiān)聽器,當用戶選擇文件后觸發(fā)文件讀取操作。

<input type="file" id="excelFile" accept=".xlsx,.xls" />
document.getElementById('excelFile').addEventListener('change', function(e) {
    const file = e.target.files[0];  // 獲取用戶選擇的第一個文件
    if (file) {
        const reader = new FileReader();  // 創(chuàng)建FileReader對象
        reader.onload = function(event) {
            const data = new Uint8Array(event.target.result);  // 轉(zhuǎn)換為二進制數(shù)組
            const workbook = XLSX.read(data, { type: 'array' });  // 使用js-xlsx解析
            console.log(workbook);  // 輸出解析后的workbook對象
        };
        reader.readAsArrayBuffer(file);  // 以ArrayBuffer形式讀取文件
    }
});

注意:  FileReader.readAsArrayBuffer()  是讀取 Excel 文件的推薦方式,因為 Excel 文件是二進制格式。

代碼邏輯分析

  • 第 1 行 :為 <input> 元素綁定 change 事件監(jiān)聽器。
  • 第 2 行 :通過 e.target.files[0] 獲取用戶選擇的第一個文件。
  • 第 4 行 :創(chuàng)建 FileReader 實例,用于異步讀取文件。
  • 第 5 行 :定義 onload 事件回調(diào),當文件讀取完成后執(zhí)行。
  • 第 6 行 :將 result 轉(zhuǎn)換為 Uint8Array ,以便傳給 XLSX.read() 。
  • 第 7 行 :調(diào)用 XLSX.read() 方法解析 Excel 文件。
  • 第 10 行 :以 ArrayBuffer 格式讀取文件內(nèi)容。

3.2 XLSX.readFile方法詳解

XLSX.readFile js-xlsx 提供的另一個便捷方法,可以直接傳入文件路徑或文件對象進行解析,尤其適用于 Node.js 環(huán)境或 Electron 應(yīng)用。

3.2.1 參數(shù)說明與使用方式

參數(shù)名類型必填描述
filenamestring 文件路徑或文件名
optsobject 配置選項,如  type  ,  sheet  ,  cellDates  等

常見配置選項:

選項名類型默認值描述
typestring "base64" 讀取類型,可選  base64  ,  binary  ,  buffer  ,  array  ,  file 
sheetnumber  或  string 指定讀取的工作表索引或名稱
cellDatesboolean false 是否將日期單元格轉(zhuǎn)換為 JS Date 對象

示例代碼

const workbook = XLSX.readFile('data.xlsx', {
    type: 'file',
    cellDates: true
});
console.log(workbook);

代碼邏輯分析

  • 第 1 行 :調(diào)用 XLSX.readFile() 方法讀取本地路徑為 data.xlsx 的文件。
  • 第 2 行 :指定讀取類型為 file ,即直接讀取文件路徑。
  • 第 3 行 :將日期單元格轉(zhuǎn)換為 Date 對象,便于后續(xù)處理。

注意:  XLSX.readFile()  在瀏覽器中使用時需確保文件路徑有效,通常用于 Electron 或本地文件系統(tǒng)環(huán)境。

3.2.2 讀取不同格式的Excel文件(.xls與.xlsx)

js-xlsx 支持讀取 .xls (Excel 2003)和 .xlsx (Excel 2007 及以上)兩種格式,無需額外配置。

支持格式對比表:

文件格式擴展名說明是否支持
Excel 2003.xls 二進制格式,BIFF8? 支持
Excel 2007+.xlsx 基于 ZIP 的 XML 格式? 支持
CSV.csv 純文本格式? 支持(需手動處理)
Excel 2016+(新功能).xlsm  ,  .xlsx 含宏或高級功能? 基礎(chǔ)功能支持

示例流程圖(mermaid)

graph TD
    A[用戶選擇Excel文件] --> B{判斷文件擴展名}
    B -->| .xls | C[使用XLSX.readFile讀取]
    B -->| .xlsx | D[使用XLSX.readFile讀取]
    C --> E[解析為Workbook對象]
    D --> E
    E --> F[輸出解析結(jié)果]

3.3 文件讀取后的數(shù)據(jù)結(jié)構(gòu)初步解析

當 Excel 文件被成功讀取后, XLSX.readFile 返回一個 workbook 對象,該對象包含了整個 Excel 文件的數(shù)據(jù)結(jié)構(gòu)。

3.3.1 Workbook對象的結(jié)構(gòu)

workbook 對象是一個 JavaScript 對象,其結(jié)構(gòu)如下:

{
  SheetNames: ['Sheet1', 'Sheet2'],
  Sheets: {
    Sheet1: { '!ref': 'A1:D10', A1: { v: 'Header1', t: 's' }, ... },
    Sheet2: { '!ref': 'A1:C5', A1: { v: 'Data1', t: 's' }, ... }
  },
  Props: { ... },
  Custprops: { ... }
}
屬性名類型描述
SheetNamesArray<string> 所有工作表名稱
SheetsObject 以工作表名稱為鍵,對應(yīng)工作表數(shù)據(jù)對象
PropsObject 文檔屬性(如創(chuàng)建者、修改時間等)
CustpropsObject 自定義屬性

3.3.2 常用屬性與方法介紹

SheetNames 數(shù)組

SheetNames 是一個字符串數(shù)組,保存了 Excel 文件中所有工作表的名稱。例如:

console.log(workbook.SheetNames); // ['Sheet1', 'Sheet2']

Sheets 對象

每個工作表數(shù)據(jù)以鍵值對形式存儲在 Sheets 對象中,例如:

const sheet = workbook.Sheets['Sheet1'];
console.log(sheet['A1']); // { v: 'Header1', t: 's' }

每個單元格數(shù)據(jù)對象包含以下屬性:

屬性類型描述
vany 單元格值
tstring 值的類型,如 'n' (數(shù)值)、 's' (字符串)、 'd' (日期)等
zstring 數(shù)值格式(如日期格式)
wstring 格式化后的顯示值

示例代碼

const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];

for (let i = 1; i <= 10; i++) {
    const cell = worksheet['A' + i];
    if (cell) {
        console.log(`A${i}:`, cell.v);
    }
}

代碼邏輯分析

  • 第 1 行 :獲取第一個工作表名稱。
  • 第 2 行 :根據(jù)名稱獲取工作表對象。
  • 第 4 行 :遍歷 A1 到 A10 單元格。
  • 第 5 行 :判斷單元格是否存在。
  • 第 6 行 :輸出單元格的值。

通過本章內(nèi)容,我們已經(jīng)掌握了如何使用 XLSX.readFile 方法讀取 Excel 文件,并對其返回的 workbook 對象進行初步解析。下一章我們將深入探討 workbook 對象的內(nèi)部結(jié)構(gòu),包括 SheetNames 、 Sheets 和單元格數(shù)據(jù)的具體表示方式。

4. 解析Workbook對象結(jié)構(gòu)

在使用 js-xlsx 庫讀取 Excel 文件后,返回的核心對象是一個 Workbook 對象。該對象包含了文件中所有工作表(Sheet)的名稱列表(SheetNames)以及各個工作表的數(shù)據(jù)結(jié)構(gòu)(Sheets)。為了有效提取和處理 Excel 文件中的數(shù)據(jù),開發(fā)者必須深入理解 Workbook 對象的結(jié)構(gòu)及其子對象的組織方式。本章將逐步解析 Workbook 的核心屬性與數(shù)據(jù)結(jié)構(gòu),并通過代碼示例說明如何遍歷和訪問其中的數(shù)據(jù)。

4.1 Workbook對象的核心屬性

4.1.1 SheetNames數(shù)組的作用

SheetNames Workbook 對象中的一個數(shù)組屬性,用于存儲 Excel 文件中所有工作表的名稱。Excel 文件通常包含多個工作表(Sheet),例如“Sheet1”、“Sheet2”等。在前端處理文件時,通常需要根據(jù)名稱動態(tài)訪問特定的工作表。

const workbook = XLSX.readFile('example.xlsx');
console.log(workbook.SheetNames);
// 輸出類似 ["Sheet1", "Sheet2"]

代碼邏輯分析:

  • XLSX.readFile('example.xlsx') :讀取本地 Excel 文件,返回一個 Workbook 對象。
  • workbook.SheetNames :訪問 Workbook 中的 SheetNames 屬性,它是一個數(shù)組,包含所有工作表的名稱。
  • console.log(...) :將名稱數(shù)組輸出到控制臺,便于開發(fā)者查看和調(diào)試。

4.1.2 Sheets對象的組成與結(jié)構(gòu)

Sheets Workbook 對象中另一個核心屬性,它是一個對象(Object),鍵(Key)為工作表名稱,值(Value)為對應(yīng)的工作表對象(Sheet Object)。每個 Sheet 對象中存儲了該工作表中所有單元格的數(shù)據(jù)及其格式信息。

const sheetNames = workbook.SheetNames;
const sheets = workbook.Sheets;

sheetNames.forEach(sheetName => {
    const sheet = sheets[sheetName];
    console.log(`Sheet: ${sheetName}`, sheet);
});

代碼邏輯分析:

  • workbook.Sheets :獲取 Workbook 中的所有工作表對象。
  • sheetNames.forEach(...) :遍歷所有工作表名稱。
  • sheets[sheetName] :通過名稱訪問對應(yīng)的 Sheet 對象。
  • console.log(...) :輸出每個 Sheet 對象的內(nèi)容,幫助開發(fā)者理解其內(nèi)部結(jié)構(gòu)。

4.2 Sheet對象的數(shù)據(jù)結(jié)構(gòu)解析

4.2.1 單元格數(shù)據(jù)的表示方式(A1、B2等)

js-xlsx 中,Sheet 對象的每個單元格由其地址(如 A1、B2 等)作為鍵進行存儲。每個單元格數(shù)據(jù)以對象形式存儲,包含 .v (值)、 .t (類型)、 .w (顯示值)等字段。

const sheet = workbook.Sheets['Sheet1'];
const cellA1 = sheet['A1'];
console.log(cellA1);

輸出示例:

{
  "v": "姓名",
  "t": "s",
  "w": "姓名"
}

參數(shù)說明:

  • v :單元格的實際值(value)。
  • t :單元格的數(shù)據(jù)類型(s 表示字符串,n 表示數(shù)字,d 表示日期等)。
  • w :單元格的顯示格式值(formatted value)。

4.2.2 各類型數(shù)據(jù)的存儲格式(數(shù)值、字符串、日期等)

不同類型的單元格數(shù)據(jù)在 Sheet 對象中以不同的方式存儲,開發(fā)者需要根據(jù)類型字段 .t 來判斷如何處理數(shù)據(jù)。

類型標識符數(shù)據(jù)類型示例值
"s" 字符串"姓名"
"n" 數(shù)值89.5
"d" 日期"2023-01-01"
"b" 布爾值true / false
"e" 錯誤值#DIV/0!

代碼示例:根據(jù)類型解析單元格內(nèi)容

function getCellValue(cell) {
    if (!cell) return '';
    switch(cell.t) {
        case 's': // 字符串
            return cell.v;
        case 'n': // 數(shù)值
            return cell.v;
        case 'd': // 日期
            return cell.w;
        case 'b': // 布爾值
            return cell.v ? '是' : '否';
        case 'e': // 錯誤
            return '錯誤值: ' + cell.w;
        default:
            return '';
    }
}

邏輯分析:

  • 函數(shù) getCellValue(cell) 接收一個單元格對象。
  • 使用 switch 判斷 .t 類型,返回對應(yīng)的值。
  • 若單元格為空或未定義,返回空字符串。
  • 對于日期類型,使用 .w 獲取格式化字符串而非原始時間戳。

4.3 遍歷工作簿內(nèi)容

4.3.1 遍歷SheetNames獲取工作表名稱

遍歷 SheetNames 是訪問每個工作表的前提。通過名稱訪問對應(yīng)的 Sheet 對象,可以進一步提取數(shù)據(jù)。

const workbook = XLSX.readFile('data.xlsx');
workbook.SheetNames.forEach((sheetName, index) => {
    console.log(`第 ${index + 1} 個工作表名稱:${sheetName}`);
});

流程圖說明:

graph TD
    A[開始] --> B[讀取Excel文件]
    B --> C[獲取SheetNames數(shù)組]
    C --> D[遍歷數(shù)組]
    D --> E[輸出每個Sheet名稱]
    E --> F[結(jié)束]

邏輯分析:

  • 讀取 Excel 文件后,遍歷 SheetNames 數(shù)組。
  • 使用 forEach 方法,傳入當前名稱與索引。
  • 輸出每個工作表名稱,便于后續(xù)訪問。

4.3.2 動態(tài)訪問不同工作表的數(shù)據(jù)

在實際應(yīng)用中,常常需要根據(jù)用戶選擇或業(yè)務(wù)邏輯動態(tài)訪問不同工作表的數(shù)據(jù)。以下示例演示如何根據(jù)名稱訪問特定工作表并提取數(shù)據(jù):

function getSheetData(sheetName) {
    const sheet = workbook.Sheets[sheetName];
    const data = [];

    const range = XLSX.utils.decode_range(sheet['!ref']);
    for (let row = range.s.r; row <= range.e.r; row++) {
        const rowData = [];
        for (let col = range.s.c; col <= range.e.c; col++) {
            const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
            const cell = sheet[cellAddress];
            rowData.push(getCellValue(cell));
        }
        data.push(rowData);
    }
    return data;
}

表格展示:函數(shù) getSheetData 返回結(jié)構(gòu)示例

姓名年齡生日
張三281995-03-15
李四321990-07-22

邏輯分析:

  • XLSX.utils.decode_range(sheet['!ref']) :解析工作表的范圍,如 "A1:C3"
  • 使用雙層循環(huán)遍歷行和列。
  • 通過 XLSX.utils.encode_cell 構(gòu)建單元格地址。
  • 調(diào)用 getCellValue 提取數(shù)據(jù)。
  • 將每行數(shù)據(jù)組合為二維數(shù)組返回。

通過本章內(nèi)容,我們深入解析了 Workbook 對象的核心屬性與結(jié)構(gòu),掌握了 SheetNames Sheets 的作用,并學(xué)會了如何遍歷和提取單元格數(shù)據(jù)。下一章我們將進一步探討如何獲取工作表名稱列表,并動態(tài)訪問具體的工作表內(nèi)容,為前端 Excel 數(shù)據(jù)處理打下堅實基礎(chǔ)。

5. 獲取SheetNames與訪問具體工作表

在前端使用 js-xlsx 讀取 Excel 文件后,開發(fā)者通常需要對工作簿中的多個工作表進行訪問與處理。Excel 文件可以包含多個工作表(Sheet),每個工作表對應(yīng)不同的數(shù)據(jù)集或業(yè)務(wù)邏輯。本章將詳細介紹如何獲取 Excel 文件中所有工作表的名稱,以及如何訪問特定名稱的工作表,并實現(xiàn)數(shù)據(jù)的動態(tài)展示與切換。

5.1 獲取Excel文件中的所有工作表名稱

5.1.1 SheetNames數(shù)組的讀取方法

在使用 js-xlsx 解析 Excel 文件后,會得到一個 workbook 對象,其中包含了一個名為 SheetNames 的數(shù)組,該數(shù)組中存儲了該工作簿中所有工作表的名稱。

const workbook = XLSX.read(data, { type: 'array' });
const sheetNames = workbook.SheetNames;
console.log(sheetNames); // 輸出所有工作表名稱,例如:["Sheet1", "Sheet2"]

代碼解析:
-  XLSX.read(data, { type: 'array' })  :將二進制數(shù)據(jù)  data  轉(zhuǎn)換為工作簿對象。
-  workbook.SheetNames  :獲取所有工作表名稱組成的數(shù)組。
-  console.log(sheetNames)  :輸出工作表名稱數(shù)組,用于調(diào)試或后續(xù)操作。

該數(shù)組可以用于生成工作表名稱下拉框,或作為數(shù)據(jù)展示的入口。開發(fā)者可以通過遍歷該數(shù)組,動態(tài)獲取每個工作表的數(shù)據(jù)。

示例:遍歷SheetNames并展示名稱

sheetNames.forEach((name, index) => {
    console.log(`工作表${index + 1}名稱為:${name}`);
});

代碼邏輯說明:
- 使用  forEach  遍歷  SheetNames  數(shù)組。
- 輸出每個工作表名稱及其索引位置,便于后續(xù)選擇。

5.1.2 多工作表文件的處理策略

對于包含多個工作表的 Excel 文件,處理策略主要包括:

處理方式說明
逐個讀取按照  SheetNames  順序,依次讀取每個工作表的數(shù)據(jù)
按需加載用戶選擇工作表后,再讀取對應(yīng)數(shù)據(jù),減少前端內(nèi)存占用
合并數(shù)據(jù)將多個工作表的數(shù)據(jù)合并為一個數(shù)據(jù)集進行展示

優(yōu)化建議:
- 對于大型 Excel 文件,推薦采用按需加載策略,避免一次性讀取所有數(shù)據(jù)導(dǎo)致性能下降。
- 可以結(jié)合前端組件(如 Tab 面板)實現(xiàn)多工作表切換。

5.2 訪問指定名稱的工作表

5.2.1 通過XLSX.utils.aoa_to_sheet解析Sheet對象

在獲取 workbook 后,可以通過 workbook.Sheets[SheetName] 獲取對應(yīng)的工作表對象。該對象中包含了工作表的原始數(shù)據(jù)結(jié)構(gòu),包括單元格地址與值的映射。

const sheetName = sheetNames[0]; // 獲取第一個工作表名稱
const worksheet = workbook.Sheets[sheetName]; // 獲取工作表對象
console.log(worksheet);

參數(shù)說明:
-  sheetNames[0]  :表示第一個工作表的名稱,如  "Sheet1"  。
-  worksheet  :返回的工作表對象,結(jié)構(gòu)為  { '!ref': 'A1:C3', A1: { v: '標題' }, B1: { v: 123 }, ... }  。

若需要將工作表數(shù)據(jù)轉(zhuǎn)換為二維數(shù)組,可以使用 XLSX.utils.sheet_to_json XLSX.utils.sheet_to_aoa 方法:

const aoa = XLSX.utils.sheet_to_aoa(worksheet);
console.log(aoa);

代碼解析:
-  XLSX.utils.sheet_to_aoa(worksheet)  :將工作表轉(zhuǎn)換為二維數(shù)組。
-  aoa  :輸出為二維數(shù)組,如  [['標題', '數(shù)值'], ['A', 10], ['B', 20]]  。

5.2.2 獲取Sheet的原始數(shù)據(jù)格式

工作表對象(Sheet)的原始數(shù)據(jù)結(jié)構(gòu)如下:

{
  "!ref": "A1:C3",
  "A1": { "t": "s", "v": "姓名" },
  "B1": { "t": "s", "v": "年齡" },
  "C1": { "t": "s", "v": "性別" },
  "A2": { "t": "s", "v": "張三" },
  "B2": { "t": "n", "v": 28 },
  "C2": { "t": "s", "v": "男" }
}

字段說明:
-  !ref  :表示數(shù)據(jù)范圍,這里是  A1:C3  。
-  t  :表示單元格數(shù)據(jù)類型,如:
-  's'  :字符串(String)
-  'n'  :數(shù)值(Number)
-  'd'  :日期(Date)
-  v  :表示單元格的值。

開發(fā)者可以通過遍歷該結(jié)構(gòu)來手動解析數(shù)據(jù),或使用 XLSX.utils.sheet_to_json 方法進行自動轉(zhuǎn)換。

5.3 工作表數(shù)據(jù)的動態(tài)展示

5.3.1 將工作表數(shù)據(jù)渲染至HTML表格

將 Excel 數(shù)據(jù)渲染為 HTML 表格是常見的需求。以下是一個完整的實現(xiàn)示例:

<table id="excelTable" border="1"></table>
function renderTable(sheetData) {
    const table = document.getElementById('excelTable');
    table.innerHTML = ''; // 清空舊數(shù)據(jù)

    // 遍歷二維數(shù)組
    sheetData.forEach(row => {
        const tr = document.createElement('tr');
        row.forEach(cell => {
            const td = document.createElement('td');
            td.textContent = cell;
            tr.appendChild(td);
        });
        table.appendChild(tr);
    });
}

// 示例:讀取第一個工作表并渲染
const sheetName = sheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const aoa = XLSX.utils.sheet_to_aoa(worksheet);
renderTable(aoa);

代碼邏輯分析:
-  renderTable(sheetData)  :接收二維數(shù)組,將其渲染為 HTML 表格。
-  sheetData.forEach(...)  :遍歷每一行。
- 創(chuàng)建  tr  和  td  元素,填充單元格內(nèi)容。
- 最終將表格插入到頁面中。

5.3.2 支持多Sheet切換的前端實現(xiàn)

為了實現(xiàn)多工作表切換功能,可以添加下拉框讓用戶選擇工作表名稱,然后動態(tài)加載并渲染對應(yīng)數(shù)據(jù)。

<select id="sheetSelector"></select>
<table id="excelTable" border="1"></table>
const sheetSelector = document.getElementById('sheetSelector');

// 填充下拉框
sheetNames.forEach(name => {
    const option = document.createElement('option');
    option.value = name;
    option.textContent = name;
    sheetSelector.appendChild(option);
});

// 監(jiān)聽下拉框變化
sheetSelector.addEventListener('change', () => {
    const selectedSheet = sheetSelector.value;
    const worksheet = workbook.Sheets[selectedSheet];
    const aoa = XLSX.utils.sheet_to_aoa(worksheet);
    renderTable(aoa);
});

代碼說明:
- 使用  select  元素創(chuàng)建下拉框。
- 遍歷  sheetNames  ,為每個工作表名稱創(chuàng)建一個  option  。
- 添加事件監(jiān)聽器,當下拉框選項改變時,重新加載并渲染對應(yīng)工作表數(shù)據(jù)。

流程圖:多Sheet切換實現(xiàn)邏輯

graph TD
    A[用戶選擇工作表] --> B[獲取工作表名稱]
    B --> C[從workbook中獲取對應(yīng)Sheet]
    C --> D[轉(zhuǎn)換為二維數(shù)組]
    D --> E[渲染為HTML表格]

流程圖說明:
- 用戶通過下拉框選擇工作表名稱。
- 獲取該名稱對應(yīng)的工作表對象。
- 將工作表數(shù)據(jù)轉(zhuǎn)換為二維數(shù)組。
- 渲染為 HTML 表格展示給用戶。

本章深入講解了如何獲取 Excel 文件中的所有工作表名稱、訪問指定工作表以及實現(xiàn)數(shù)據(jù)的動態(tài)展示與切換。通過 SheetNames 數(shù)組可以獲取所有工作表名稱,結(jié)合 workbook.Sheets[name] 可以訪問具體工作表的數(shù)據(jù)。此外,使用 XLSX.utils.sheet_to_aoa 可將數(shù)據(jù)轉(zhuǎn)換為二維數(shù)組,并結(jié)合 HTML 動態(tài)渲染為表格。最后,通過下拉框?qū)崿F(xiàn)了多工作表切換功能,為后續(xù)的數(shù)據(jù)展示與交互奠定了基礎(chǔ)。

6. 使用sheet_to_json轉(zhuǎn)換數(shù)據(jù)為數(shù)組

在前端處理 Excel 文件的過程中,一個非常關(guān)鍵的步驟是將 Excel 中的工作表數(shù)據(jù)轉(zhuǎn)化為 JavaScript 可操作的格式。 sheet_to_json js-xlsx 庫提供的一個核心方法,用于將 Sheet 對象轉(zhuǎn)換為 JSON 數(shù)組形式,便于后續(xù)的數(shù)據(jù)處理、展示或上傳。

6.1 sheet_to_json方法的基本用法

sheet_to_json XLSX.utils 模塊下的一個工具函數(shù),能夠?qū)⒁粋€ Sheet 對象(即工作表)轉(zhuǎn)換為 JavaScript 數(shù)組對象。

6.1.1 參數(shù)配置與字段映射

const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
  header: 1, // 設(shè)置第一行為表頭
  defval: null, // 空值用 null 填充
  raw: true // 禁止自動轉(zhuǎn)換數(shù)據(jù)類型
});
參數(shù)名類型默認值描述
header number / array1設(shè)置哪一行作為字段名(如 header: 1 表示第一行為字段名)
defval anyundefined當單元格為空時填充的默認值
raw booleanfalse是否保留原始數(shù)據(jù)類型(不轉(zhuǎn)換數(shù)字、日期等)
range number0指定讀取的行范圍(如只讀取前5行)

6.1.2 數(shù)據(jù)轉(zhuǎn)換的格式規(guī)范

header: 1 時, sheet_to_json 會將第一行作為字段名,后續(xù)每一行對應(yīng)一個對象。例如:

[
  { "姓名": "張三", "年齡": 25 },
  { "姓名": "李四", "年齡": 30 }
]

header: 0 ,則默認以 A、B、C 作為字段名,輸出如下:

[
  { "A": "姓名", "B": "年齡" },
  { "A": "張三", "B": 25 }
]

6.2 數(shù)據(jù)轉(zhuǎn)換的進階技巧

6.2.1 忽略空行與無效數(shù)據(jù)

可以通過 sheet_to_json blankrows 參數(shù)來控制是否忽略空行,默認為 true ,表示不忽略。若要忽略空行,可以結(jié)合 JavaScript 的 filter 方法處理:

const filteredData = jsonData.filter(row => Object.values(row).some(cell => cell !== null && cell !== ""));

6.2.2 自定義列名與字段命名

如果你希望將 Excel 中的列頭映射為自定義字段名,可以在讀取后手動重命名字段:

const renamedData = jsonData.map(row => ({
  name: row['姓名'],
  age: row['年齡']
}));

或者使用 sheet_to_json 前對 Sheet 對象進行預(yù)處理,替換原始列名。

6.3 數(shù)據(jù)處理與JavaScript數(shù)組操作結(jié)合

6.3.1 使用filter、map等方法處理轉(zhuǎn)換后的數(shù)據(jù)

一旦數(shù)據(jù)被轉(zhuǎn)換為 JSON 數(shù)組,就可以使用常見的數(shù)組方法進行處理:

// 篩選年齡大于25的數(shù)據(jù)
const adults = renamedData.filter(person => person.age > 25);

// 提取所有名字
const names = renamedData.map(person => person.name);

6.3.2 數(shù)據(jù)驗證與錯誤處理機制

在數(shù)據(jù)處理過程中,應(yīng)加入數(shù)據(jù)校驗邏輯,防止非法數(shù)據(jù)導(dǎo)致運行錯誤:

const validData = renamedData.filter(person => {
  if (typeof person.age !== 'number') {
    console.warn('年齡字段錯誤:', person);
    return false;
  }
  return true;
});

也可以結(jié)合 try-catch 捕獲轉(zhuǎn)換過程中的異常:

try {
  const jsonData = XLSX.utils.sheet_to_json(worksheet);
} catch (e) {
  console.error('數(shù)據(jù)轉(zhuǎn)換失敗:', e);
}

6.4 示例代碼實現(xiàn)完整讀取流程

6.4.1 完整代碼結(jié)構(gòu)與邏輯說明

以下是一個完整的前端讀取 Excel 文件并轉(zhuǎn)換為 JSON 數(shù)組的示例代碼:

<input type="file" id="excelFile" accept=".xlsx, .xls" />
<table id="dataTable"></table>

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script>
  document.getElementById('excelFile').addEventListener('change', function(e) {
    const file = e.target.files[0];
    const reader = new FileReader();

    reader.onload = function(event) {
      const data = new Uint8Array(event.target.result);
      const workbook = XLSX.read(data, { type: 'array' });
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];

      // 轉(zhuǎn)換為JSON數(shù)組
      const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

      // 手動映射字段
      const renamedData = jsonData.slice(1).map(row => ({
        name: row[0],
        age: row[1]
      }));

      // 渲染到HTML表格
      const table = document.getElementById('dataTable');
      table.innerHTML = '';
      renamedData.forEach(person => {
        const tr = document.createElement('tr');
        tr.innerHTML = `<td>${person.name}</td><td>${person.age}</td>`;
        table.appendChild(tr);
      });
    };

    reader.readAsArrayBuffer(file);
  });
</script>

6.4.2 實際運行效果與調(diào)試技巧

上述代碼實現(xiàn)了一個完整的流程:
1. 用戶選擇 Excel 文件;
2. 通過 FileReader 讀取文件;
3. 使用 XLSX.read 解析為 Workbook;
4. 使用 sheet_to_json 轉(zhuǎn)換為 JSON;
5. 映射字段并渲染到 HTML 表格。

調(diào)試時建議在控制臺打印中間變量:

console.log('原始數(shù)據(jù):', jsonData);
console.log('映射后數(shù)據(jù):', renamedData);

通過瀏覽器開發(fā)者工具(F12)查看控制臺輸出和 DOM 元素,可以快速定位問題所在。

以上就是JavaScript前端讀取Excel文件的實戰(zhàn)指南的詳細內(nèi)容,更多關(guān)于JavaScript讀取Excel文件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

定州市| 江阴市| 泸州市| 萨嘎县| 九江县| 托里县| 山阴县| 兴仁县| 托克托县| 怀集县| 河间市| 包头市| 皮山县| 馆陶县| 那曲县| 全南县| 大庆市| 大厂| 罗江县| 普陀区| 惠水县| 周宁县| 尖扎县| 同仁县| 溧水县| 康定县| 南靖县| 彝良县| 阳高县| 河南省| 东宁县| 东阿县| 南安市| 江永县| 且末县| 韶关市| 扶风县| 达拉特旗| 蒙山县| 扶余县| 崇信县|