国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

Node.js利用js-xlsx處理Excel文件的方法詳解

2024-05-06 16:38:16
字體:
供稿:網(wǎng)友

簡介

本文介紹用 Node.js 中的 js-xlsx 庫來處理 Excel 文件。

js-xlsx 庫是目前 Github 上 star 數(shù)量最多的處理 Excel 的庫,功能強(qiáng)大,但上手難度稍大。文檔有些亂,不適合快速上手。

本文對 js-xlsx 庫進(jìn)行一定的總結(jié),并提供幾個實用的例子供讀者測試,學(xué)習(xí),交流。

安裝

$ npm install xlsx

一些概念

在使用這個庫之前,先介紹庫中的一些概念。

  • workbook 對象,指的是整份 Excel 文檔。我們在使用 js-xlsx 讀取 Excel 文檔之后就會獲得 workbook 對象。
  • worksheet 對象,指的是 Excel 文檔中的表。我們知道一份 Excel 文檔中可以包含很多張表,而每張表對應(yīng)的就是 worksheet 對象。
  • cell 對象,指的就是 worksheet 中的單元格,一個單元格就是一個 cell 對象。

它們的關(guān)系如下:

// workbook{ SheetNames: ['sheet1', 'sheet2'], Sheets: { // worksheet 'sheet1': {  // cell  'A1': { ... },  // cell  'A2': { ... },  ... }, // worksheet 'sheet2': {  // cell  'A1': { ... },  // cell  'A2': { ... },  ... } }}

用法

基本用法

  • XLSX.readFile 打開 Excel 文件,返回 workbook
  • workbook.SheetNames 獲取表名
  • workbook.Sheets[xxx] 通過表名獲取表格
  • 按自己的需求去處理表格
  • 生成新的 Excel 文件

具體用法

讀取 Excel 文件

import XLSX from 'xlsx';const workbook = XLSX.readFile('someExcel.xlsx', opts);

獲取 Excel 文件中的表

// 獲取 Excel 中所有表名const sheetNames = workbook.SheetNames; // 返回 ['sheet1', 'sheet2']// 根據(jù)表名獲取對應(yīng)某張表const worksheet = workbook.Sheets[sheetNames[0]];

通過 worksheet[address] 來操作表格,以 ! 開頭的 key 是特殊的字段。

// 獲取 A1 單元格對象let a1 = worksheet['A1']; // 返回 { v: 'hello', t: 's', ... }// 獲取 A1 中的值a1.v // 返回 'hello'// 獲取表的有效范圍worksheet['!ref'] // 返回 'A1:B20'worksheet['!range'] // 返回 range 對象,{ s: { r: 0, c: 0}, e: { r: 100, c: 2 } }// 獲取合并過的單元格worksheet['!merges'] // 返回一個包含 range 對象的列表,[ {s: { r: 0, c: 0 }, c: { r: 2, c: 1 } } ]

實戰(zhàn)

解析 Excel 生成 JSON

Tips 事實上,你可以直接通過 XLSX.utils.sheet_to_json(worksheet) 獲得同樣的結(jié)果

注意 本例子中假設(shè)表的第一行為字段名

const headers = {};const data = [];const keys = Object.keys(worksheet);keys // 過濾以 ! 開頭的 key .filter(k => k[0] !== '!') // 遍歷所有單元格 .forEach(k => {  // 如 A11 中的 A  let col = k.substring(0, 1);  // 如 A11 中的 11  let row = parseInt(k.substring(1));  // 當(dāng)前單元格的值  let value = worksheet[k].v;  // 保存字段名  if (row === 1) {   headers[col] = value;   return;  }  // 解析成 JSON  if (!data[row]) {   data[row] = {};  }  data[row][headers[col]] = value; });console.log(data); // [ { '姓名': 'test1', '年齡': 20 }, { '姓名': 'test2', '年齡': 10 } ... ]

合并表格

步驟:

  • 讀取多份表格
  • 合并數(shù)組

Tips: 其實合并表格跟 XLSX 沒什么關(guān)系,只是處理幾個數(shù)組而已。

sheet1

 

id name age
1 test1 30
2 test2 20
3 test3 18

 

sheet2

 

id country remark
1 China hello
2 America world
3 Unkonw ???

 

let sheet1 = XLSX.utils.sheet_to_json(sheet1);let sheet2 = XLSX.utils.sheet_to_json(sheet2);// 先合并 sheet1 和 sheet2,再對統(tǒng)一處理const result = sheet1.concat(sheet2).reduce((prev, next) => { let index = prev.findIndex((elem, i) => elem.id === next.id); if (index === -1) {  return prev.concat(next); } else {  prev[index] = Object.assign({}, prev[index], next);  return prev; }}, []);console.log(result);// [ { id: '1',// name: 'test1',// age: '30',// country: 'China',// remark: 'hello' },// { id: '2',// name: 'test2',// age: '20',// country: 'America',// remark: 'world' },// { id: '3',// name: 'test3',// age: '18',// country: 'Unkonw',// remark: '???' } ]

導(dǎo)出表格

步驟:

  • 構(gòu)建特定的數(shù)據(jù)結(jié)構(gòu),如下。
  • 調(diào)用 XLSX.writeFile(workbook, filename) 即可。
