JavaScript前端讀取Excel文件的實戰(zhàn)指南
簡介:在前端開發(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ù)名 | 類型 | 必填 | 描述 |
|---|---|---|---|
| filename | string | 是 | 文件路徑或文件名 |
| opts | object | 否 | 配置選項,如 type , sheet , cellDates 等 |
常見配置選項:
| 選項名 | 類型 | 默認值 | 描述 |
|---|---|---|---|
| type | string | "base64" | 讀取類型,可選 base64 , binary , buffer , array , file |
| sheet | number 或 string | 無 | 指定讀取的工作表索引或名稱 |
| cellDates | boolean | 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: { ... }
}
| 屬性名 | 類型 | 描述 |
|---|---|---|
| SheetNames | Array<string> | 所有工作表名稱 |
| Sheets | Object | 以工作表名稱為鍵,對應(yīng)工作表數(shù)據(jù)對象 |
| Props | Object | 文檔屬性(如創(chuàng)建者、修改時間等) |
| Custprops | Object | 自定義屬性 |
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ù)對象包含以下屬性:
| 屬性 | 類型 | 描述 |
|---|---|---|
| v | any | 單元格值 |
| t | string | 值的類型,如 'n' (數(shù)值)、 's' (字符串)、 'd' (日期)等 |
| z | string | 數(shù)值格式(如日期格式) |
| w | string | 格式化后的顯示值 |
示例代碼
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)示例
| 姓名 | 年齡 | 生日 |
|---|---|---|
| 張三 | 28 | 1995-03-15 |
| 李四 | 32 | 1990-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 / array | 1 | 設(shè)置哪一行作為字段名(如 header: 1 表示第一行為字段名) |
defval | any | undefined | 當單元格為空時填充的默認值 |
raw | boolean | false | 是否保留原始數(shù)據(jù)類型(不轉(zhuǎn)換數(shù)字、日期等) |
range | number | 0 | 指定讀取的行范圍(如只讀取前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)文章
使用bootstrap3開發(fā)響應(yīng)式網(wǎng)站
這篇文章主要為大家詳細介紹了使用bootstrap3開發(fā)響應(yīng)式網(wǎng)站的具體代碼,感興趣的小伙伴們可以參考一下2016-05-05
用js實現(xiàn)的十進制的顏色值轉(zhuǎn)換成十六進制的代碼
用js實現(xiàn)的十進制的顏色值轉(zhuǎn)換成十六進制的代碼...2007-03-03
深入淺出webpack教程系列_安裝與基本打包用法和命令參數(shù)詳解
下面小編就為大家?guī)硪黄钊霚\出webpack教程系列_安裝與基本打包用法和命令參數(shù)詳解。小編覺得挺不錯的,現(xiàn)在就想給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09

