查看完整版本: 網頁前端Javascript套件:SheetJS/js-xlsx.js
頁: [1]

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線上CDNhttps://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檔,其內給予資料:

http://www02.eyny.com/forum.php?mod=image&aid=117605505&size=300x300&key=4338c6811a38aedb147ee419207a0677&nocache=yes&type=fixnone

或使用附件:


上傳完xlsx檔會於網頁內顯示資料:
http://www02.eyny.com/forum.php?mod=image&aid=117605510&size=300x300&key=37538dcefeb36a89a73753dbdc53bb07&nocache=yes&type=fixnone

點擊下載測試檔案時,會將內建測試資料儲存至xlsx並彈出下載視窗,下載後xlsx內資料為:
http://www02.eyny.com/forum.php?mod=image&aid=117605951&size=300x300&key=d8f1aead25594c38ef26a014f8fd1128&nocache=yes&type=fixnone

範例程式碼如下:

<!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;

                //使用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文件[https://github.com/SheetJS/js-xlsx]


            //to_json
            function to_json(workbook) {
                var result = {};
                workbook.SheetNames.forEach(function (sheetName) {
                    var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets);
                    if (roa.length > 0) {
                        result = 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);
                    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文件[https://github.com/SheetJS/js-xlsx]


            //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.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 };
                        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;
                            cell.v = datenum(cell.v);
                        }
                        else cell.t = 's';

                        ws = 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 = 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 = ws;
            var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });


            //saveAs
            saveAs(new Blob(, { 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>



...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>
頁: [1]