1. 程式人生 > >在瀏覽器和node中使用 GitHub的js-xlsx庫進行Excel檔案處理(一)

在瀏覽器和node中使用 GitHub的js-xlsx庫進行Excel檔案處理(一)

關鍵詞:JavaScript, js excel,node excel

1.簡介

js-xlsx 庫是目前 Github 上 star 數量最多的處理 Excel 的庫,功能強大,提供了各種對錶格的操作,但是這個專案文件有些亂,提供的demo也只具備最基本的功能。本文對 js-xlsx 庫進行一定的總結,一是為了自我知識的存檔,二是想和大家多多交流。

支援解析的格式有:
Excel 2007+ XML Formats (XLSX/XLSM)
Excel 2007+ Binary Format (XLSB)
Excel 2003-2004 XML Format (XML “SpreadsheetML”)
Excel 97-2004 (XLS BIFF8)
Excel 5.0/95 (XLS BIFF5)
OpenDocument Spreadsheet (ODS)

支援輸出格式有:
XLSX
CSV (and general DSV)
JSON and JS objects (various styles)

2.安裝

1.在node環境中,載入xlsx的模組只包含基本的特性,如果需要用到一些不常見額外特性,得自己安裝。

2.在瀏覽器中,可以新增js引用來使用這些額外的特性。比如:

<script src="dist/cpexcel.js"></script>
<script src="dist/ods.js"></script>

這些額外特性檔案都包含在原始碼的dist/ directory資料夾裡面。在這個資料夾裡面,還有xlsx的各種版本核心程式碼,完整版,精簡版,壓縮版等。

3.xlsx.js使用了ES5的功能,比如Array和forEach等,為了相容低版本的瀏覽器,使用了shim技術。在載入xlsx.js檔案之前載入shim.js(在dist/ directory資料夾裡面),還有xlsx只能解析xls,也就是97-03的excel表格,如果要解析xlsx,也就是03之後的excel表格,需要引入jszip.js檔案,而且需要在xlsx之前載入。如下:

<script src="jszip.js"></script>
<script src="shim.js"></script>
<script src="xlsx.js"
>
</script>

名詞解釋:
workbook物件:指的是整份 Excel 文件。我們在使用 js-xlsx 讀取 Excel 文件之後就會獲得 workbook 物件。
worksheet 物件:指的是 Excel 文件中的表。我們知道一份 Excel 文件中可以包含很多張表,而每張表對應的就是 worksheet 物件。
cell 物件:指的就是 worksheet 中的單元格,一個單元格就是一個 cell 物件。

3.解析表格

接下來會一步步分析怎麼解析操作表格。node環境、瀏覽器環境分開講。分析之前,說一下我用於測試的表格。新建一個excel檔案,名字叫excel-test。裡面有三個表Sheet1、Sheet2、Sheet3,其中Sheet3為空。內容如圖:
這裡寫圖片描述

這裡寫圖片描述

1)node環境中

1.安裝xlsx模組,命令列視窗中輸入:npm install xlsx

2.用 XLSX.readFile 開啟 Excel 檔案,返回 workbook
程式碼:

if(typeof require !== 'undefined') XLSX = require('xlsx');
var workbook = XLSX.readFile('test.xlsx');

首先載入xlsx模組,然後使用readFile開啟excel檔案,特別需要注意路徑問題,如果沒有指明路徑,readFile預設開啟excel檔案的根路徑是你安裝node模組的位置(電腦裡面node_modules檔案的位置),而不是你專案原始碼檔案的路徑。我的excel檔案不在預設的根路徑下,使用相對路徑(注意斜槓方向啊):

var workbook = XLSX.readFile('./Desktop/ExcelParseClient/excel-test.xlsx');

3.用 workbook.SheetNames 獲取表名,程式碼:

var sheetNames = workbook.SheetNames; 

console.log(sheetNames)列印如圖所示:

這裡寫圖片描述

4.用 workbook.Sheets[xxx] 通過表名獲取表格,程式碼:

var worksheet = workbook.Sheets[sheetNames[i]];

我們來看看worksheet到底是什麼?

var worksheet = workbook.Sheets[Sheet1];
console.log(“列印sheet1:\n”,worksheet);如圖:

這裡寫圖片描述

可以看出,worksheet是一個物件,裡面包含名稱/值對,值對的值仍然是物件。要獲取A1單元格的值,這樣:

var desired_cell = worksheet[A1];
var desired_value = desired_cell.v;

5.按自己的需求去處理表格
綜合前面1234步的程式碼,程式碼為:

if(typeof require !== 'undefined')XLSX=require('xlsx');
var workbook = XLSX.readFile('./Desktop/ExcelParseClient/excel-test.xlsx');
var sheet_name_list = workbook.SheetNames;
/*處理表格*/
sheet_name_list.forEach(function(sheetname) { /* iterate through sheets */
  var worksheet = workbook.Sheets[sheetname];
  for (z in worksheet) {
    /* 帶!的屬性(比如!ref)是表格的特殊屬性,用來輸出表格的資訊,不是表格的內容,所以去掉 */
    if(z[0] === '!') continue;
    console.log(sheetname + ": " + z + "=" + JSON.stringify(worksheet[z].v));
  }
});

輸出結果為:

這裡寫圖片描述

2)瀏覽器環境中

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JS-XLSX Demo</title>
</head>
<body>
<p><input type="file" name="xlfile" accept="application/vnd.ms-excel,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" id="xlf" />開啟Excel檔案</p>
<pre id="out"></pre>
<br />
<script src="shim.js"></script>
<script src="jszip.js"></script>
<script src="xlsx.js"></script>
<script>
/*this version is the source code that delete all the other code*/
var X = XLSX;
var e=e||window.event;
var wtf_mode = false;
function fixdata(data) {
    var o = "", l = 0, w = 10240;
    for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
    o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
    return o;
}

/*transfer the workbook to the json*/
function to_json(workbook) {
    var result = {};
    workbook.SheetNames.forEach(function(sheetName) {
        var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
        if(roa.length > 0){
            result[sheetName] = roa;
        }
    });
    console.log(result);
    return result;
}

var xlf = document.getElementById('xlf');
// the "e" means the event(change)
// the event.target means the node of the Event,in this programming ,e.target.id equals xlf
function handleFile(e) {
    var files = e.target.files;
    var f = files[0];
    {   var reader = new FileReader();
        var name = f.name;
        reader.readAsArrayBuffer(f);
        //onload means that the function(e) would be executed when the reader has finished the loading
        reader.onload = function(e) {
            //return ArrayBuffer{}
            var data = e.target.result;
            var arr = fixdata(data);
            var wb = X.read(btoa(arr), {type: 'base64'});
        };
    }
}
if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
</script>
</body>
</html>

上面node環境中,使用js-xlsx庫的基本操作一步步解析,實際上該庫提供了封裝好的函式一次性解析excel表格成json資料。使用:var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);

關於js-xlsx庫的使用就先分析到這裡,下一篇分析怎麼用json資料生成excel檔案,以及對錶格內容進行判斷,比如空格、重複等等。