V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Cybozu0
V2EX  ›  推广

用 JS 实现 excel 预览

  •  
  •   Cybozu0 · 2020-08-06 12:35:45 +08:00 · 1432 次点击
    这是一个创建于 1331 天前的主题,其中的信息可能已经有所发展或是发生改变。

    概要

    这次为大家分享的是,如何用 js 写出 excel 文件的预览。

    他方便了 pc 用户和手机端用户可以无需下载,并且直接在线预览 excel 文件。

    因为 excel 转 html 的显示用的是第三方开源库的代码,所以实现上有所限制。具体请参见 所用到开源的库 这些库的说明。

    | 支持 | 不支持|
    | --- | --- |
    | 多 sheet 显示 | 图片显示 |
    | 合并后的单元格显示 | 链接,文字样式等 |
    | 手机画面优化 | |

    效果图

    PC:

    0015ed4c2338e02748a6246ec14c321

    手机:

    0015ed4c232e459910f436f2bcc0458

    示例代码

    所用到开源的库

    js:

    jQuery:https://js.cybozu.cn/jquery/3.4.1/jquery.min.js

    sheetjs ( js-xlsx ):https://github.com/SheetJS/sheetjs

    bootstrap: https://github.com/twbs/bootstrap

    css:

    https://github.com/FortAwesome/Font-Awesome

    https://github.com/keaukraine/bootstrap4-fs-modal ( mobile 端)

    代码

    判断是否为 excel 文件

     function checkXls(file) {
        let reg = /\.xl(s[xmb]|t[xm]|am|s)$/g;
        return reg.test(file);
     }
    

    加载模态框,显示加载画面,添加预览图标

    function loadModal(fileInfo) {
            let previewElement;
            jQuery(".file-image-container-gaia").each(function (i, e) {
                let fileName = jQuery(e).children("a:eq(0)").text();
                if (fileName == fileInfo.name && jQuery(e).children("button").length == 0) {
                    previewElement = jQuery(e);
                    return false;
                }
            });
            if (!previewElement) return;
            let modalId = 'myModal' + fileInfo.fileKey;
            let tabId = 'myTab' + fileInfo.fileKey;
            let tabContentId = 'tab-content' + fileInfo.fileKey;
            let $button = $('<button type="button" class="btn btn-default" data-toggle="modal" data-target="#' + modalId + '"><span class="fa fa-search"></span></button>');
            let myModal =
                '<style type="text/css">td{word-break: keep-all;white-space:nowrap;}</style>' +
                '<div class="modal fade tab-pane active" id="' + modalId + '" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">' +
                '<div class="modal-dialog modal-xl" style="border-radius:5px" role="document">' +
                '<div class="modal-content">' +
                '<div class="modal-header">' +
                '<h5 class="modal-title">' + fileInfo.name + '</h5>' +
                '<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
                '<span aria-hidden="true">&times;</span>' +
                '</button>' +
                '</div>' +
                '<ul class="nav nav-tabs" id=' + tabId + '>' +
                '</ul>' +
                '<div id=' + tabContentId + ' class="tab-content">' +
                '<div class="d-flex justify-content-center">' +
                '<div class="spinner-border" role="status">' +
                '<span class="sr-only">Loading...</span>' +
                '</div>' +
                '</div>' +
                '</div>' +
                '<div class="modal-footer">' +
                '<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>' +
                '</div>' +
                '</div>' +
                '</div>' +
                '</div>';
            previewElement.append($button);
            $('body').prepend(myModal);
            $('#' + modalId).on('shown.bs.modal', function (e) {
                loadRemoteFile(fileInfo);
            })
        }
    

    下载文件并加载到模态框中

     function readWorkbookFromRemoteFile(url, callback) {
            let xhr = new XMLHttpRequest();
            xhr.open('get', url, true);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.responseType = 'arraybuffer';
            xhr.onload = function (e) {
                if (xhr.status == 200) {
                    let data = new Uint8Array(xhr.response)
                    let workbook = XLSX.read(data, { type: 'array' });
                    if (callback) callback(workbook);
                }
            };
            xhr.send();
        }
        function readWorkbook(workbook, fileInfo) {
            let sheetNames = workbook.SheetNames;
            let navHtml = '';
            let tabHtml = '';
            let myTabId = 'myTab' + fileInfo.fileKey;
            let tabContentId = 'tab-content' + fileInfo.fileKey;
            for (let index = 0; index < sheetNames.length; index++) {
                let sheetName = sheetNames[index];
                let worksheet = workbook.Sheets[sheetName];
                let sheetHtml = XLSX.utils.sheet_to_html(worksheet);
                let tabid = "tab" + fileInfo.fileKey + "-" + index;
                let xlsid = "xlsid" + fileInfo.fileKey + "-" + index;
                let active = index == 0 ? "active" : '';
                navHtml += '<li class="nav-item"><a class="nav-link ' + active + '"  href="#"  data-target="#' + tabid + '" data-toggle="tab">' + sheetName + '</a></li>';
                tabHtml += '<div id="' + tabid + '" class="tab-pane ' + active + '" style="padding:10px;overflow:auto;height:600px" >' +
                    '<div id="' + xlsid + '">' + sheetHtml + ' </div></div>';
            }
            jQuery("#" + myTabId).html(navHtml);
            jQuery("#" + tabContentId).html(tabHtml);
            jQuery("#" + tabContentId + ' table').addClass("table table-bordered table-hover");
        }
        function loadRemoteFile(fileInfo) {
            let fileUrl = '/k/v1/file.json?fileKey=' + fileInfo.fileKey;
            readWorkbookFromRemoteFile(fileUrl, function (workbook) {
                readWorkbook(workbook, fileInfo);
            });
        }
    

    具体的 mobile 优化等等详细代码请参考完整文章:

    kintone excel 预览插件 更多文章和演示:Kintone demo 环境

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2914 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 14:07 · PVG 22:07 · LAX 07:07 · JFK 10:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.