// workbook{ SheetNames: ['mySheet'], Sheets: {  'mySheet': {   '!ref': 'A1:E4', // 必須要有這個范圍才能輸出,否則導(dǎo)出的 excel 會是一個空表   A1: { v: 'id' },   ...  } }}
var _headers = ['id', 'name', 'age', 'country', 'remark']var _data = [ { id: '1',    name: 'test1',    age: '30',    country: 'China',    remark: 'hello' },    { id: '2',    name: 'test2',    age: '20',    country: 'America',    remark: 'world' },    { id: '3',    name: 'test3',    age: '18',    country: 'Unkonw',    remark: '???' } ];var headers = _headers    // 為 _headers 添加對應(yīng)的單元格位置    // [ { v: 'id', position: 'A1' },    // { v: 'name', position: 'B1' },    // { v: 'age', position: 'C1' },    // { v: 'country', position: 'D1' },    // { v: 'remark', position: 'E1' } ]    .map((v, i) => Object.assign({}, {v: v, position: String.fromCharCode(65+i) + 1 }))    // 轉(zhuǎn)換成 worksheet 需要的結(jié)構(gòu)    // { A1: { v: 'id' },    // B1: { v: 'name' },    // C1: { v: 'age' },    // D1: { v: 'country' },    // E1: { v: 'remark' } }    .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {});var data = _data    // 匹配 headers 的位置,生成對應(yīng)的單元格數(shù)據(jù)    // [ [ { v: '1', position: 'A2' },    //  { v: 'test1', position: 'B2' },    //  { v: '30', position: 'C2' },    //  { v: 'China', position: 'D2' },    //  { v: 'hello', position: 'E2' } ],    // [ { v: '2', position: 'A3' },    //  { v: 'test2', position: 'B3' },    //  { v: '20', position: 'C3' },    //  { v: 'America', position: 'D3' },    //  { v: 'world', position: 'E3' } ],    // [ { v: '3', position: 'A4' },    //  { v: 'test3', position: 'B4' },    //  { v: '18', position: 'C4' },    //  { v: 'Unkonw', position: 'D4' },    //  { v: '???', position: 'E4' } ] ]    .map((v, i) => _headers.map((k, j) => Object.assign({}, { v: v[k], position: String.fromCharCode(65+j) + (i+2) })))    // 對剛才的結(jié)果進(jìn)行降維處理(二維數(shù)組變成一維數(shù)組)    // [ { v: '1', position: 'A2' },    // { v: 'test1', position: 'B2' },    // { v: '30', position: 'C2' },    // { v: 'China', position: 'D2' },    // { v: 'hello', position: 'E2' },    // { v: '2', position: 'A3' },    // { v: 'test2', position: 'B3' },    // { v: '20', position: 'C3' },    // { v: 'America', position: 'D3' },    // { v: 'world', position: 'E3' },    // { v: '3', position: 'A4' },    // { v: 'test3', position: 'B4' },    // { v: '18', position: 'C4' },    // { v: 'Unkonw', position: 'D4' },    // { v: '???', position: 'E4' } ]    .reduce((prev, next) => prev.concat(next))    // 轉(zhuǎn)換成 worksheet 需要的結(jié)構(gòu)    // { A2: { v: '1' },    //  B2: { v: 'test1' },    //  C2: { v: '30' },    //  D2: { v: 'China' },    //  E2: { v: 'hello' },    //  A3: { v: '2' },    //  B3: { v: 'test2' },    //  C3: { v: '20' },    //  D3: { v: 'America' },    //  E3: { v: 'world' },    //  A4: { v: '3' },    //  B4: { v: 'test3' },    //  C4: { v: '18' },    //  D4: { v: 'Unkonw' },    //  E4: { v: '???' } }    .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {});// 合并 headers 和 datavar output = Object.assign({}, headers, data);// 獲取所有單元格的位置var outputPos = Object.keys(output);// 計算出范圍var ref = outputPos[0] + ':' + outputPos[outputPos.length - 1];// 構(gòu)建 workbook 對象var wb = { SheetNames: ['mySheet'], Sheets: {  'mySheet': Object.assign({}, output, { '!ref': ref }) }};// 導(dǎo)出 ExcelXLSX.writeFile(wb, 'output.xlsx');

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網(wǎng)的支持。

出處

http://scarletsky.github.io/2016/01/30/nodejs-process-excel/

參考資料

https://github.com/SheetJS/js-xlsx

http://stackoverflow.com/questions/30859901/parse-xlsx-with-node-and-create-json


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 高青县| 四川省| 盐边县| 彭阳县| 泾川县| 漳州市| 璧山县| 江陵县| 萨迦县| 宣城市| 桐庐县| 婺源县| 霸州市| 淮北市| 东莞市| 自治县| 英超| 铜梁县| 凤城市| 县级市| 宣化县| 黑水县| 依兰县| 旺苍县| 淳化县| 东丽区| 江都市| 永丰县| 青神县| 金沙县| 崇阳县| 大荔县| 无棣县| 泰宁县| 辉南县| 和田市| 永宁县| 油尖旺区| 上饶市| 上饶市| 平江县|