开发者中心包含此范例模板(kintone Excel预览),请前往开发者中心下载学习。
Index
概要
这次为大家分享的是,如何用js写出Excel文件的预览。
他方便了pc用户和手机端用户可以无需下载,并且直接在线预览Excel文件。
因为Excel转html的显示用的是第三方开源库的代码,所以实现上有所限制。具体请参见 所用到开源的库 这些库的说明。
支持 | 不支持 |
---|---|
多sheet显示 | 图片显示 |
合并后的单元格显示 | 链接,文字样式等 |
手机画面优化 |
效果图
PC:
手机:
示例代码
所用到开源的库
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">×</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优化
使用"bootstrap-fs-modal.min.css"库,在mobile上打开Excel预览图标,会全屏显示Excel内容,同时关闭按钮调整在最上端,符合用户使用习惯。
function loadModal(fileInfo) { let previewElement; jQuery(".control-showlayout-file-gaia .control-value-gaia div").each(function (index, e) { let fileName = jQuery(e).find("a:eq(0)").text(); if (fileName == fileInfo.name && jQuery(e).find("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 modal-fullscreen" id="' + modalId + '" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">' + '<div class="modal-dialog modal-dialog-scrollable" 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">×</span>' + '</button>' + '</div>' + '<div>'+ '<ul class="nav nav-tabs" id=' + tabId + '>' + '</ul>' + '</div>' + '<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>' + '</div>' + '</div>'; previewElement.append($button); $('body').prepend(myModal); $('#' + modalId).on('shown.bs.modal', function (e) { loadRemoteFile(fileInfo); }) }
和kintone的结合
绑定kintone事件
kintone.events.on('app.record.detail.show', function (event) { let record = event.record; for (let index in record) { let field = record[index]; if (field.type === "FILE") { let fieldValue = field.value; fieldValue.forEach(function (file) { if (checkXls(file.name)) { loadModal(file); } }) } } });
做成kintone插件
如果你还不了解插件开发,请先参考 kintone 插件开发流程。
因为本范例没有用到插件的设置画面,所以插件的开发比较简单,只需要设置好manifest.json,然后打包即可
manifest.json
{ "manifest_version": 1, "version": 1, "type": "APP", "homepage_url": { "zh": "https://cybozudev.kf5.com/hc" }, "desktop": { "js": [ "https://js.cybozu.cn/jquery/3.4.1/jquery.min.js", "https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js", "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.1/xlsx.full.min.js", "js/excelPreview.js" ], "css": [ "https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css", "https://js.cybozu.cn/font-awesome/v4.7.0/css/font-awesome.min.css" ] }, "icon": "image/excelPreview.png", "name": { "en": "excelPreview", "ja": "excelPreview", "zh": "excelPreview" }, "description": { "en": "Excel Preview", "ja": "Excel Preview", "zh": "Excel Preview" }, "mobile": { "js": [ "https://js.cybozu.cn/jquery/3.4.1/jquery.min.js", "https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js", "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.1/xlsx.full.min.js", "js/excelPreviewMobile.js" ], "css": [ "https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css", "https://js.cybozu.cn/font-awesome/v4.7.0/css/font-awesome.min.css", "css/bootstrap-fs-modal.min.css" ] } }
使用
安装后,只有Excel的文件后面会有预览标识,其他文件不会出现预览图标。
代码下载
注意事项
本示例代码不保证其运行。
我们不为本示例代码提供技术支持。