伊莉討論區
標題: 網頁前端Javascript套件:SheetJS/js-xlsx.js [打印本頁]
作者: Semisphere 時間: 2017-2-5 12:23 PM 標題: 網頁前端Javascript套件:SheetJS/js-xlsx.js
本帖最後由 Semisphere 於 2017-2-5 12:44 PM 編輯
SheetJS/js-xlsxhttps://github.com/SheetJS/js-xlsx
若我們要由網頁前端使用Javascript直接存取Office Excel 2007檔案(*.xlsx)內資料,其實還蠻辛苦的,主因需實做解析與儲存xlsx之標準格式,這挺複雜。這邊推薦一Javascript函式庫:SheetJS/js-xlsx,來進行讀檔與產製xlsx檔案工作。雖說推薦,但實際上去看SheetJS/js-xlsx的GitHub官網,操作說明其實不太完整,寫的內容不夠詳盡,算是勉強推薦,也因此我們還需參考官網所提供的操作範例:
http://oss.sheetjs.com/js-xlsx/
再由瀏覽器F12開發者功能找出原始碼來比對確認,透過人工方式自己補齊缺乏的功能。另查谷歌時,也會看到其他使用者所提供的原始碼,因不同SheetJS/js-xlsx版本稍有不同,故自己谷歌時得再三小心。
SheetJS/js-xlsx線上CDN
https://cdnjs.com/libraries/xlsx
現在因SheetJS/js-xlsx要支援新舊版Excel、OpenDocument Spreadsheet (ODS)等格式,分了好幾個模組,若想一次解決可選完整的單檔版xlsx.full.min.js。目前的版本號為0.8.2。測試功能正常後,我這邊也再小封裝一次方便自己與大家使用,讀存分別為:
- function readxlsx(inpdata, fmt)
- //讀取xlsx檔
- //inpdata:由input file讀入之data
- //fmt:讀取格式,可有"json"或"csv",csv格式之分欄符號為逗號,分行符號為[\n]
複製代碼
- function downloadxlsx(filename, sheetname, data)
- //儲存xlsx檔
- //filename:要下載儲存之xlsx檔名
- //sheetname:資料表名
- //data:要下載之資料,需為二維陣列
複製代碼
以下為使用SheetJS/js-xlsx 0.8.2重封裝的兩函式使用範例,上傳檔案可使用excel開啟xlsx檔,其內給予資料:
或使用附件:
[attach]117605506[/attach]
上傳完xlsx檔會於網頁內顯示資料:
點擊下載測試檔案時,會將內建測試資料儲存至xlsx並彈出下載視窗,下載後xlsx內資料為:
範例程式碼如下:
- <!DOCTYPE html>
- <html>
- <head>
- <title>js-xlsx Demo</title>
- <meta charset="utf-8">
- <!--使用jQuery操作dom-->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
- <!--使用JS-XLSX操作xlsx-->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.2/xlsx.full.min.js"></script>
- <!--使用FileSaver下載資料成為檔案-->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
- <script>
- $(document).ready(function () {
-
- //綁定change事件,讀xlsx檔
- $('#upload_input').on('change', function (e) {
- //取得上傳第一個檔案
- var files = e.target.files;
- var f = files[0];
- //使用FileReader讀檔
- var reader = new FileReader();
- //檔案名稱
- var name = f.name;
- //onload觸發事件
- reader.onload = function (e) {
- //對象內資料
- var data = e.target.result;
- //讀取xlsx資料
- var retjson = readxlsx(data, 'json');
- var retcsv = readxlsx(data, 'csv');
- //顯示內容
- $('#upload_showjson').html(JSON.stringify(retjson, null, '\t'));
- $('#upload_showcsv').html(retcsv);
- };
- //以BinaryString讀入
- reader.readAsBinaryString(f);
- });
- //綁定click事件,下載xlsx檔
- $('#download_button').on('click', function () {
- //檔名
- var filename = 'download.xlsx';
- //表名
- var sheetname = 'test';
- //測試資料
- var data = [
- ['name', 'number', 'date'],
- ['abc', 1, new Date().toLocaleString()],
- ['def', 123.456, new Date('2015-03-25T13:30:12Z')],
- ];
- //下載
- downloadxlsx(filename, sheetname, data);
- })
-
- });
- function readxlsx(inpdata, fmt) {
- //讀取xlsx檔
- //參數
- //inpdata為由input file讀入之data
- //fmt為讀取格式,可有"json"或"csv",csv格式之分欄符號為逗號,分行符號為[\n]
- //說明
- //所使用函式可參考js-xlsx的GitHub文件[[url]https://github.com/SheetJS/js-xlsx[/url]]
- //to_json
- function to_json(workbook) {
- var result = {};
- workbook.SheetNames.forEach(function (sheetName) {
- var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
- if (roa.length > 0) {
- result[sheetName] = roa;
- }
- });
- return result;
- }
- //to_csv
- function to_csv(workbook) {
- var result = [];
- workbook.SheetNames.forEach(function(sheetName) {
- var csv = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);
- if(csv.length > 0){
- result.push('SHEET: ' + sheetName);
- result.push('\n');
- result.push(csv);
- }
- });
- return result;
- }
- //讀檔
- var workbook = XLSX.read(inpdata, { type: 'binary' });
- //轉為json物件回傳
- if (fmt === 'json') {
- return to_json(workbook);
- }
- else {
- return to_csv(workbook);
- }
- }
- function downloadxlsx(filename, sheetname, data) {
- //儲存xlsx檔
- //參數
- //filename為要下載儲存之xlsx檔名,,sheetname為資料表名,data為要下載之資料,需為二維陣列。以下為使用範例:
- //var filename = 'download.xlsx';
- //var sheetname = 'test';
- //var data = [
- // ['name', 'number', 'date'],
- // ['abc', 1, new Date().toLocaleString()],
- // ['def', 123.456, new Date('2015-03-25T13:30:12Z')],
- //];
- //downloadxlsx(filename, sheetname, data);
- //說明
- //所使用函式可參考js-xlsx的GitHub文件[[url]https://github.com/SheetJS/js-xlsx[/url]]
- //datenum
- function datenum(v, date1904) {
- if (date1904) v += 1462;
- var epoch = Date.parse(v);
- return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
- }
- //sheet_from_array_of_arrays
- function sheet_from_array_of_arrays(data, opts) {
- var ws = {};
- var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
- for (var R = 0; R != data.length; ++R) {
- for (var C = 0; C != data[R].length; ++C) {
- if (range.s.r > R) range.s.r = R;
- if (range.s.c > C) range.s.c = C;
- if (range.e.r < R) range.e.r = R;
- if (range.e.c < C) range.e.c = C;
- var cell = { v: data[R][C] };
- if (cell.v == null) continue;
- var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
- if (typeof cell.v === 'number') cell.t = 'n';
- else if (typeof cell.v === 'boolean') cell.t = 'b';
- else if (cell.v instanceof Date) {
- cell.t = 'n'; cell.z = XLSX.SSF._table[14];
- cell.v = datenum(cell.v);
- }
- else cell.t = 's';
- ws[cell_ref] = cell;
- }
- }
- if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
- return ws;
- }
- //s2ab
- function s2ab(s) {
- var buf = new ArrayBuffer(s.length);
- var view = new Uint8Array(buf);
- for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
- return buf;
- }
- //Workbook
- function Workbook() {
- if (!(this instanceof Workbook)) return new Workbook();
- this.SheetNames = [];
- this.Sheets = {};
- }
- //write
- var wb = new Workbook();
- var ws = sheet_from_array_of_arrays(data);
- wb.SheetNames.push(sheetname);
- wb.Sheets[sheetname] = ws;
- var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
- //saveAs
- saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), filename)
- }
- </script>
- </head>
- <body>
- <input type="file" id="upload_input" />
- <h4>show json</h4>
- <pre id="upload_showjson"></pre>
- <h4>show csv</h4>
- <pre id="upload_showcsv"></pre>
- <button id="download_button">下載測試檔案</button>
- </body>
- </html>
複製代碼
歡迎光臨 伊莉討論區 (http://a401.file-static.com/) |
Powered by Discuz! |