伊莉討論區

標題: 網頁前端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-xlsx

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


若我們要由網頁前端使用Javascript直接存取Office Excel 2007檔案(*.xlsx)內資料,其實還蠻辛苦的,主因需實做解析與儲存xlsx之標準格式,這挺複雜。這邊推薦一Javascript函式庫:SheetJS/js-xlsx,來進行讀檔與產製xlsx檔案工作。雖說推薦,但實際上去看SheetJS/js-xlsxGitHub官網,操作說明其實不太完整,寫的內容不夠詳盡,算是勉強推薦,也因此我們還需參考官網所提供的操作範例:


http://oss.sheetjs.com/js-xlsx/


再由瀏覽器F12開發者功能找出原始碼來比對確認,透過人工方式自己補齊缺乏的功能。另查谷歌時,也會看到其他使用者所提供的原始碼,因不同SheetJS/js-xlsx版本稍有不同,故自己谷歌時得再三小心。


SheetJS/js-xlsx線上CDN

https://cdnjs.com/libraries/xlsx


現在因SheetJS/js-xlsx要支援新舊版ExcelOpenDocument Spreadsheet (ODS)等格式,分了好幾個模組,若想一次解決可選完整的單檔版xlsx.full.min.js。目前的版本號為0.8.2。測試功能正常後,我這邊也再小封裝一次方便自己與大家使用,讀存分別為:

  1. function readxlsx(inpdata, fmt)
  2. //讀取xlsx檔
  3. //inpdata:由input file讀入之data
  4. //fmt:讀取格式,可有"json"或"csv",csv格式之分欄符號為逗號,分行符號為[\n]
複製代碼

  1. function downloadxlsx(filename, sheetname, data)
  2. //儲存xlsx檔
  3. //filename:要下載儲存之xlsx檔名
  4. //sheetname:資料表名
  5. //data:要下載之資料,需為二維陣列
複製代碼

以下為使用SheetJS/js-xlsx 0.8.2重封裝的兩函式使用範例,上傳檔案可使用excel開啟xlsx檔,其內給予資料:



或使用附件:
[attach]117605506[/attach]

上傳完xlsx檔會於網頁內顯示資料:


點擊下載測試檔案時,會將內建測試資料儲存至xlsx並彈出下載視窗,下載後xlsx內資料為:


範例程式碼如下:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title>js-xlsx Demo</title>
  5.     <meta charset="utf-8">


  6.     <!--使用jQuery操作dom-->
  7.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

  8.     <!--使用JS-XLSX操作xlsx-->
  9.     <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.2/xlsx.full.min.js"></script>

  10.     <!--使用FileSaver下載資料成為檔案-->
  11.     <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>


  12.     <script>


  13.         $(document).ready(function () {
  14.       

  15.             //綁定change事件,讀xlsx檔
  16.             $('#upload_input').on('change', function (e) {

  17.                 //取得上傳第一個檔案
  18.                 var files = e.target.files;
  19.                 var f = files[0];

  20.                 //使用FileReader讀檔
  21.                 var reader = new FileReader();

  22.                 //檔案名稱
  23.                 var name = f.name;

  24.                 //onload觸發事件
  25.                 reader.onload = function (e) {

  26.                     //對象內資料
  27.                     var data = e.target.result;

  28.                     //讀取xlsx資料
  29.                     var retjson = readxlsx(data, 'json');
  30.                     var retcsv = readxlsx(data, 'csv');

  31.                     //顯示內容
  32.                     $('#upload_showjson').html(JSON.stringify(retjson, null, '\t'));
  33.                     $('#upload_showcsv').html(retcsv);

  34.                 };

  35.                 //以BinaryString讀入
  36.                 reader.readAsBinaryString(f);

  37.             });


  38.             //綁定click事件,下載xlsx檔
  39.             $('#download_button').on('click', function () {

  40.                 //檔名
  41.                 var filename = 'download.xlsx';

  42.                 //表名
  43.                 var sheetname = 'test';

  44.                 //測試資料
  45.                 var data = [
  46.                     ['name', 'number', 'date'],
  47.                     ['abc', 1, new Date().toLocaleString()],
  48.                     ['def', 123.456, new Date('2015-03-25T13:30:12Z')],
  49.                 ];

  50.                 //下載
  51.                 downloadxlsx(filename, sheetname, data);


  52.             })
  53.         

  54.         });


  55.         function readxlsx(inpdata, fmt) {
  56.             //讀取xlsx檔

  57.             //參數
  58.             //inpdata為由input file讀入之data
  59.             //fmt為讀取格式,可有"json"或"csv",csv格式之分欄符號為逗號,分行符號為[\n]

  60.             //說明
  61.             //所使用函式可參考js-xlsx的GitHub文件[[url]https://github.com/SheetJS/js-xlsx[/url]]


  62.             //to_json
  63.             function to_json(workbook) {
  64.                 var result = {};
  65.                 workbook.SheetNames.forEach(function (sheetName) {
  66.                     var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
  67.                     if (roa.length > 0) {
  68.                         result[sheetName] = roa;
  69.                     }
  70.                 });
  71.                 return result;
  72.             }


  73.             //to_csv
  74.             function to_csv(workbook) {
  75.                 var result = [];
  76.                 workbook.SheetNames.forEach(function(sheetName) {
  77.                     var csv = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);
  78.                     if(csv.length > 0){
  79.                         result.push('SHEET: ' + sheetName);
  80.                         result.push('\n');
  81.                         result.push(csv);
  82.                     }
  83.                 });
  84.                 return result;
  85.             }


  86.             //讀檔
  87.             var workbook = XLSX.read(inpdata, { type: 'binary' });


  88.             //轉為json物件回傳
  89.             if (fmt === 'json') {
  90.                 return to_json(workbook);
  91.             }
  92.             else {
  93.                 return to_csv(workbook);
  94.             }


  95.         }


  96.         function downloadxlsx(filename, sheetname, data) {
  97.             //儲存xlsx檔

  98.             //參數
  99.             //filename為要下載儲存之xlsx檔名,,sheetname為資料表名,data為要下載之資料,需為二維陣列。以下為使用範例:
  100.             //var filename = 'download.xlsx';
  101.             //var sheetname = 'test';
  102.             //var data = [
  103.             //    ['name', 'number', 'date'],
  104.             //    ['abc', 1, new Date().toLocaleString()],
  105.             //    ['def', 123.456, new Date('2015-03-25T13:30:12Z')],
  106.             //];
  107.             //downloadxlsx(filename, sheetname, data);

  108.             //說明
  109.             //所使用函式可參考js-xlsx的GitHub文件[[url]https://github.com/SheetJS/js-xlsx[/url]]


  110.             //datenum
  111.             function datenum(v, date1904) {
  112.                 if (date1904) v += 1462;
  113.                 var epoch = Date.parse(v);
  114.                 return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
  115.             }


  116.             //sheet_from_array_of_arrays
  117.             function sheet_from_array_of_arrays(data, opts) {
  118.                 var ws = {};
  119.                 var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
  120.                 for (var R = 0; R != data.length; ++R) {
  121.                     for (var C = 0; C != data[R].length; ++C) {
  122.                         if (range.s.r > R) range.s.r = R;
  123.                         if (range.s.c > C) range.s.c = C;
  124.                         if (range.e.r < R) range.e.r = R;
  125.                         if (range.e.c < C) range.e.c = C;
  126.                         var cell = { v: data[R][C] };
  127.                         if (cell.v == null) continue;
  128.                         var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });

  129.                         if (typeof cell.v === 'number') cell.t = 'n';
  130.                         else if (typeof cell.v === 'boolean') cell.t = 'b';
  131.                         else if (cell.v instanceof Date) {
  132.                             cell.t = 'n'; cell.z = XLSX.SSF._table[14];
  133.                             cell.v = datenum(cell.v);
  134.                         }
  135.                         else cell.t = 's';

  136.                         ws[cell_ref] = cell;
  137.                     }
  138.                 }
  139.                 if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
  140.                 return ws;
  141.             }


  142.             //s2ab
  143.             function s2ab(s) {
  144.                 var buf = new ArrayBuffer(s.length);
  145.                 var view = new Uint8Array(buf);
  146.                 for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  147.                 return buf;
  148.             }


  149.             //Workbook
  150.             function Workbook() {
  151.                 if (!(this instanceof Workbook)) return new Workbook();
  152.                 this.SheetNames = [];
  153.                 this.Sheets = {};
  154.             }


  155.             //write
  156.             var wb = new Workbook();
  157.             var ws = sheet_from_array_of_arrays(data);
  158.             wb.SheetNames.push(sheetname);
  159.             wb.Sheets[sheetname] = ws;
  160.             var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });


  161.             //saveAs
  162.             saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), filename)


  163.         }


  164.     </script>

  165. </head>
  166. <body>

  167.     <input type="file" id="upload_input" />

  168.     <h4>show json</h4>
  169.     <pre id="upload_showjson"></pre>

  170.     <h4>show csv</h4>
  171.     <pre id="upload_showcsv"></pre>

  172.     <button id="download_button">下載測試檔案</button>

  173. </body>
  174. </html>
複製代碼








歡迎光臨 伊莉討論區 (http://a401.file-static.com/) Powered by Discuz!