JavaScript讀取Excel文件實(shí)戰(zhàn)指南
簡(jiǎn)介:在JavaScript環(huán)境中,讀取和處理Excel表格數(shù)據(jù)是常見的開發(fā)需求,尤其在前后端數(shù)據(jù)交互場(chǎng)景中。本文介紹的“xlsx.full.min.js”是一個(gè)輕量級(jí)但功能強(qiáng)大的JavaScript庫(kù)XLSX的核心文件,它支持XLS、XLSX、CSV和JSON等多種格式的讀寫操作。通過(guò)FileReader API,開發(fā)者可以輕松實(shí)現(xiàn)用戶上傳Excel文件的解析與處理;同時(shí),XLSX還支持?jǐn)?shù)據(jù)轉(zhuǎn)換、樣式設(shè)置、公式計(jì)算等高級(jí)功能。本資料涵蓋XLSX庫(kù)的基本使用、核心API、數(shù)據(jù)解析方法以及性能優(yōu)化技巧,幫助開發(fā)者快速掌握在前端或后端項(xiàng)目中集成Excel數(shù)據(jù)處理的能力。

1. JavaScript處理Excel數(shù)據(jù)概述
隨著Web應(yīng)用在企業(yè)級(jí)數(shù)據(jù)處理場(chǎng)景中的深入應(yīng)用,前端對(duì)Excel文件的操作需求日益增長(zhǎng)。JavaScript作為前端開發(fā)的核心語(yǔ)言,結(jié)合現(xiàn)代瀏覽器能力,已經(jīng)能夠高效地實(shí)現(xiàn)Excel文件的讀取、解析與生成。本章將引導(dǎo)讀者理解為何在Web環(huán)境中選擇JavaScript進(jìn)行Excel數(shù)據(jù)處理,并探討其背后的技術(shù)原理與常見應(yīng)用場(chǎng)景。通過(guò)對(duì)比主流處理方案,為后續(xù)章節(jié)中將要使用的XLSX庫(kù)奠定技術(shù)選型基礎(chǔ)。
2. XLSX庫(kù)簡(jiǎn)介與基礎(chǔ)使用
XLSX庫(kù),也稱為SheetJS,是一個(gè)廣泛使用的開源JavaScript庫(kù),專門用于在前端和后端(Node.js)中讀寫Excel文件。它支持多種文件格式,包括 .xlsx 、 .xls 、 .csv 、 .ods 等,具有高度的兼容性和靈活性。在現(xiàn)代Web應(yīng)用中,特別是在數(shù)據(jù)導(dǎo)入導(dǎo)出、報(bào)表生成和數(shù)據(jù)展示場(chǎng)景中,XLSX庫(kù)因其輕量級(jí)、無(wú)需依賴、跨平臺(tái)等特性,成為處理Excel數(shù)據(jù)的首選工具。
本章將從XLSX庫(kù)的核心功能入手,逐步引導(dǎo)讀者了解其支持的文件格式與兼容性、引入方式、基本數(shù)據(jù)結(jié)構(gòu),并搭建一個(gè)基礎(chǔ)的開發(fā)環(huán)境,為后續(xù)章節(jié)中深入學(xué)習(xí)其讀寫操作與數(shù)據(jù)處理打下堅(jiān)實(shí)基礎(chǔ)。
2.1 XLSX庫(kù)的核心功能概述
XLSX庫(kù)的核心優(yōu)勢(shì)在于其強(qiáng)大的Excel文件處理能力,無(wú)論是讀取還是寫入,都能滿足大多數(shù)應(yīng)用場(chǎng)景的需求。以下將從文件格式支持與讀寫流程兩個(gè)方面進(jìn)行介紹。
2.1.1 支持的文件格式與兼容性
XLSX庫(kù)支持多種電子表格格式的讀寫操作,主要包括:
| 文件格式 | 描述 | 是否支持讀 | 是否支持寫 |
|---|---|---|---|
.xlsx | Office Open XML 格式,Excel 2007+ 默認(rèn)格式 | ? | ? |
.xls | Excel Binary Workbook 格式,Excel 97-2003 使用 | ? | ? |
.csv | 逗號(hào)分隔值文件,常用于數(shù)據(jù)交換 | ? | ? |
.ods | OpenDocument Spreadsheet 格式,常用于LibreOffice/OpenOffice | ? | ? |
.fods | Flat OpenDocument Spreadsheet 格式 | ? | ? |
? 表示支持讀寫操作。
XLSX庫(kù)兼容性方面表現(xiàn)優(yōu)異,可在主流瀏覽器(如Chrome、Firefox、Safari)和Node.js環(huán)境中運(yùn)行。此外,它不依賴任何框架(如jQuery或React),可以無(wú)縫集成到各種前端項(xiàng)目中。
2.1.2 讀寫操作的基本流程
XLSX庫(kù)的基本操作流程分為以下幾個(gè)步驟:
graph TD
A[讀取Excel文件] --> B[解析為工作簿對(duì)象]
B --> C{選擇工作表}
C --> D[提取數(shù)據(jù)]
D --> E[轉(zhuǎn)換為JSON/數(shù)組]
E --> F[展示或處理數(shù)據(jù)]
G[準(zhǔn)備數(shù)據(jù)] --> H[創(chuàng)建工作簿對(duì)象]
H --> I[創(chuàng)建工作表]
I --> J[寫入Excel文件]
以讀取為例,XLSX庫(kù)通過(guò) XLSX.readFile 或 XLSX.read 方法讀取文件,將其解析為一個(gè)包含多個(gè)工作表的“工作簿”對(duì)象(Workbook),然后可以選擇特定工作表(Sheet),并通過(guò) XLSX.utils.sheet_to_json 等方法提取數(shù)據(jù),最終以JSON或數(shù)組形式返回,供后續(xù)業(yè)務(wù)邏輯處理。
2.2 引入XLSX庫(kù)的多種方式
根據(jù)不同的開發(fā)環(huán)境,XLSX庫(kù)可以通過(guò)多種方式引入到項(xiàng)目中,以下將分別介紹使用CDN、Node.js安裝以及結(jié)合Webpack等構(gòu)建工具的方式。
2.2.1 使用CDN引入
在前端HTML頁(yè)面中,最簡(jiǎn)單的方式是通過(guò)CDN引入XLSX庫(kù)。以下是一個(gè)HTML示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XLSX CDN 引入示例</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
</head>
<body>
<input type="file" id="fileInput" />
<script>
document.getElementById('fileInput').addEventListener('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function(evt) {
const data = evt.target.result;
const workbook = XLSX.read(data, { type: 'binary' });
console.log(workbook);
};
reader.readAsBinaryString(file);
});
</script>
</body>
</html>邏輯分析:
<script src="...">引入XLSX庫(kù)。input元素允許用戶選擇Excel文件。FileReader用于讀取文件內(nèi)容。XLSX.read(data, { type: 'binary' })將文件內(nèi)容解析為工作簿對(duì)象。
參數(shù)說(shuō)明:
type: 'binary':表示傳入的數(shù)據(jù)為二進(jìn)制字符串格式,適用于Excel 2007+(.xlsx)文件。
2.2.2 在Node.js環(huán)境中安裝
在Node.js項(xiàng)目中,可以通過(guò)npm安裝XLSX庫(kù):
npm install xlsx
安裝完成后,可以在JavaScript文件中通過(guò) require 方式引入:
const XLSX = require('xlsx');
// 讀取Excel文件
const workbook = XLSX.readFile('example.xlsx');
// 獲取所有工作表名稱
const sheetNames = workbook.SheetNames;
console.log(sheetNames);
// 獲取第一個(gè)工作表
const sheetName = sheetNames[0];
const worksheet = workbook.Sheets[sheetName];
// 轉(zhuǎn)換為JSON格式
const jsonData = XLSX.utils.sheet_to_json(worksheet);
console.log(jsonData);邏輯分析:
XLSX.readFile用于讀取本地Excel文件。workbook.SheetNames是一個(gè)數(shù)組,包含所有工作表名稱。workbook.Sheets[sheetName]獲取指定名稱的工作表對(duì)象。sheet_to_json方法將工作表轉(zhuǎn)換為JSON數(shù)組。
參數(shù)說(shuō)明:
sheet_to_json可以接受一個(gè)配置對(duì)象,例如{ header: 1 }表示將第一行作為數(shù)據(jù)處理,返回二維數(shù)組。
2.2.3 結(jié)合前端構(gòu)建工具(如Webpack)
在使用Webpack等構(gòu)建工具的項(xiàng)目中,可以通過(guò)ES6的 import 方式引入XLSX庫(kù):
npm install xlsx
然后在你的JavaScript模塊中:
import * as XLSX from 'xlsx';
function handleFile(file) {
const reader = new FileReader();
reader.onload = (e) => {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: 'array' });
const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
const json = XLSX.utils.sheet_to_json(firstSheet);
console.log(json);
};
reader.readAsArrayBuffer(file);
}邏輯分析:
- 使用
readAsArrayBuffer讀取文件為ArrayBuffer。 type: 'array'表示傳入的數(shù)據(jù)是ArrayBuffer類型。- 后續(xù)流程與Node.js中類似,獲取工作表并轉(zhuǎn)換為JSON。
參數(shù)說(shuō)明:
type: 'array'是處理ArrayBuffer時(shí)的標(biāo)準(zhǔn)參數(shù),確保正確解析Excel文件。
2.3 初識(shí)Excel文件結(jié)構(gòu)
要高效地使用XLSX庫(kù),理解Excel文件的基本結(jié)構(gòu)是關(guān)鍵。Excel文件本質(zhì)上是一個(gè)包含多個(gè)工作表的工作簿,每個(gè)工作表由行和列組成,行與列的交點(diǎn)即為單元格。
2.3.1 工作簿、工作表與單元格的關(guān)系
Excel文件結(jié)構(gòu)可以理解為一個(gè)三層嵌套關(guān)系:
工作簿(Workbook)
└── 工作表(Sheet)
└── 單元格(Cell)- 工作簿(Workbook) :整個(gè)Excel文件,通常以
.xlsx或.xls為后綴。 - 工作表(Sheet) :工作簿中的一張表格,一個(gè)工作簿可以包含多個(gè)工作表,默認(rèn)名稱如
Sheet1,Sheet2等。 - 單元格(Cell) :工作表中的最小單位,用于存儲(chǔ)數(shù)據(jù)、公式、樣式等信息。
在XLSX庫(kù)中,這些結(jié)構(gòu)通過(guò)以下對(duì)象表示:
workbook.SheetNames: 包含所有工作表名稱的數(shù)組。workbook.Sheets: 一個(gè)對(duì)象,鍵為工作表名稱,值為工作表對(duì)象(Sheet)。worksheet['A1']: 表示A1單元格的數(shù)據(jù)對(duì)象。
2.3.2 行、列與單元格的索引方式
XLSX庫(kù)中的單元格索引方式遵循Excel的標(biāo)準(zhǔn)格式:
- 列索引 :使用字母表示,如
A,B, …,Z,AA,AB等。 - 行索引 :使用數(shù)字表示,從1開始,如
1,2,3等。 - 單元格地址 :由列和行組合而成,如
A1,B2,C10等。
XLSX庫(kù)提供了工具函數(shù)用于處理這些索引:
const XLSX = require('xlsx');
// 將列索引轉(zhuǎn)換為數(shù)字
const colNum = XLSX.utils.decode_col('C'); // 返回 2(從0開始)
// 將行索引轉(zhuǎn)換為數(shù)字
const rowNum = XLSX.utils.decode_row('5'); // 返回 4(從0開始)
// 將地址解析為對(duì)象
const cellAddress = XLSX.utils.decode_cell('B3');
console.log(cellAddress); // 輸出 { c: 1, r: 2 }
// 將對(duì)象轉(zhuǎn)換為地址字符串
const address = XLSX.utils.encode_cell({ c: 1, r: 2 }); // 返回 "B3"邏輯分析:
decode_col和decode_row用于將Excel格式的列/行索引轉(zhuǎn)換為程序中使用的數(shù)字。decode_cell和encode_cell實(shí)現(xiàn)地址字符串與對(duì)象之間的轉(zhuǎn)換。
2.4 開發(fā)環(huán)境搭建與測(cè)試用例準(zhǔn)備
在正式進(jìn)行Excel數(shù)據(jù)處理前,需要搭建一個(gè)基礎(chǔ)的開發(fā)環(huán)境,并準(zhǔn)備測(cè)試用例以驗(yàn)證代碼功能。
2.4.1 創(chuàng)建HTML頁(yè)面并引入XLSX庫(kù)
我們可以通過(guò)一個(gè)簡(jiǎn)單的HTML頁(yè)面來(lái)測(cè)試XLSX庫(kù)的功能:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>XLSX 測(cè)試頁(yè)面</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
</head>
<body>
<h2>上傳Excel文件</h2>
<input type="file" id="upload" accept=".xlsx,.xls,.csv" />
<h3>解析結(jié)果:</h3>
<pre id="output"></pre>
<script>
document.getElementById('upload').addEventListener('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function(evt) {
const data = evt.target.result;
const workbook = XLSX.read(data, { type: 'binary' });
const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
const json = XLSX.utils.sheet_to_json(firstSheet);
document.getElementById('output').textContent = JSON.stringify(json, null, 2);
};
reader.readAsBinaryString(file);
});
</script>
</body>
</html>功能說(shuō)明:
- 用戶選擇Excel文件后,通過(guò)
FileReader讀取文件內(nèi)容。 - 使用
XLSX.read解析為工作簿對(duì)象。 - 獲取第一個(gè)工作表并將其轉(zhuǎn)換為JSON格式。
- 顯示解析結(jié)果。
2.4.2 準(zhǔn)備測(cè)試Excel文件
為了驗(yàn)證上述代碼的功能,我們可以準(zhǔn)備一個(gè)簡(jiǎn)單的Excel測(cè)試文件,例如:
| 姓名 | 年齡 | 城市 |
|---|---|---|
| 張三 | 28 | 北京 |
| 李四 | 32 | 上海 |
| 王五 | 25 | 廣州 |
將上述內(nèi)容保存為 test.xlsx ,上傳到測(cè)試頁(yè)面后,應(yīng)能看到如下JSON輸出:
[
{
"姓名": "張三",
"年齡": 28,
"城市": "北京"
},
{
"姓名": "李四",
"年齡": 32,
"城市": "上海"
},
{
"姓名": "王五",
"年齡": 25,
"城市": "廣州"
}
]通過(guò)這個(gè)簡(jiǎn)單的測(cè)試,我們驗(yàn)證了XLSX庫(kù)的基本讀取和解析功能,為后續(xù)深入學(xué)習(xí)數(shù)據(jù)處理、格式轉(zhuǎn)換、寫入操作等打下了良好的基礎(chǔ)。
3. 讀取與解析Excel文件
在現(xiàn)代Web應(yīng)用中,處理Excel文件已經(jīng)成為數(shù)據(jù)交互和展示的重要環(huán)節(jié)。JavaScript通過(guò)強(qiáng)大的第三方庫(kù)如 SheetJS (即 xlsx 庫(kù)),為前端開發(fā)者提供了高效、靈活的Excel文件處理能力。本章將圍繞 讀取與解析Excel文件 展開,詳細(xì)介紹如何使用 xlsx 庫(kù)來(lái)加載、解析Excel文件,并提取其中的數(shù)據(jù),同時(shí)對(duì)數(shù)據(jù)的格式、空值、公式等進(jìn)行處理。
3.1 讀取Excel文件的基本方法
在使用JavaScript處理Excel文件之前,首先需要將文件加載到內(nèi)存中。 xlsx 庫(kù)提供了多種方式來(lái)讀取Excel文件,主要包括:
XLSX.readFile():用于讀取本地文件(適用于Node.js環(huán)境)XLSX.read():用于處理Base64編碼字符串或ArrayBuffer(適用于瀏覽器環(huán)境)
3.1.1 使用readFile方法加載本地文件
XLSX.readFile() 方法適用于Node.js環(huán)境下讀取本地磁盤上的Excel文件。
const XLSX = require('xlsx');
const workbook = XLSX.readFile('data.xlsx');
代碼邏輯分析:
- 第1行:引入
xlsx模塊。 - 第2行:使用
readFile方法加載名為data.xlsx的Excel文件,返回一個(gè)工作簿對(duì)象workbook。
參數(shù)說(shuō)明:
'data.xlsx':表示Excel文件的路徑,可以是相對(duì)路徑或絕對(duì)路徑。workbook:是一個(gè)包含整個(gè)Excel文件結(jié)構(gòu)的對(duì)象,包括多個(gè)工作表。
適用場(chǎng)景:
該方法適用于后端Node.js環(huán)境下的Excel文件處理,如導(dǎo)入數(shù)據(jù)、批量處理等場(chǎng)景。
3.1.2 使用read方法處理Base64或ArrayBuffer數(shù)據(jù)
在瀏覽器環(huán)境中,通常通過(guò) FileReader 讀取用戶上傳的文件,獲取其ArrayBuffer或Base64編碼后,再通過(guò) XLSX.read() 進(jìn)行解析。
const fileInput = document.getElementById('file');
fileInput.addEventListener('change', function (e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function (evt) {
const data = evt.target.result;
const workbook = XLSX.read(data, { type: 'array' }); // 或 'base64'
};
reader.readAsArrayBuffer(file);
});
代碼邏輯分析:
- 第1-2行:獲取文件輸入元素并監(jiān)聽其變化事件。
- 第3行:創(chuàng)建一個(gè)
FileReader對(duì)象。 - 第5-9行:當(dāng)文件讀取完成后,調(diào)用
XLSX.read()解析Excel數(shù)據(jù)。 - 第11行:以
ArrayBuffer格式讀取文件內(nèi)容。
參數(shù)說(shuō)明:
data:文件內(nèi)容,可以是ArrayBuffer或Base64字符串。{ type: 'array' }:指定輸入數(shù)據(jù)類型為ArrayBuffer,若使用Base64則應(yīng)為{ type: 'base64' }。
瀏覽器兼容性說(shuō)明:
該方法在主流瀏覽器中均支持,是前端處理Excel文件的常用手段。
3.2 解析Excel工作簿與工作表
Excel文件通常由一個(gè)或多個(gè)工作簿(Workbook)組成,每個(gè)工作簿包含多個(gè)工作表(Worksheet)。解析Excel的核心在于理解其結(jié)構(gòu)并從中提取所需數(shù)據(jù)。
3.2.1 獲取工作簿中的所有工作表名稱
加載完Excel文件后,可以通過(guò) workbook.SheetNames 獲取所有工作表的名稱。
const sheetNames = workbook.SheetNames; console.log(sheetNames); // 輸出如: ['Sheet1', 'Sheet2']
代碼邏輯分析:
- 第1行:獲取工作簿中所有工作表的名稱列表。
- 第2行:打印出工作表名稱數(shù)組。
數(shù)據(jù)結(jié)構(gòu)說(shuō)明:
workbook.SheetNames返回一個(gè)數(shù)組,包含每個(gè)工作表的名稱字符串。
3.2.2 根據(jù)名稱或索引獲取指定工作表
通過(guò)工作表名稱可以直接獲取對(duì)應(yīng)的工作表對(duì)象,也可以通過(guò)索引訪問。
const sheetName = sheetNames[0]; const worksheet = workbook.Sheets[sheetName];
代碼邏輯分析:
- 第1行:獲取第一個(gè)工作表的名稱。
- 第2行:通過(guò)名稱從
workbook.Sheets中獲取工作表對(duì)象。
工作表對(duì)象結(jié)構(gòu)說(shuō)明:
worksheet是一個(gè)對(duì)象,其鍵為單元格地址(如”A1”),值為包含單元格值的對(duì)象(如{ v: "Hello", t: "s" })。
示例結(jié)構(gòu):
{
"A1": { v: "Name", t: "s" },
"B1": { v: "Age", t: "s" },
"A2": { v: "Alice", t: "s" },
"B2": { v: 30, t: "n" }
}
3.3 數(shù)據(jù)提取與格式處理
在獲取到工作表對(duì)象后,下一步是提取數(shù)據(jù)并將其轉(zhuǎn)換為更易處理的格式(如JSON)。
3.3.1 將工作表數(shù)據(jù)轉(zhuǎn)換為JSON格式
XLSX.utils.sheet_to_json() 函數(shù)可以將工作表轉(zhuǎn)換為JSON數(shù)組。
const jsonData = XLSX.utils.sheet_to_json(worksheet); console.log(jsonData);
代碼邏輯分析:
- 第1行:使用
sheet_to_json函數(shù)將工作表轉(zhuǎn)換為JSON格式。 - 第2行:打印出轉(zhuǎn)換后的數(shù)據(jù)。
輸出示例:
[
{ "Name": "Alice", "Age": 30 },
{ "Name": "Bob", "Age": 25 }
]
參數(shù)說(shuō)明:
- 默認(rèn)情況下,
sheet_to_json()會(huì)將第一行作為字段名(key)。 - 可以通過(guò)設(shè)置選項(xiàng)控制行為,如:
XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // 返回二維數(shù)組
3.3.2 使用sheet_to_json函數(shù)提取數(shù)據(jù)
除了默認(rèn)轉(zhuǎn)換方式,還可以通過(guò)配置選項(xiàng)控制輸出格式。
const options = {
header: 1, // 返回二維數(shù)組
raw: true, // 不解析單元格格式
range: 1 // 自動(dòng)檢測(cè)范圍
};
const dataArray = XLSX.utils.sheet_to_json(worksheet, options);代碼邏輯分析:
- 第1-5行:定義轉(zhuǎn)換選項(xiàng)。
- 第7行:使用選項(xiàng)進(jìn)行數(shù)據(jù)提取。
參數(shù)說(shuō)明:
| 參數(shù)名 | 說(shuō)明 |
|---|---|
header | 若為1,則第一行作為數(shù)組索引;若為其他值,則作為字段名 |
raw | 若為true,則不自動(dòng)轉(zhuǎn)換單元格格式(如日期、數(shù)字) |
range | 控制數(shù)據(jù)范圍,若為1則自動(dòng)檢測(cè)有效數(shù)據(jù)區(qū)域 |
3.3.3 處理空值、公式與樣式信息
在實(shí)際數(shù)據(jù)中,可能會(huì)遇到空值、公式、樣式等復(fù)雜情況,需進(jìn)行特殊處理。
1. 處理空值
空單元格在轉(zhuǎn)換為JSON時(shí)可能被忽略,可以通過(guò)設(shè)置 defval 參數(shù)來(lái)填充默認(rèn)值。
const jsonData = XLSX.utils.sheet_to_json(worksheet, { defval: null });
2. 解析公式
默認(rèn)情況下,公式不會(huì)被解析,只返回公式字符串。若需獲取公式計(jì)算結(jié)果,需啟用 cellFormula 選項(xiàng):
const workbook = XLSX.read(data, { cellFormula: true });
此時(shí),單元格對(duì)象中將包含 .f 字段,表示公式本身, .v 字段表示計(jì)算結(jié)果。
3. 讀取樣式信息
樣式信息默認(rèn)不會(huì)被保留,若需讀取樣式,需在讀取時(shí)啟用 cellStyles 選項(xiàng):
const workbook = XLSX.read(data, { cellStyles: true });
此時(shí),每個(gè)單元格對(duì)象中將包含 .s 字段,表示樣式信息(如字體、顏色、邊框等)。
總結(jié)與延伸
本章深入講解了如何使用JavaScript結(jié)合 xlsx 庫(kù)讀取與解析Excel文件。從文件加載、工作簿結(jié)構(gòu)解析,到數(shù)據(jù)提取與格式處理,我們掌握了以下關(guān)鍵能力:
- 如何在Node.js和瀏覽器環(huán)境中讀取Excel文件;
- 如何獲取工作表并解析其結(jié)構(gòu);
- 如何將工作表數(shù)據(jù)轉(zhuǎn)換為JSON格式;
- 如何處理空值、公式與樣式信息。
在下一章中,我們將進(jìn)一步探討如何將解析后的數(shù)據(jù)重新生成Excel文件,并支持多種格式之間的轉(zhuǎn)換,實(shí)現(xiàn)完整的Excel數(shù)據(jù)處理閉環(huán)。
4. 數(shù)據(jù)轉(zhuǎn)換與表格生成
在現(xiàn)代Web應(yīng)用中,數(shù)據(jù)的雙向轉(zhuǎn)換能力尤為重要。Excel作為數(shù)據(jù)交互的通用格式,不僅需要支持從Excel讀取數(shù)據(jù)并轉(zhuǎn)換為結(jié)構(gòu)化數(shù)據(jù)(如JSON),也需要能夠?qū)⑶岸颂幚砗蟮臄?shù)據(jù)反向?qū)懭隕xcel,實(shí)現(xiàn)數(shù)據(jù)閉環(huán)。本章將重點(diǎn)講解如何使用XLSX庫(kù)將結(jié)構(gòu)化數(shù)據(jù)(如JSON、二維數(shù)組)轉(zhuǎn)換為Excel表格,并生成可下載或傳輸?shù)腅xcel文件。同時(shí),我們還將探討不同格式(如CSV、JSON)與Excel之間的互操作,以及在處理大型數(shù)據(jù)集時(shí)的性能優(yōu)化策略。
4.1 從JSON數(shù)據(jù)生成Excel工作表
XLSX庫(kù)提供了將JSON數(shù)據(jù)直接轉(zhuǎn)換為Excel工作表的能力,這對(duì)于前端生成報(bào)表、導(dǎo)出用戶數(shù)據(jù)等場(chǎng)景非常實(shí)用。核心方法是使用 XLSX.utils.json_to_sheet 函數(shù)。
4.1.1 使用json_to_sheet函數(shù)創(chuàng)建工作表
json_to_sheet 函數(shù)接收一個(gè)JSON數(shù)組作為輸入,并將其轉(zhuǎn)換為Excel工作表對(duì)象。該函數(shù)會(huì)自動(dòng)識(shí)別字段名作為表頭,并逐行填充數(shù)據(jù)。
const jsonData = [
{ name: "張三", age: 28, department: "技術(shù)部" },
{ name: "李四", age: 32, department: "市場(chǎng)部" },
{ name: "王五", age: 25, department: "財(cái)務(wù)部" }
];
const ws = XLSX.utils.json_to_sheet(jsonData);逐行解釋:
jsonData:是一個(gè)包含對(duì)象的數(shù)組,每個(gè)對(duì)象代表一行數(shù)據(jù)。XLSX.utils.json_to_sheet(jsonData):將該數(shù)組轉(zhuǎn)換為一個(gè)工作表對(duì)象ws,該對(duì)象可以添加到工作簿中。
4.1.2 添加表頭與字段映射
有時(shí)我們需要自定義表頭或字段順序,可以使用 header 選項(xiàng)來(lái)指定字段順序,或者使用 skipHeader 跳過(guò)自動(dòng)生成的表頭。
const ws = XLSX.utils.json_to_sheet(jsonData, {
header: ["department", "name", "age"],
skipHeader: false
});
參數(shù)說(shuō)明:
header:指定字段順序,若未指定則按對(duì)象第一個(gè)元素的鍵順序生成。skipHeader:是否跳過(guò)表頭,默認(rèn)為false,設(shè)為true時(shí)不生成表頭行。
效果對(duì)比:
| 參數(shù)設(shè)置 | 表頭順序 |
|---|---|
| 未指定header | name, age, department |
| 指定header為[“department”, “name”, “age”] | department, name, age |
4.2 二維數(shù)組與工作表的互操作
除了JSON數(shù)據(jù),XLSX庫(kù)也支持將二維數(shù)組轉(zhuǎn)換為工作表。這在處理表格數(shù)據(jù)或?qū)С鯤TML表格內(nèi)容時(shí)非常實(shí)用。
4.2.1 使用aoa_to_sheet處理二維數(shù)組
aoa_to_sheet 函數(shù)用于將二維數(shù)組轉(zhuǎn)換為工作表對(duì)象,適合處理已有的二維結(jié)構(gòu)數(shù)據(jù)。
const data = [
["姓名", "年齡", "部門"],
["張三", 28, "技術(shù)部"],
["李四", 32, "市場(chǎng)部"],
["王五", 25, "財(cái)務(wù)部"]
];
const ws = XLSX.utils.aoa_to_sheet(data);逐行解釋:
data:是一個(gè)二維數(shù)組,第一行為表頭,后續(xù)為數(shù)據(jù)行。XLSX.utils.aoa_to_sheet(data):將該數(shù)組轉(zhuǎn)換為工作表對(duì)象。
4.2.2 向現(xiàn)有工作表追加數(shù)據(jù)(sheet_add_aoa)
如果已有工作表,可以使用 sheet_add_aoa 方法追加數(shù)據(jù)。
const newData = [
["趙六", 29, "行政部"],
["錢七", 31, "研發(fā)部"]
];
XLSX.utils.sheet_add_aoa(ws, newData, { origin: -1 });參數(shù)說(shuō)明:
ws:已有的工作表對(duì)象。newData:要追加的二維數(shù)組。origin: -1:表示從最后一行之后開始追加。
mermaid流程圖:
graph TD
A[準(zhǔn)備二維數(shù)組] --> B[創(chuàng)建工作表]
B --> C[已有工作表]
C --> D[準(zhǔn)備新數(shù)據(jù)]
D --> E[調(diào)用 sheet_add_aoa]
E --> F[追加數(shù)據(jù)至工作表]
4.3 創(chuàng)建與寫入Excel文件
在完成工作表的構(gòu)建后,下一步是將其寫入一個(gè)完整的Excel文件,并支持下載或傳輸。
4.3.1 使用writeFile方法保存Excel文件
XLSX.writeFile 函數(shù)可以將工作簿保存為本地文件。
const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "員工信息"); XLSX.writeFile(wb, "員工數(shù)據(jù).xlsx");
逐行解釋:
XLSX.utils.book_new():創(chuàng)建一個(gè)新的工作簿。book_append_sheet:將工作表ws添加到工作簿中,并命名為“員工信息”。writeFile(wb, "員工數(shù)據(jù).xlsx"):將工作簿保存為名為員工數(shù)據(jù).xlsx的Excel文件。
4.3.2 使用write方法生成Base64或Blob數(shù)據(jù)
如果需要將Excel文件作為Base64字符串或Blob對(duì)象傳輸(如上傳至服務(wù)器或預(yù)覽),可以使用 XLSX.write 方法。
const excelBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
參數(shù)說(shuō)明:
bookType:指定輸出格式,如xlsx、xls、csv等。type:輸出類型,支持base64、binary、array等。
轉(zhuǎn)換方式對(duì)比:
| 輸出類型 | 特點(diǎn) | 適用場(chǎng)景 |
|---|---|---|
| base64 | 可用于嵌入網(wǎng)頁(yè)或傳輸 | 接口傳輸、預(yù)覽 |
| array | 可轉(zhuǎn)換為Blob對(duì)象 | 文件下載、上傳 |
| binary | 原始二進(jìn)制字符串 | 低層處理、兼容舊系統(tǒng) |
4.4 支持多種格式的轉(zhuǎn)換
XLSX庫(kù)不僅支持Excel格式,還支持CSV、JSON等常見格式的互操作。這對(duì)于構(gòu)建通用的數(shù)據(jù)導(dǎo)出功能非常有用。
4.4.1 CSV、JSON與Excel之間的相互轉(zhuǎn)換
JSON轉(zhuǎn)CSV
const csvData = XLSX.utils.sheet_to_csv(ws); console.log(csvData);
輸出示例:
姓名,年齡,部門
張三,28,技術(shù)部
李四,32,市場(chǎng)部
王五,25,財(cái)務(wù)部
CSV轉(zhuǎn)Excel
const ws = XLSX.utils.csv_to_sheet(csvData);
JSON轉(zhuǎn)Excel(前面已講)
4.4.2 處理大型數(shù)據(jù)集時(shí)的性能優(yōu)化
在處理大型數(shù)據(jù)集(如數(shù)萬(wàn)行)時(shí),XLSX庫(kù)的性能可能會(huì)成為瓶頸。以下是幾種優(yōu)化策略:
- 分頁(yè)處理 :將大數(shù)據(jù)拆分為多個(gè)工作表或多個(gè)文件。
- 減少樣式與公式 :避免寫入樣式和公式,僅導(dǎo)出純文本數(shù)據(jù)。
- 使用流式處理 :在Node.js環(huán)境中使用流(stream)處理大文件,避免內(nèi)存溢出。
- Web Worker處理 :在前端將數(shù)據(jù)處理邏輯放入Web Worker中,避免阻塞主線程。
優(yōu)化建議對(duì)比表:
| 優(yōu)化方式 | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|
| 分頁(yè)處理 | 降低單個(gè)文件大小 | 增加文件數(shù)量 |
| 禁用樣式 | 提高導(dǎo)出速度 | 丟失格式 |
| 流式處理 | 支持超大文件 | 需Node.js環(huán)境 |
| Web Worker | 不阻塞UI | 實(shí)現(xiàn)復(fù)雜度高 |
mermaid流程圖:
graph TD
A[開始處理大型數(shù)據(jù)] --> B{是否使用分頁(yè)?}
B -->|是| C[分批次導(dǎo)出]
B -->|否| D{是否禁用樣式?}
D -->|是| E[純數(shù)據(jù)導(dǎo)出]
D -->|否| F[保留樣式]
A --> G[使用流式處理(Node.js)]
G --> H[避免內(nèi)存溢出]通過(guò)本章內(nèi)容,我們已經(jīng)掌握了如何將JSON或二維數(shù)組轉(zhuǎn)換為Excel表格,并進(jìn)一步生成Excel文件。同時(shí),我們還了解了如何在不同格式之間進(jìn)行互操作,以及在處理大型數(shù)據(jù)集時(shí)的性能優(yōu)化策略。這些技能在實(shí)際開發(fā)中極具實(shí)用價(jià)值,無(wú)論是前端數(shù)據(jù)導(dǎo)出還是后端批量處理,都能顯著提升開發(fā)效率與用戶體驗(yàn)。
5. Excel數(shù)據(jù)處理實(shí)戰(zhàn)與擴(kuò)展功能
5.1 前端Excel數(shù)據(jù)展示實(shí)戰(zhàn)
在前幾章中,我們已經(jīng)掌握了如何使用XLSX庫(kù)讀取Excel文件、解析數(shù)據(jù)并轉(zhuǎn)換為JSON格式。本節(jié)將基于這些基礎(chǔ)操作,展示如何將解析后的數(shù)據(jù)在網(wǎng)頁(yè)中進(jìn)行動(dòng)態(tài)展示,實(shí)現(xiàn)前端數(shù)據(jù)可視化。
5.1.1 在網(wǎng)頁(yè)中展示解析后的Excel數(shù)據(jù)
我們可以通過(guò)HTML的 <input type="file"> 元素讓用戶上傳Excel文件,然后利用XLSX庫(kù)進(jìn)行解析,最后將結(jié)果渲染到頁(yè)面上。以下是一個(gè)完整的示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Excel 數(shù)據(jù)展示</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
</head>
<body>
<h2>上傳Excel文件以查看數(shù)據(jù)</h2>
<input type="file" id="excelFile" accept=".xlsx,.xls" />
<div id="tableContainer"></div>
<script>
document.getElementById('excelFile').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' });
// 獲取第一個(gè)工作表名稱
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
// 將工作表數(shù)據(jù)轉(zhuǎn)換為JSON格式
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
// 渲染為HTML表格
const tableHTML = '<table border="1">';
jsonData.forEach((row) => {
tableHTML += '<tr>';
row.forEach((cell) => {
tableHTML += `<td>${cell || ''}</td>`;
});
tableHTML += '</tr>';
});
tableHTML += '</table>';
document.getElementById('tableContainer').innerHTML = tableHTML;
};
reader.readAsArrayBuffer(file);
});
</script>
</body>
</html>5.1.2 使用表格組件動(dòng)態(tài)渲染數(shù)據(jù)
在實(shí)際開發(fā)中,為了增強(qiáng)用戶體驗(yàn)和交互性,推薦使用成熟的前端表格組件,如 DataTables 或 AG Grid 。下面展示如何將解析后的Excel數(shù)據(jù)綁定到 DataTables 表格中:
<!-- 引入 DataTables -->
<link rel="stylesheet" rel="external nofollow" >
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<!-- 表格容器 -->
<table id="dataTable" class="display" style="width:100%"></table>
<script>
// 假設(shè) jsonData 是之前解析的 Excel 數(shù)據(jù)
const table = $('#dataTable').DataTable({
data: jsonData,
columns: jsonData[0].map((_, i) => ({ title: `列${i+1}` })),
paging: true,
searching: true,
info: true
});
</script>說(shuō)明 :
jsonData是一個(gè)二維數(shù)組,其中每一項(xiàng)代表一行數(shù)據(jù)。通過(guò)映射第一行數(shù)據(jù)來(lái)動(dòng)態(tài)生成列標(biāo)題,并使用 DataTables 的 API 實(shí)現(xiàn)分頁(yè)、搜索等功能。
5.2 前后端數(shù)據(jù)交互與Excel處理流程
在實(shí)際項(xiàng)目中,Excel文件往往需要上傳至服務(wù)器進(jìn)行處理或存儲(chǔ)。本節(jié)將介紹如何從前端上傳文件,后端接收并解析Excel,最后返回處理后的數(shù)據(jù)。
5.2.1 前端上傳Excel文件并發(fā)送至后端
前端可以通過(guò) FormData 和 fetch 實(shí)現(xiàn)文件上傳。示例代碼如下:
document.getElementById('excelFile').addEventListener('change', function(e) {
const file = e.target.files[0];
const formData = new FormData();
formData.append('file', file);
fetch('/api/upload-excel', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log('后端返回?cái)?shù)據(jù):', data);
// 可以將 data 渲染到頁(yè)面上
})
.catch(error => {
console.error('上傳失敗:', error);
});
});5.2.2 后端處理數(shù)據(jù)并返回結(jié)果
以 Node.js + Express 為例,后端使用 multer 處理文件上傳,使用 xlsx 庫(kù)解析 Excel 數(shù)據(jù):
const express = require('express');
const multer = require('multer');
const XLSX = require('xlsx');
const app = express();
const upload = multer({ dest: 'uploads/' });
app.post('/api/upload-excel', upload.single('file'), (req, res) => {
const workbook = XLSX.readFile(req.file.path);
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet);
res.json(jsonData);
});
app.listen(3000, () => {
console.log('服務(wù)器運(yùn)行于 http://localhost:3000');
});流程說(shuō)明:
1. 用戶上傳Excel文件;
2. 前端通過(guò)fetch將文件發(fā)送到后端;
3. 后端接收文件并解析為JSON;
4. 后端將解析結(jié)果返回給前端;
5. 前端將結(jié)果渲染為表格或圖表。
5.3 高級(jí)功能探索:公式與樣式支持
默認(rèn)情況下,XLSX庫(kù)在解析Excel文件時(shí)不會(huì)保留公式和樣式信息。但在某些高級(jí)場(chǎng)景下,我們需要保留這些元數(shù)據(jù)。本節(jié)將介紹如何啟用這些功能。
5.3.1 解析并保留Excel中的公式
XLSX庫(kù)默認(rèn)只解析單元格的顯示值,不解析公式內(nèi)容。要獲取公式,可以在 sheet_to_json 方法中設(shè)置 raw: false 并訪問 s (start)和 e (end)屬性來(lái)獲取單元格范圍。
const workbook = XLSX.read(data, { type: 'array', cellFormula: true });
workbook.SheetNames.forEach(sheetName => {
const worksheet = workbook.Sheets[sheetName];
const range = XLSX.utils.decode_range(worksheet['!ref']);
for (let R = range.s.r; R <= range.e.r; ++R) {
for (let C = range.s.c; C <= range.e.c; ++C) {
const cellAddress = XLSX.utils.encode_cell({ r: R, c: C });
const cell = worksheet[cellAddress];
if (cell && cell.f) {
console.log(`單元格 ${cellAddress} 的公式為: ${cell.f}`);
}
}
}
});參數(shù)說(shuō)明:
-cellFormula: true:?jiǎn)⒂霉浇馕觯?br />-cell.f:表示單元格中的公式字符串。
5.3.2 讀取與寫入單元格樣式信息
樣式信息的讀取和寫入相對(duì)復(fù)雜,XLSX庫(kù)支持通過(guò) cellStyles: true 來(lái)啟用樣式解析:
const workbook = XLSX.read(data, { type: 'array', cellStyles: true });
workbook.SheetNames.forEach(sheetName => {
const worksheet = workbook.Sheets[sheetName];
const range = XLSX.utils.decode_range(worksheet['!ref']);
for (let R = range.s.r; R <= range.e.r; ++R) {
for (let C = range.s.c; C <= range.e.c; ++C) {
const cellAddress = XLSX.utils.encode_cell({ r: R, c: C });
const cell = worksheet[cellAddress];
if (cell && cell.s) {
console.log(`單元格 ${cellAddress} 的樣式為:`, cell.s);
}
}
}
});說(shuō)明:
-cell.s:指向workbook.SSF中的樣式索引;
- 樣式數(shù)據(jù)存儲(chǔ)在workbook.SSF和workbook.CS中。
5.4 擴(kuò)展應(yīng)用場(chǎng)景與未來(lái)展望
5.4.1 在數(shù)據(jù)分析與可視化中的應(yīng)用
結(jié)合前端圖表庫(kù)如 ECharts 或 Chart.js,可以將Excel數(shù)據(jù)解析后用于動(dòng)態(tài)圖表展示。例如,我們可以將Excel中的銷售數(shù)據(jù)解析為JSON,并使用 ECharts 生成柱狀圖:
<div id="chart" style="width:600px;height:400px;"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
<script>
const chart = echarts.init(document.getElementById('chart'));
const option = {
title: { text: '銷售數(shù)據(jù)' },
tooltip: {},
xAxis: { data: jsonData.map(row => row[0]) }, // 假設(shè)第一列為名稱
yAxis: { type: 'value' },
series: [{
name: '銷售額',
type: 'bar',
data: jsonData.slice(1).map(row => row[1]) // 假設(shè)第二列為數(shù)值
}]
};
chart.setOption(option);
</script>5.4.2 與后端服務(wù)集成實(shí)現(xiàn)自動(dòng)化報(bào)表生成
將前端Excel上傳、后端數(shù)據(jù)處理、模板引擎(如 Handlebars)結(jié)合,可實(shí)現(xiàn)自動(dòng)化報(bào)表生成功能。例如:
- 用戶上傳Excel模板;
- 后端解析數(shù)據(jù)并填充模板;
- 生成新的Excel文件并返回給用戶下載。
這種模式廣泛應(yīng)用于企業(yè)級(jí)數(shù)據(jù)報(bào)表系統(tǒng)、財(cái)務(wù)系統(tǒng)、自動(dòng)化辦公流程中。
到此這篇關(guān)于JavaScript讀取Excel文件實(shí)戰(zhàn)指南的文章就介紹到這了,更多相關(guān)Javascript讀取excel文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 微信小程序中如何使用xlsx(xlsx.mini.min.js)實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出功能
- 使用Python將JSON格式的假期數(shù)據(jù)轉(zhuǎn)換為Excel文件
- JavaScript前端讀取Excel文件的實(shí)戰(zhàn)指南
- 基于Python實(shí)現(xiàn)excel表格數(shù)據(jù)一鍵轉(zhuǎn)json格式小工具
- JavaScript實(shí)現(xiàn)Excel導(dǎo)出功能的完整代碼示例
- Python進(jìn)行JSON和Excel文件轉(zhuǎn)換處理指南
- Python打造Excel與JSON轉(zhuǎn)換工具全攻略(從開發(fā)到打包)
- 深入淺出使用JS/TS輕松搞定Excel與XML互轉(zhuǎn)
- 使用ExcelJS實(shí)現(xiàn)Excel數(shù)據(jù)報(bào)表導(dǎo)出的完整指南
相關(guān)文章
使用Performance Observer實(shí)現(xiàn)網(wǎng)頁(yè)性能優(yōu)化的示例詳解
在當(dāng)今的網(wǎng)頁(yè)開發(fā)中,性能監(jiān)控已經(jīng)成為確保用戶體驗(yàn)的一個(gè)關(guān)鍵部分,本文將深入探討一個(gè)強(qiáng)大的性能監(jiān)控工具PerformanceObserver,看看如何使用它提升網(wǎng)站性能吧2025-03-03
用javascript實(shí)現(xiàn)頁(yè)內(nèi)搜索的腳本代碼
用javascript實(shí)現(xiàn)頁(yè)內(nèi)搜索的腳本代碼...2007-08-08
javascript四舍五入函數(shù)代碼分享(保留后幾位)
這篇文章主要介紹了javascript四舍五入函數(shù)分享,大家參考使用吧2013-12-12
JS+DIV實(shí)現(xiàn)鼠標(biāo)劃過(guò)切換層效果的實(shí)例代碼
這篇文章主要是對(duì)JS+DIV實(shí)現(xiàn)鼠標(biāo)劃過(guò)切換層效果的實(shí)例代碼進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
javascript Table 中2個(gè)列(TD)的交換實(shí)現(xiàn)代碼
非常不錯(cuò)的用js控制talbe中td的位置的實(shí)現(xiàn)代碼。2009-02-02
小議Function.apply()之二------利用Apply的參數(shù)數(shù)組化來(lái)提高 JavaScript程序性能
小議Function.apply()之二------利用Apply的參數(shù)數(shù)組化來(lái)提高 JavaScript程序性能...2006-11-11
基于JavaScript實(shí)現(xiàn)新年賀卡特效
本文介紹了一款超級(jí)炫酷的2022新年快樂html網(wǎng)頁(yè)特效,霓虹的城市夜景和絢爛的煙花很是特別,該html頁(yè)面還有交互效果,點(diǎn)擊鼠標(biāo)就會(huì)呈現(xiàn)煙花綻放的特效。需要的可以參考一下2022-01-01

