来源:未知 时间:2022-04-27 13:47 作者:小飞侠 阅读:次
[导读] 转载自 GITHUB用户rockboom 的翻译文档 SheetJs下载: GITHUB地址 | CSDN下载地址 基础案例 htmllang=zh-cnheadmetacharset=UTF-8titleJS读取和导出excel示例/titlemetaname=descriptioncontent=使用sheetjs读取和导出e...
转载自 GITHUB用户rockboom 的翻译文档 基础案例<html lang="zh-cn"><head> <meta charset="UTF-8"> <title>JS读取和导出excel示例</title> <meta name="description" content="使用sheetjs读取和导出excel示例"> <style type="text/css"> table { border-collapse: collapse; } th, td { border: solid 1px #6D6D6D; padding: 5px 10px; } .mt-sm {margin-top: 8px;} body { background: #f4f4f4; padding: 0; margin: 0; } .container { width: 1024px; margin: 0 auto; background: #fff; padding: 20px; min-height: 100vh; } </style></head><body style=""> <div class="container"> <h1>JavaScript读取和导出excel示例(基于js-xlsx)</h1> <div> <a href="http://blog.haoji.me/js-excel.html" _target="_blank">如何使用JavaScript实现纯前端读取和导出excel文件</a><br> <a href="http://oss.sheetjs.com/js-xlsx/">官网演示</a><br> <a href="https://github.com/SheetJS/js-xlsx/">Github</a> </div> <h2>读取excel(仅读取第一个sheet)</h2> <div class="mt-sm"> <input type="file" id="file" style="display:none;" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"> <a href="javascript:selectFile()">加载本地excel文件</a> <a href="javascript:loadRemoteFile('./sample/sample.xlsx')">加载远程excel文件</a> </div> <p>结果输出:(下面表格可直接编辑导出)</p> <div id="result" contenteditable=""><table><tbody><tr><th></th><th>A</th><th>B</th><th>C</th><th>D</th></tr><tr><td>1</td><td>姓名</td><td>性别</td><td>年龄</td><td>籍贯</td></tr><tr><td>2</td><td>张三</td><td>男</td><td>18</td><td>广东惠州</td></tr><tr><td>3</td><td>李四</td><td>女</td><td>22</td><td>河北石家庄</td></tr></tbody></table></div> <h2>导出excel</h2> <div class="mt-sm" style="padding-bottom:40px;"> <input type="button" onclick="exportExcel()" value="保存"> 上面读取的表格您可以直接编辑,编辑后点击保存即可导出excel文件。 </div> <h2>导出带单元格合并的excel</h2> <input type="button" value="导出" onclick="exportSpecialExcel()"> </div> <script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="https://static.newmorehot.com/Public/Home/assets/js/jsxlsx/xlsx.core.min.js"></script> <script type="text/javascript"> function selectFile() { document.getElementById('file').click(); } // 读取本地excel文件 function readWorkbookFromLocalFile(file, callback) { var reader = new FileReader(); reader.onload = function(e) { var data = e.target.result; var workbook = XLSX.read(data, {type: 'binary'}); if(callback) callback(workbook); }; reader.readAsBinaryString(file); } // 从网络上读取某个excel文件,url必须同域,否则报错 function readWorkbookFromRemoteFile(url, callback) { var xhr = new XMLHttpRequest(); xhr.open('get', url, true); xhr.responseType = 'arraybuffer'; xhr.onload = function(e) { if(xhr.status == 200) { var data = new Uint8Array(xhr.response) var workbook = XLSX.read(data, {type: 'array'}); if(callback) callback(workbook); } }; xhr.send(); } // 读取 excel文件 function outputWorkbook(workbook) { var sheetNames = workbook.SheetNames; // 工作表名称集合 sheetNames.forEach(name => { var worksheet = workbook.Sheets[name]; // 只能通过工作表名称来获取指定工作表 for(var key in worksheet) { // v是读取单元格的原始值 console.log(key, key[0] === '!' ? worksheet[key] : worksheet[key].v); } }); } function readWorkbook(workbook) { var sheetNames = workbook.SheetNames; // 工作表名称集合 var worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet var csv = XLSX.utils.sheet_to_csv(worksheet); document.getElementById('result').innerHTML = csv2table(csv); } // 将csv转换成表格 function csv2table(csv) { var html = '<table>'; var rows = csv.split('\n'); rows.pop(); // 最后一行没用的 rows.forEach(function(row, idx) { var columns = row.split(','); columns.unshift(idx+1); // 添加行索引 if(idx == 0) { // 添加列索引 html += '<tr>'; for(var i=0; i<columns.length; i++) { html += '<th>' + (i==0?'':String.fromCharCode(65+i-1)) + '</th>'; } html += '</tr>'; } html += '<tr>'; columns.forEach(function(column) { html += '<td>'+column+'</td>'; }); html += '</tr>'; }); html += '</table>'; return html; } function table2csv(table) { var csv = []; $(table).find('tr').each(function() { var temp = []; $(this).find('td').each(function() { temp.push($(this).html()); }) temp.shift(); // 移除第一个 csv.push(temp.join(',')); }); csv.shift(); return csv.join('\n'); } // csv转sheet对象 function csv2sheet(csv) { var sheet = {}; // 将要生成的sheet csv = csv.split('\n'); csv.forEach(function(row, i) { row = row.split(','); if(i == 0) sheet['!ref'] = 'A1:'+String.fromCharCode(65+row.length-1)+(csv.length-1); row.forEach(function(col, j) { sheet[String.fromCharCode(65+j)+(i+1)] = {v: col}; }); }); return sheet; } // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载 function sheet2blob(sheet, sheetName) { sheetName = sheetName || 'sheet1'; var workbook = { SheetNames: [sheetName], Sheets: {} }; workbook.Sheets[sheetName] = sheet; // 生成excel的配置项 var wopts = { bookType: 'xlsx', // 要生成的文件类型 bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性 type: 'binary' }; var wbout = XLSX.write(workbook, wopts); var blob = new Blob([s2ab(wbout)], {type:"application/octet-stream"}); // 字符串转ArrayBuffer 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; } return blob; } /** * 通用的打开下载对话框方法,没有测试过具体兼容性 * @param url 下载地址,也可以是一个blob对象,必选 * @param saveName 保存文件名,可选 */ function openDownloadDialog(url, saveName) { if(typeof url == 'object' && url instanceof Blob) { url = URL.createObjectURL(url); // 创建blob地址 } var aLink = document.createElement('a'); aLink.href = url; aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效 var event; if(window.MouseEvent) event = new MouseEvent('click'); else { event = document.createEvent('MouseEvents'); event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); } aLink.dispatchEvent(event); } $(function() { document.getElementById('file').addEventListener('change', function(e) { var files = e.target.files; if(files.length == 0) return; var f = files[0]; if(!/\.xlsx?$/g.test(f.name)) { alert('仅支持读取xlsx格式!'); return; } readWorkbookFromLocalFile(f, function(workbook) { readWorkbook(workbook); }); }); loadRemoteFile('./sample/test.xlsx'); }); function loadRemoteFile(url) { readWorkbookFromRemoteFile(url, function(workbook) { readWorkbook(workbook); }); } function exportExcel() { var csv = table2csv($('#result table')[0]); var sheet = csv2sheet(csv); var blob = sheet2blob(sheet); openDownloadDialog(blob, '导出.xlsx'); } function exportSpecialExcel() { var aoa = [ ['主要信息', null, null, '其它信息'], // 特别注意合并的地方后面预留2个null ['姓名', '性别', '年龄', '注册时间'], ['张三', '男', 18, new Date()], ['李四', '女', 22, new Date()] ]; var sheet = XLSX.utils.aoa_to_sheet(aoa); sheet['!merges'] = [ // 设置A1-C1的单元格合并 {s: {r: 0, c: 0}, e: {r: 0, c: 2}} ]; openDownloadDialog(sheet2blob(sheet), '单元格合并示例.xlsx'); } </script></body></html>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 SheetJS js-xlsxSheetJS是用于多种电子表格格式的解析器和编写器。通过官方规范、相关文档以及测试文件实现简洁的JS方法。SheetJS强调解析和编写的稳健,其跨格式的特点和统一的JS规范兼容,并且ES3/ES5浏览器向后兼容IE6。 支持格式的图表 (点击查看) 目录表点击展示目录表 安装在浏览器里使用,增加一个script标签: <script lang="javascript" src="dist/xlsx.full.min.js"></script>1 使用CDN (点击显示详情)
unpkg提供最新的版本: <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>1 使用 npm: $ npm install xlsx1 使用 bower: $ bower install js-xlsx1 JS生态示例示例 目录 包括了一些简单的项目: 框架和APIS 打包工具 集成平台 可选模块可选特点 (点击显示详情) node版本自动要求模块提供其他的特性。某些模块的文件相当大而且仅在一些特殊的场景下才会用到,因此不应该把他们当做核心部分一起加载。在浏览器中用到这些模块时,可以用下面的方式进行加载: <!-- international support from js-codepage --><script src="dist/cpexcel.js"></script>12 每一个依赖合适的版本可以放在 dist/directory 目录下。 /* uncomment the lines below to remove support */ resolve: { alias: { "./dist/cpexcel.js": "" } // <-- omit international support }1234 ECMAScript 5 的兼容性自从库使用了像 Array#forEach 这样的函数,老版本的浏览器需要shim 提供缺少的函数。 要在加载 xlsx.js 的script标签之前添加shim,才能使用它。 <!-- add the shim first --><script type="text/javascript" src="shim.min.js"></script><!-- after the shim is referenced, add the library --><script type="text/javascript" src="xlsx.full.min.js"></script>1234 shim.min.js也包括了在IE6-9中用于加载和保存文件的 IE_LoadFile 和 IE_SaveFile。对于适用于Photoshop和其它的Adobe产品的格式,xlsx.extendscript.js脚本会绑定shim。 原理原理 (点击显示详情) 在SheetJS之前,处理电子表格文件的接口只能用于特定的格式。许多第三方库要么支持一种格式,要么为每一种支持的文件类型提供一个不同的类集。虽然在Excel 2007里面引入了XLSB,但只有Sheet和Excel支持这种格式。 为了提高不可知格式的显示,js-xlsx使用了被称作[“Common Spreadsheet Format”]的纯JS的显示方法(#common-spreadsheet-format)。强调一种统一的显示方式,能够有一些特点,比如格式转换和嵌套class tap。通过提取出各种格式的复杂性,工具没有必要担心特定的文件类型。 一个简单的的对象显示和细心的代码练习相结合,能让示例运行在较老的浏览器以及像ExtendScript和Web Workers这样可选择的环境里执行。虽然很想使用最新的和最好的特性,不过这些特性需要最新的浏览器,用以限制兼容性。 工具函数捕获通用的使用例子,比如生成JS对象或HTML。大多数简单例子的操作只要几行代码。大多数复杂的普遍的复杂操作应该直截了当的生成。 在Excel 2007种,Excel添加XSLX格式作为默认的起始端。然而,有一些其他格式会更多的出现上述的属性。例如,XLSB格式XLSX格式相似,不过文件会使用一半的空间,而且也会更开的打开文件。虽然XLSX编写器可以使用,但是其他格式的编写器也可以使用,因此使用者能够充分利用每一种格式独特的特点。社区版本的主要关注点在正确的数据转换,即从任意一个兼容的数据表示中提取数据,导出适用于任意第三方接口的各种数据格式。 解析工作簿对于解析,第一步是读取文件。这一步包括获取数据并且导入数据库。这里有一些常用的例子。 nodejs读取文件 (点击显示详情) `readFile` 只能在服务器环境中使用。浏览器没有用于读取任意指定路径文件的API,因此必须使用另外的策略。 ```js if(typeof require !== 'undefined') XLSX = require('xlsx'); var workbook = XLSX.readFile('test.xlsx'); /* DO SOMETHING WITH workbook HERE */ ``` Photoshop ExtendScript读取文件 (点击显示详情) readFile 用Photoshop和其他的ExtendScript目标把逻辑File包起来。需要指定文件的绝对路径 #include "xlsx.extendscript.js"/* Read test.xlsx from the Documents folder */var workbook = XLSX.readFile(Folder.myDocuments + '/' + 'test.xlsx');/* DO SOMETHING WITH workbook HERE */1234 extendscript 包含了一个更复杂的例子。 浏览器从页面读取TABLE元素 (点击显示详情) `table_to_book` 和 `table_to_sheet`工具函数获取DOM的TABLE元素,并且通过子节点进行迭代。 var workbook = XLSX.utils.table_to_book(document.getElementById('tableau'));/* DO SOMETHING WITH workbook HERE */12 一个网页里面的多张表可以被转换成单个的工作表。 /* create new workbook */var workbook = XLSX.utils.book_new();/* convert table 'table1' to worksheet named "Sheet1" */var ws1 = XLSX.utils.table_to_sheet(document.getElementById('table1'));XLSX.utils.book_append_sheet(workbook, ws1, "Sheet1");/* convert table 'table2' to worksheet named "Sheet2" */var ws2 = XLSX.utils.table_to_sheet(document.getElementById('table2'));XLSX.utils.book_append_sheet(workbook, ws2, "Sheet2");/* workbook now has 2 worksheets */123456789101112 另一种选择,HTML代码也可以被提取和解析。 var htmlstr = document.getElementById('tableau').outerHTML;var workbook = XLSX.read(htmlstr, {type:'string'});12 浏览器下载文件(ajax) (点击显示详情) 注意:对于运行在老版浏览器里更完整的例子,请查看示例 var url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx";/* set up async GET request */var req = new XMLHttpRequest();req.open("GET", url, true);req.responseType = "arraybuffer";req.onload = function(e) { var data = new Uint8Array(req.response); var workbook = XLSX.read(data, {type:"array"}); /* DO SOMETHING WITH workbook HERE */}req.send();123456789101112131415 浏览器拖拽 (点击显示详情) 拖拽使用了HTML5 的 `FileReader` API,加载数据时使用`readAsBinaryString` 或 `readAsArrayBuffer`。但并不是所有的浏览器都支持全部的 `FileReader` API,因此非常推荐动态的特性检测。 var rABS = true; // true: readAsBinaryString ; false: readAsArrayBufferfunction handleDrop(e) { e.stopPropagation(); e.preventDefault(); var files = e.dataTransfer.files, f = files[0]; var reader = new FileReader(); reader.onload = function(e) { var data = e.target.result; if(!rABS) data = new Uint8Array(data); var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'}); /* DO SOMETHING WITH workbook HERE */ }; if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f);}drop_dom_element.addEventListener('drop', handleDrop, false);123456789101112131415 浏览器通过form元素上传文件 (点击显示详情) 来自file input元素的数据能够被和拖拽例子中相同的FileReaderAPI处理。 var rABS = true; // true: readAsBinaryString ; false: readAsArrayBufferfunction handleFile(e) { var files = e.target.files, f = files[0]; var reader = new FileReader(); reader.onload = function(e) { var data = e.target.result; if(!rABS) data = new Uint8Array(data); var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'}); /* DO SOMETHING WITH workbook HERE */ }; if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f);}input_dom_element.addEventListener('change', handleFile, false);1234567891011121314 oldie示例展示了一个IE兼容性的回退方案。 包括移动App文件处理等更多的使用例子可以在included demos中查看。 流式读取文件为什么没有流式读取API? (点击显示详情) 最常用的和最令人感兴趣的格式(XLS, XLSX/M, XLSB, ODS)最终都是ZIP或CFB文件容器。两种格式都不会放目录结构在文件开头:ZIP文件把主要的目录记录放在逻辑文件的结尾,然而CFB文件可以把存储信息放在文件的任何地方。所以,为了正确地处理这些格式,流式函数必须在开始之前缓存整个文件。这样证明了流式的期待的错误,因此我们不提供任何流式阅读API。 当处理可读流时,最简单的方式是缓存流,并且最后再去处理整个文件。这可以通过临时文件或者是显式连接流来实现。 显式连接流 (点击显示详情) var fs = require('fs');var XLSX = require('xlsx');function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{ var buffers = []; stream.on('data', function(data) { buffers.push(data); }); stream.on('end', function() { var buffer = Buffer.concat(buffers); var workbook = XLSX.read(buffer, {type:"buffer"}); /* DO SOMETHING WITH workbook IN THE CALLBACK */ cb(workbook); });}12345678910111213 使用像concat-stream这样的模块会有更多有效的解决办法可以使用。 首先写入文件系统 (点击显示详情) 这个例子使用tempfile生成文件名。 var fs = require('fs'), tempfile = require('tempfile');var XLSX = require('xlsx');function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{ var fname = tempfile('.sheetjs'); console.log(fname); var ostream = fs.createWriteStream(fname); stream.pipe(ostream); ostream.on('finish', function() { var workbook = XLSX.readFile(fname); fs.unlinkSync(fname); /* DO SOMETHING WITH workbook IN THE CALLBACK */ cb(workbook); });}123456789101112131415 使用工作簿完整的对象格式会在本文件的后面部分进行介绍。 读取指定的单元格 (点击显示详情) 这个例子提取first工作表中A1单元格的存储值: var first_sheet_name = workbook.SheetNames[0];var address_of_cell = 'A1';/* Get worksheet */var worksheet = workbook.Sheets[first_sheet_name];/* Find desired cell */var desired_cell = worksheet[address_of_cell];/* Get the value */var desired_value = (desired_cell ? desired_cell.v : undefined);1234567891011 在工作簿中增加新的工作表 (点击显示详情) 例子中使用XLSX.utils.aoa_to_sheet生成工作表,使用XLSX.utils.book_append_sheet把表添加到工作簿中。 var new_ws_name = "SheetJS";/* make worksheet */var ws_data = [ [ "S", "h", "e", "e", "t", "J", "S" ], [ 1 , 2 , 3 , 4 , 5 ]];var ws = XLSX.utils.aoa_to_sheet(ws_data);/* Add the worksheet to the workbook */XLSX.utils.book_append_sheet(wb, ws, ws_name);1234567891011 从头开始创建工作簿 (点击显示详情) 工作簿对象包含一个SheetNames名称数组和一个Sheets对象,用来将表名映射到表对象。XLSX.utils.book_new工具函数创建一个新的工作簿对象: /* create a new blank workbook */var wb = XLSX.utils.book_new();12 新的工作簿是空白的而且不包含工作表。如果工作簿,那么写入函数将会出错。 解析和编写示例
node安装一个能够读取电子数据表和输出各种格式的命令行工具 xlsx。源码可以在 bin 目录下的xlsx.njs里面找到。 XLSX.utils中的一些辅助函数会生成不同的工作表视图。
编写工作簿对编写而言,第一步是生成导出数据。辅助函数write 和 writeFile将会生成各种适合分发的数据格式。第二步是和端点实际的共享数据。假设workbook是一个工作簿对象。 nodejs写入文件 (点击显示详情) XLSX.writeFile uses fs.writeFileSync in server environments: if(typeof require !== 'undefined') XLSX = require('xlsx');/* output format determined by filename */XLSX.writeFile(workbook, 'out.xlsb');/* at this point, out.xlsb is a file that you can distribute */1234 Photoshop ExtendScript 写入文件 (点击显示详情) writeFile 把 File包裹在 Photoshop 和 other ExtendScript 目标里面。指定的路径应该是绝对路径。 #include "xlsx.extendscript.js"/* output format determined by filename */XLSX.writeFile(workbook, 'out.xlsx');/* at this point, out.xlsx is a file that you can distribute */1234 extendscript 示例包含有更复杂的例子。 浏览器将TABLE元素添加到页面 (点击显示详情) sheet_to_html工具函数生成能被添加到任意DOM元素的HTML代码。 var worksheet = workbook.Sheets[workbook.SheetNames[0]];var container = document.getElementById('tableau');container.innerHTML = XLSX.utils.sheet_to_html(worksheet);123 浏览器上传文件(ajax) (点击显示详情) 用 XHR 的完整的复杂示例可以在 XHR示例 中查看,获取和包装器库的例子也可以包含在里面。例子中假设服务器能处理Base64编码的文件(查看基本的莫得服务器示例)。 /* in this example, send a base64 string to the server */var wopts = { bookType:'xlsx', bookSST:false, type:'base64' };var wbout = XLSX.write(workbook,wopts);var req = new XMLHttpRequest();req.open("POST", "/upload", true);var formdata = new FormData();formdata.append('file', 'test.xlsx'); // <-- server expects `file` to hold nameformdata.append('data', wbout); // <-- `data` holds the base64-encoded datareq.send(formdata);1234567891011 浏览器保存文件 (点击显示详情) XLSX.writeFile 包含了一些用于触发文件保存的方法。
并没有标准的方法判断是否真实的文件已经被下载了。 /* output format determined by filename */XLSX.writeFile(workbook, 'out.xlsb');/* at this point, out.xlsb will have been downloaded */123 浏览器保存文件(兼容性) (点击显示详情) XLSX.writeFile方法在大多数的现代浏览器以及老版本的浏览器中都能使用。对于更老的浏览器,wrapper库里面有变通的方法可以应用。 FileSaver.js 执行 saveAs方法。 注意:如果saveAs方法可以使用,XLSX.writeFile会自动调用。 /* bookType can be any supported output type */var wopts = { bookType:'xlsx', bookSST:false, type:'array' };var wbout = XLSX.write(workbook,wopts);/* the saveAs call downloads a file on the local machine */saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx");1234567 Downloadify使用Flash SWF按钮生成本地文件,即使是ActiveX不能使用的环境也适用。 Downloadify.create(id,{ /* other options are required! read the downloadify docs for more info */ filename: "test.xlsx", data: function() { return XLSX.write(wb, {bookType:"xlsx", type:'base64'}); }, append: false, dataType: 'base64'});1234567 oldie示例展示了IE向后兼容的场景。 included demos包含了移动app和其他专门的部署。 写入示例
流式写入XLSX.stream对象中可以使用流式写入函数。流式函数像普通的函数一样传入相同的参数,不过返回一个可读流。但是他们只暴露在Nodejs中。
nodejs转换成CSV并写入文件 (点击显示详情) var output_file_name = "out.csv";var stream = XLSX.stream.to_csv(worksheet);stream.pipe(fs.createWriteStream(output_file_name));123 nodejs将JSON流输出到屏幕 (点击显示详情) /* to_json returns an object-mode stream */var stream = XLSX.stream.to_json(worksheet, {raw:true});/* the following stream converts JS objects to text via JSON.stringify */var conv = new Transform({writableObjectMode:true});conv._transform = function(obj, e, cb){ cb(null, JSON.stringify(obj) + "\n"); };stream.pipe(conv); conv.pipe(process.stdout);12345678 https://github.com/sheetjs/sheetaki pips将可写流写入nodejs响应。 接口XLSX是浏览器暴露出来可以使用的方法,导出到node中能够使用的XLSX.version是XLSX库的版本(通过构建脚本添加)。XLSX.SSF是格式化库的嵌入版本。 解析函数XLSX.read(data, read_opts) 用来解析数据 data。 写入函数XLSX.write(wb, write_opts) 用来写入工作簿 wb。 XLSX.stream 包含一组流式写入函数的集合。 写入选项会在写入选项部分部分进行阐述。 工具XLSX.utils对象中的工具函数都可以使用,工具函数在工具函数部分进行阐述。 导入:
导出:
单元格和单元格地址的操作:
常用的数据表格式(Common Spreadsheet Format)js-xlsx符合常用的数据表格式(CSF)。 一般结构单元格地址对象的存储格式为{c:C, r:R},其中C和R分别代表的是0索引列和行号。例如单元格地址B5用对象{c:1, r:4}表示。 单元格范围对象存储格式为{s:S, e:E},其中S是第一个单元格,E是最后一个单元格。范围是包含关系。例如范围 A3:B7用对象{s:{c:0, r:2}, e:{c:1, r:6}}表示。当遍历数据表范围时,工具函数执行行优先命令。 for(var R = range.s.r; R <= range.e.r; ++R) { for(var C = range.s.c; C <= range.e.c; ++C) { var cell_address = {c:C, r:R}; /* if an A1-style address is needed, encode the address */ var cell_ref = XLSX.utils.encode_cell(cell_address); }}1234567 单元格对象单元格对象是纯粹的JS对象,它的keys和values遵循下列的约定:
如果w文本可以使用,内置的导出工具(比如CSV导出方法)就会使用它。要想改变单元格的值,在打算导出之前确保删除cell.w(或者设置 cell.w为undefined)。工具函数会根据数字格式(cell.z)和原始值(如果可用)重新生成w文本。 真实的数组公式存储在数组范围中第一个单元个的f字段内。此范围内的其他单元格会省略f字段。 数据类型原始值被存储在v值属性中,用来解释基于t类型的属性。这样的区别允许用于数字和数字类型文本的展示。下面有6种有效的单元格类型。
Error 值以及含义 (点击显示详情)
n表示Number类型。n包括了所有被Excel存储为数字的数据表,比如dates/times和Boolean字段。Excel专门使用能够被IEEE754浮点数表示的数据,比如JS Number,所以字段 v 保存原始数字。w字段保持格式化文本。Dates 默认存储为数字,使用XLSX.SSF.parse_date_code进行转换。 类型 d表示日期类型,只有当选项为cellDates才会生成日期类型。因为JSON没有普通的日期类型,所以希望解析器存储的日期字符串像从date.toISOString()中获取的一样。另一方面,写入函数和导出函数也可以处理日期字符串和JS日期对象。需要注意Excel会忽略时区修饰符,并且处理所有本地时区的日期。代码库没有改正这个错误。 类型z表示空白的存根单元格。生成存根单元格是为了以防万一单元格没有被赋予指定值,但是保留了注释或者是其他的元数据。存根单元格会被核心库的数据处理工具函数忽略。默认情况下不会生成存根单元格,只有当解析器sheetStubs的选项被设为true时才会生成。 日期Excel 日期编码的细节 (点击显示详情) 默认情况下,Excel把日期存储为数字,并用指定的日期处理格式编码进行处理。例如,日期19-Feb-17被存储为数字42785,数字格式为d-mmm-yy。SSF模块了解数字格式并进行适当的转换。 XSLX也支持特定的日期类型d,它的数据是ISO 8601日期字符串。格式化工具把日期还原为数字。 所有解析器的默认行为是生成数字单元格。设置cellDates为true会强制生成器存储日期。 时区和日期 (点击显示详情) Excel没有原生的通用时间的概念。所有的时间都会在本地时区指定。Excel限制指定真正的绝对日期。 对于下面的Excel,代码库将所有的日期视为相对于当地时区的日期。 时期:1900年和1904年 (点击显示详情) Excel支持两种时期(January 1 1900和January 1 1904),查看"1900 vs. 1904 Date System" article。工作簿的时期可以通过测试工作簿的wb.Workbook.WBProps.date1904属性来决定: !!(((wb.Workbook||{}).WBProps||{}).date1904)1 数据表对象每一个不以!开始的key都会映射到一个单元格(用A-1符合)。sheet[address] 返回指定地址的单元格对象。 指定的数据表属性(通过 sheet[key]访问, 每一个都以 !开始):
处理数据表的函数应该对!ref的存在进行检测。如果!ref被忽略或者不是有效的范围,函数就可以吧数据表看做是空表或者尝试猜范围。词库附带的工具函数会将工作表视为空(例如CSV的输出是空字符串)。 当用sheetRows属性集读取工作表时,ref参数会使用限制的范围。最初的范围通过ws['!fullref']设置。
页面边距详情 (点击显示详情)
/* Set worksheet sheet to "normal" */ws["!margins"]={left:0.7, right:0.7, top:0.75,bottom:0.75,header:0.3,footer:0.3}/* Set worksheet sheet to "wide" */ws["!margins"]={left:1.0, right:1.0, top:1.0, bottom:1.0, header:0.5,footer:0.5}/* Set worksheet sheet to "narrow" */ws["!margins"]={left:0.25,right:0.25,top:0.75,bottom:0.75,header:0.3,footer:0.3}123456 工作表对象除了基本的数据表关键字之外,工作表还增加了下面的内容:
工作表保护详情 (点击显示详情)
type AutoFilter = { ref:string; // A-1 based range representing the AutoFilter table range}123 图表对象图表会被显示为标准的数据表。要注意和!type被设置为"chart"的属性进行区分。 底层数据和!ref指的是图表中的缓存数据。 图表的第一行是底层标题。 宏对象宏对象会被显示为标准的数据表。注意与!type设置为"macro"的属性进行区分。 对话框对象对话框对象会被显示为标准的数据表。注意与!type设置为"dialog"的属性进行区分。 工作簿对象workbook.SheetNames 是工作簿内工作表的有序列表。 wb.Sheets[sheetname] 返回一个表示工作表的对象。 wb.Props 是一个存储标准属性的对象。wb.Custprops 存储自定义的属性。因为XLS标准属性偏离了XLSX标准,所以XLS解析把核心的属性存储在两个属性中。 wb.Workbook 存储工作簿级别的特性. 工作簿文件属性各种各样的文件格式为不同的文件属性使用不同的内置名称。工作簿的Props对象用来规范这些名称。 文件属性 (点击显示详情)
例如设置工作簿的title属性: if(!wb.Props) wb.Props = {};wb.Props.Title = "Insert Title Here";12 自定义的属性会被添加到工作簿的Custom对象中: if(!wb.Custprops) wb.Custprops = {};wb.Custprops["Custom Property"] = "Custom Value";12 写入函数将会处理选项对象的Props键: /* force the Author to be "SheetJS" */XLSX.write(wb, {Props:{Author:"SheetJS"}});12 工作簿级别的特性wb.Workbook 存储工作簿级别的特性。 定义名称wb.Workbook.Names 是一个定义名称对象的数组,这些名称对象都有键: 定义名称属性 (点击显示)
Excel 允许两个表格范围定义的名称共享相同的名称。但是一个表格范围的名称不能和一个工作簿范围的名称相冲突。工作簿写入函数不强制这样的约束。 工作簿视图wb.Workbook.Views 是一个工作簿视图对象数组,这些视图对象有keys。
混合的工作簿属性
文档特点即使是想存储数据这样的基本特点,官方的Excel格式也会用不同的方式存储相同的内容。期望解析器从底层文件格式转换为通用的电子表格格式。期望编写器将CSF格式转换回基本的文件格式。 公式A1单元格样式字符串被存储在f字段中。虽然不同的文件格式用不同的方式存储文件格式,不过这些格式都需要被翻译。虽然一些格式存储的公式有一个前导等号,但是CSF公式不以=开始。 A1=1, A2=2, A3=A1+A2的显示 (点击展示详情) { "!ref": "A1:A3", A1: { t:'n', v:1 }, A2: { t:'n', v:2 }, A3: { t:'n', v:3, f:'A1+A2' }}123456 共享的公式会被解压缩,并且每一个单元格都有相应的公式。编写器通常不会尝试去生成共享公式。 有公式记录但是没有值的单元格会被序列化,序列化的方式能够被Excel和其他电子表格工具将会识别。这个代码库将不会自动计算公式结果!例如去计算工作表中的BESSELJ。 没有已知值的公式 (点击显示详情) { "!ref": "A1:A3", A1: { t:'n', v:3.14159 }, A2: { t:'n', v:2 }, A3: { t:'n', f:'BESSELJ(A1,A2)' }}123456 数组公式 数组公式被存储在数组块左上角的单元格内。一个数组公式的所有单元格都会有于该范围对应的F字段。一个单一的单元格公式要注意于F字段所存储的纯公式进行区分。 数组公式示例 (点击显示详情) 例如设置单元格C1为数组公式{=SUM(A1:A3*B1:B3)}: worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };1 对于多个单元格的数组公式,每一个单元格都有相同的数组范围,不过只有第一个单元格指定公式。考虑D1:D3=A1:A3*B1:B3: worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };worksheet['D2'] = { t:'n', F:"D1:D3" };worksheet['D3'] = { t:'n', F:"D1:D3" };123 工具函数和编写器被用来检查F字段的存在,并且忽略单元格内任何可能的公式元素f,这些单元格并不包含起始单元格。这些操作函数并不会被要求执行公式的校验。 公式输出工具函数 (点击显示详情) sheet_to_formulae方法生成为每个公式或者是数组公式生成一行。数组公式被渲染在range=formula的表格内,而纯单元格被渲染在cell=formula or value的表格内。注意字符串的迭代会有前缀符号',与Excel公式栏显示的一致。 公式文件格式细节 (点击显示详情)
因为Excel禁止单元格的命名与A1的名称或者是RC样式单元格引用相冲突,可能会进行不是那么简单的正则变化。DIFF解析的公式必须被明确的解开。OpenFormula可以转换正则表达式。 列属性每张表都会有!cols数组,如果展开的话就是ColInfo的一个集合,有下列的属性: type ColInfo = { /* visibility */ hidden?: boolean; // if true, the column is hidden /* column width is specified in one of the following ways: */ wpx?: number; // width in screen pixels width?: number; // width in Excel's "Max Digit Width", width*256 is integral wch?: number; // width in characters /* other fields for preserving features from files */ MDW?: number; // Excel's "Max Digit Width" unit, always integral};123456789101112 为什么有三种宽度类型? (点击显示详情) 有三种不同的宽度类型对应于电子数据表存储列宽的三种不同方式。 SYLK和其他的纯文本格式使用原生的字符计算。像Visicalc和Multiplan这样的同时期的工具是基于字符的。因为字符有相同的宽度,足以存储一个计数。这样的传统也延续到了BIFF格式。 SpreadsheetML (2003) 尝试通过标准化整个文件中的屏幕像素计数来与HTML对齐。列宽、行高以及其他的测量使用像素。当像素和字符数量不一致时,Excel四舍五入结果。 XLSX内部用一个模糊的"最大数位宽度"表存储列宽。最大数字宽度是渲染时最大数字的宽度,通常字符"0"是最宽的。内部的宽度必须是宽度除以256的整数倍。ECMA-376介绍了一个公式用于像素和内部宽度之间的转换。这代表一种混合的方式。 读取函数尝试去填充全部的三种属性。写函数努力尝试将指定值循环到所需类型。为了阻止潜在的冲突。首先操作应该要删除其他的属性。列入,当改变像素宽度时,删除wch 和 width属性。 执行细节 (点击显示详情) 给出的这些约束可能决定了MDW没有检查字体!解析器通过从宽度转换为像素并返回来猜测像素宽度,重复所有可能的MDW并选择最小化村务的MDW。XLML实际上存储额像素宽度,所以猜想会在相反的方向运行。 即使所有的信息都是可用的,也会期望写入函数遵循下面的优先级顺序:
行属性如果!rows 数组在每张电子表中都存在,那就是一个RowInfo对象的集合,集合包含一下的属性: type RowInfo = { /* visibility */ hidden?: boolean; // if true, the row is hidden /* row height is specified in one of the following ways: */ hpx?: number; // height in screen pixels hpt?: number; // height in points level?: number; // 0-indexed outline / group level};12345678910 注意:Excel UI显示基本大纲级别为1,最大级别为8。level字段存储基本大纲级别为0,最大级别为7。 实现细节 (点击展示详情) Excel内部以点为单位存储行高。默认的分辨率是72DPI或者是96DPI,所以像素和点的大小应该相同。不同的分辨率他们可能不同,因此库分开了这些概念: 即使所有的信息都可用,写入函数也应该遵循下面的优先级顺序: 数字格式对于每一个单元格而言,cell.w的文本来自于cell.v 和 cell.z格式。如果格式没有指定,ExcelGeneral格式就会被使用。格式要么是指定的的字符串要么是格式表内的一个索引。解析器应该用数字格式表来填充workbook.SSF。写入函数用来序列化这个表。 自定义的工具应该确保本地表的表内有各自的格式字符串。Excel约定规定自定义的格式以索引164开头。下面的例子从头创建了一个自定义的格式: 自定义格式的新工作簿 (点击显示详情) var wb = { SheetNames: ["Sheet1"], Sheets: { Sheet1: { "!ref":"A1:C1", A1: { t:"n", v:10000 }, // <-- General format B1: { t:"n", v:10000, z: "0%" }, // <-- Builtin format C1: { t:"n", v:10000, z: "\"T\"\ #0.00" } // <-- Custom format } }}1234567891011 这些规则和Excel如何显示自定义的数字格式稍微有些区别。特别是文字字符必须必包含在双引号里面或者在反斜杠之前。更多信息,查看Excel文档Create or delete a custom number format 或者是ECMA-376 18.8.31(数字格式)。 默认的数字格式 (点击展示详情) ECMA-376 18.8.30里列出的默认格式:
格式14(m/d/yy)被Excel本地化:即使文件指明了数字格式,也会根据系统设置用不同的方式绘制。当文件的的生产者和使用者都在相同的区域时这会很有用,不过对于网络上的例子就会不同。为了避免歧义,解析函数接受dateNF选项覆盖指定格式字符串的解释。 超链接超链接存储在单元格对象的l关键字内。超链接对象的Target字段是连接目标,包括了URI片段。工具提示被存储在Tooltip字段内,当移动鼠标到文字上方就会显示。 例如下方的片段在单元格A3内创建了一个指向http://sheetjs.com的链接,提示信息是"Find us @ SheetJS.com!": ws['A3'].l = { Target:"http://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" };1 注意Excel并不会自动为超链接添加样式–他们通常会向普通文本一样显示。 如果链接的目标是一个单元格或者是范围又或者是在相同的工作簿内定义名字(“Internal Links”),那么链接的开头会有一个哈希字符标识: ws['A2'].l = { Target:"#E2" }; /* link to cell E2 */1 单元格注释单元格注释是对象,被存储在单元格对象的c数组内。实际上注释的内容根据注释的作者被分成了小块。每一个注释对象的a字段存储注释的作者,t字段是注释的纯文字展示。 例如下面的片段在单元格A1内添加了单元格注释: if(!ws.A1.c) ws.A1.c = [];ws.A1.c.push({a:"SheetJS", t:"I'm a little comment, short and stout!"});12 注意:XLSB对作者的名字施加54个字符的限制。名字的长度超过54个字符可能造成其他的格式问题。 把注释标记为普通的隐藏,只需设置hidden属性: if(!ws.A1.c) ws.A1.c = [];ws.A1.c.push({a:"SheetJS", t:"This comment is visible"});if(!ws.A2.c) ws.A2.c = [];ws.A2.c.hidden = true;ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"});123456 数据表能见度Excel支持将表格隐藏在更低的标签栏。表格数据存储文件内,但是UI不容易让它可以使用。标准的隐藏表格会被显示在"Unhide"菜单内。Excel也有"very hidden"表格,这些表格不能被显示在菜单内。只可以通过Vb编辑器访问。 能见度的设置被存储在表格属性数组的Hidden属性当中。 更多细节 (点击显示详情)
更多详情请查看https://rawgit.com/SheetJS/test_files/master/sheet_visibility.xlsx: > wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] })[ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ]12 非Excel格式不支持"Very Hidden"状态。测试一个数据比哦啊是否可见的最好方式是检查是否Hidden属性为逻辑truth: > wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] })[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]12 VBA和宏命令VBA宏命令存储在特殊的数据blob中,当bookVBA选项为true时,blob会暴露在工作簿对象的vbaraw属性中。VBA宏命令支持 XLSM, XLSB, 和 BIFF8 XLS 格式。如果blob存在于工作簿中,并且和工作簿的名字有关联,支持的格式写入函数会自动插入数据blob。 自定义编码名称 (点击显示) 工作簿编码名称存储在wb.Workbook.WBProps.CodeName中。默认情况下Excel将会设置成ThisWorkbook或者是一个翻译的短语比如DieseArbeitsmappe。工作表和图表的编码名称在工作表属性对象的wb.Workbook.Sheets[i].CodeName中。宏数据表和对话数据表会被忽略。 读取函数和写入函数会保护编码名称,但是当在一个不同的工作簿内增加一个VBA blob时,编码名称必须被手动设置。 宏数据表 (点击显示) 老版本的Excel也支持非VBA的宏数据表表格类型,宏数据表存储了一些自动命令。他们暴露在!type设置成"macro"的对象中。 检测工作簿内宏指令 (点击显示) 如果宏指令存在,那么`vbaraw`字段就可以被设置,所以测试简单: function wb_has_macro(wb/*:workbook*/)/*:boolean*/ { if(!!wb.vbaraw) return true; const sheets = wb.SheetNames.map((n) => wb.Sheets[n]); return sheets.some((ws) => !!ws && ws['!type']=='macro');}12345 解析选项导出的read 和 readFile函数接受选项参数:
输入类型字符串能用很多种方式解释。read的type参数告诉库如何解析数据参数:
猜测文件类型实现细节 (点击显示详情) Excel和其他的电子数据表格工具读取前几个字节并且应用试探法确定稳定类型。这个支持文件类型的双关:用.xls扩展的重命名文件会告诉你的电脑使用Excel打开文件而且Excel知道如何去处理它。这个库应用了相似的逻辑:
DBF文件会基于前几个字节以及第三个和第四个字节进行检测(对应于文件日期的月和天)。 纯文本格式的猜测遵循下面的优先级顺序:
为什么随机的文本文件合法? (点击显示详情) Excel在读取文件方面非常积极。添加一个XLS 扩展到任意的显示文件,让Excel认为该文件可能是一个CSV或者是TSV文件,即使它仅仅是一列!这个库尝试去复制那样的行为。 最好的方法是去校验想要得到的工作表并且确保它有期待的行数或列数。提取范围非常简单: var range = XLSX.utils.decode_range(worksheet['!ref']);var ncols = range.e.c - range.s.c + 1, nrows = range.e.r - range.s.r + 1;12 写入选项导出的write 和 writeFile函数接受一个选型参数:
支持的输出格式与第三方工具的广泛兼容性,这个库支持很多种输出格式。明确的文件类型被bookType选项控制:
输出类型write函数的type参数备份read函数的type参数:
工具函数sheet_to_*函数接受一张工作表以及一个可选的选项对象。 XXX| A | B | C | D | E | F | G | ---+---+---+---+---+---+---+---+ 1 | S | h | e | e | t | J | S | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |12345 数组的数组输入XLSX.utils.aoa_to_sheet获取JS值数组的数组,并且返回一个工作表寻找输入数据。Numbers,Booleans和Strings都被存储为相应的样式。Date被存储为date或者是numbers。跳过数组孔和显式“未定义”值。null值可能被剔除。所有其它值存储为字符串。函数获取选项参数:
例子 (点击显示) 生成实例表: var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split(""), [1,2,3,4,5,6,7], [2,3,4,5,6,7,8]]);12345 XLSX.utils.sheet_add_aoa获取JS值的数组的数组,并且更新一个已存在的工作表对象。它遵循和aoa_to_sheet一样的过程,并且接受一个选项参数:
origin应该是以下之一:
示例 (点击显示) 考虑工作表: XXX| A | B | C | D | E | F | G | ---+---+---+---+---+---+---+---+ 1 | S | h | e | e | t | J | S | 2 | 1 | 2 | | | 5 | 6 | 7 | 3 | 2 | 3 | | | 6 | 7 | 8 | 4 | 3 | 4 | | | 7 | 8 | 9 | 5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |1234567 此工作表可按照顺序A1:G1, A2:B4, E2:G4, A5:G5构建: /* Initial row */var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]);/* Write data starting at A2 */XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});/* Write data starting at E2 */XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});/* Append row */XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});1234567891011 对象数组输入XLSX.utils.json_to_sheet获取对象数组并且返回一张基于对象自动生成"headers"的工作表。默认的列顺序由第一次出现的字段决定,这些字段通过使用Object.keys得到,不过可以使用选项参数覆盖。
示例 (点击显示) 原始的表单不能以明显的方法复制,因为JS对象的keys必须是独一无二的。之后用e_1 和 S_1替换第二个e 和 S。 var ws = XLSX.utils.json_to_sheet([ { S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 }, { S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 }], {header:["S","h","e","e_1","t","J","S_1"]});1234 或者可以跳过header行: var ws = XLSX.utils.json_to_sheet([ { A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" }, { A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 }, { A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 }], {header:["A","B","C","D","E","F","G"], skipHeader:true});12345 XLSX.utils.sheet_add_json获取一个对象数组,并且更新一个已存在的工作表对象。与json_to_sheet一样有相同的过程,并且接受一个选项参数:
origin应该是以下之一:
例子 (点击展示) 考虑工作表: XXX| A | B | C | D | E | F | G | ---+---+---+---+---+---+---+---+ 1 | S | h | e | e | t | J | S | 2 | 1 | 2 | | | 5 | 6 | 7 | 3 | 2 | 3 | | | 6 | 7 | 8 | 4 | 3 | 4 | | | 7 | 8 | 9 | 5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |1234567 工作表能够以A1:G1, A2:B4, E2:G4, A5:G5顺序构建: /* Initial row */var ws = XLSX.utils.json_to_sheet([ { A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" }], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true});/* Write data starting at A2 */XLSX.utils.sheet_add_json(ws, [ { A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 }], {skipHeader: true, origin: "A2"});/* Write data starting at E2 */XLSX.utils.sheet_add_json(ws, [ { A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 }], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]});/* Append row */XLSX.utils.sheet_add_json(ws, [ { A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 }], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1});12345678910111213141516171819 HTML Table 输入XLSX.utils.table_to_sheet获取一个table DOM元素,并且返回一个工作表寻找输入的table。Numbers会被解析。所有的数据将会被存储为字符串。 XLSX.utils.table_to_book基于工作表会产生一个最小的工作簿。 两个函数接受选项参数:
例子 (点击显示) 生成示例表单,以HTML table开始: <table id="sheetjs"><tr><td>S</td><td>h</td><td>e</td><td>e</td><td>t</td><td>J</td><td>S</td></tr><tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr><tr><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td></tr></table>12345 处理表格: var tbl = document.getElementById('sheetjs');var wb = XLSX.utils.table_to_book(tbl);12 注意:XLSX.read能够处理表示为字符串的HTML。 公式输出XLSX.utils.sheet_to_formulae生成一个命令数组,命令显示了一个人会怎样进入一个应用。每一个入口都是表格A1-cell-address=formula-or-value。字符串文字以"`"为前缀,符合Excel。 例子 (点击显示) 示例表: > var o = XLSX.utils.sheet_to_formulae(ws);> [o[0], o[5], o[10], o[15], o[20]];[ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ]123 定界分隔符输出作为一个writeFile CSV 类型的替代,XLSX.utils.sheet_to_csv也会产生CSV输出。这个函数获取一个选项参数:
例子 (点击显示) 示例表: > console.log(XLSX.utils.sheet_to_csv(ws));S,h,e,e,t,J,S1,2,3,4,5,6,72,3,4,5,6,7,8> console.log(XLSX.utils.sheet_to_csv(ws, {FS:"\t"}));S h e e t J S1 2 3 4 5 6 72 3 4 5 6 7 8> console.log(XLSX.utils.sheet_to_csv(ws,{FS:":",RS:"|"}));S:h:e:e:t:J:S|1:2:3:4:5:6:7|2:3:4:5:6:7:8|12345678910 #### UTF-16 Unicode 文本txt输出类型使用tab字符作为字段分隔符。如果codepage可用(包含全部的分发但不是核心),输出将会被编码为CP1200并且BOM会被预置。 XLSX.utils.sheet_to_txt获取和sheet_to_csv一样的参数。 HTML 输出作为’ writeFile ’ HTML类型的替代,XLSX.utils.sheet_to_html也会生成HTML输出。这个函数接受一个选项参数:
例子 (点击显示) 示例表格: > console.log(XLSX.utils.sheet_to_html(ws));// ...12 JSONXLSX.utils.sheet_to_json生成不同类型的JS对象。这个函数接受一个选项参数:
range是以下之一:
header是以下之一:
如果header不为1,行对象将会包含不可枚举的属性``rowNum`,这个属性代表与条目相对应的工作表的行。 示例 (点击显示) 示例表: > XLSX.utils.sheet_to_json(ws);[ { S: 1, h: 2, e: 3, e_1: 4, t: 5, J: 6, S_1: 7 }, { S: 2, h: 3, e: 4, e_1: 5, t: 6, J: 7, S_1: 8 } ]> XLSX.utils.sheet_to_json(ws, {header:"A"});[ { A: 'S', B: 'h', C: 'e', D: 'e', E: 't', F: 'J', G: 'S' }, { A: '1', B: '2', C: '3', D: '4', E: '5', F: '6', G: '7' }, { A: '2', B: '3', C: '4', D: '5', E: '6', F: '7', G: '8' } ]> XLSX.utils.sheet_to_json(ws, {header:["A","E","I","O","U","6","9"]});[ { '6': 'J', '9': 'S', A: 'S', E: 'h', I: 'e', O: 'e', U: 't' }, { '6': '6', '9': '7', A: '1', E: '2', I: '3', O: '4', U: '5' }, { '6': '7', '9': '8', A: '2', E: '3', I: '4', O: '5', U: '6' } ]> XLSX.utils.sheet_to_json(ws, {header:1});[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], [ '1', '2', '3', '4', '5', '6', '7' ], [ '2', '3', '4', '5', '6', '7', '8' ] ]123456789101112131415161718 展示row效果的例子: > ws['A2'].w = "3"; // set A2 formatted string value> XLSX.utils.sheet_to_json(ws, {header:1, raw:false});[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], [ '3', '2', '3', '4', '5', '6', '7' ], // <-- A2 uses the formatted string [ '2', '3', '4', '5', '6', '7', '8' ] ]> XLSX.utils.sheet_to_json(ws, {header:1});[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], [ 1, 2, 3, 4, 5, 6, 7 ], // <-- A2 uses the raw value [ 2, 3, 4, 5, 6, 7, 8 ] ]1234567891011 文件格式虽然库的名称是xlsx,不过它支持多种电子表格文件格式:
不会写入给定文件格式不支持的功能。具有范围限制的格式将会被静默截断:
Excel 2003 电子表格的范围限制被Excel的版本控制,并且不会写入函数强制执行。 Excel 2007+ XML (XLSX/XLSM)(点击显示) XlSX和XLSM文件是ZIP容器包含的与开源打包约定(Open Packaging Conventions, OPC)一致的一系列文件。大多数XLSM格式与XLSX相同,被用作文件包含宏命令。 这个格式在ECMA-376以及随后的ISO/IEC 29500都进行了标准化。Excel没有加遵循这个规范,并且还有其他文件讨论Excel如何偏离规范。 Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)(点击显示) BIFF 2/3 XLS是二进制记录的单表流。Excel 4介绍了工作簿的原理,除了有单表的XLS格式。结构与Lotus 1-2-3文件格式非常相似。BIFF5/8/12用了多种方式扩展格式,不过很大程度上保持了相同的记录格式。 对于这些格式没有官方的规范。Excel 95在这些格式里面可以写入文件,因此记录的长度以及字段都是由所有支持的格式以及比较文件决定。Excel 2016可以生成BIFF5文件,从XLSX或BIFF2开始启用全套文件测试。 Excel 97-2004 Binary (BIFF8)(点击显示) BIFF8仅仅使用混合的文件二进制容器格式,将一些内容放在文件的流内。在它的核心,它将会使用来自BIFF的老版本的二进制记录格式的扩展版本。 MS-XLS规范覆盖了文件格式的基础,并且其他的规范扩展了属性(如特性)的规范化。 Excel 2003-2004 (SpreadsheetML)(点击显示) 在XLSX之前,SpreadsheetML文件是简单的XML文件。没有官方的并且全面的的规范,虽然MS对于这种格式有发布的文档。因此Excel 2016 生成了电子表格文件,映射功能非常简单。 Excel 2007+ Binary (XLSB, BIFF12)(点击显示) XLSB格式与XLSX并行引入,将BIFF架构与内容分离和XLSX的ZIP容器相结合。XLSX子文件的大部分节点能用一个相应的子文件映射到XLSB记录中去。 MS-XLSB规范包含了文件格式的基础,并且其他的规范扩展了属性(如特性)的序列化。 定界分隔符的值 (CSV/TXT)(点击显示) Excel CSV在许多重要的方法上背离了RFC4180。生成的CSV文件通常应该运行在Excel内,但是他们不能运行RFC4180兼容的读取器中。解析器通常理解Excel CSV。如果值不可用,写入器会为公式主动生成单元格。 Excel TXT 使用tab作为分隔符,编码页1200。 注意:
其他工作簿格式(点击显示) 对其他格式的支持通常远远超出XLS / XLSB / XLSX支持,这在很大程度上是由于缺乏公开可用的文档。文件通常是在各自的应用内产生,并且会与他们的导出文件相比较以确定结构。主要的关注点是数据提出。 Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)(点击显示) Lotus格式由与BIFF结构相似的二进制记录组成。Lotus几十年前发布了一份包含原始WK1格式的规范。通过生成文件和与Excel支持进行比较来推断其他功能。 Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW)(点击显示) Quattro Pro格式使用与BIFF和Lotus一样的二进制记录。一些较新的格式(命名为WB3 和 QPW)使用像BIFF8 XLS一样的CFB附件。 OpenDocument Spreadsheet(开放文档格式的电子表格) (ODS/FODS)(点击显示) ODS是一种类似于XLSX的XML-in-ZIP格式,而FODS是一种类似于SpreadsheetML的XML格式。两种格式都在OASIS标准中进行了详细的说明,不过像LO/OO工具被添加到了未公开的扩展中。解析器和编写器并没有实现全部的标准,反而重点实现了提取和存储行数据中重要的部分。 Uniform Office Spreadsheet(统一办公电子表格) (UOS1/2)(点击显示) UOS是一种非常相似的格式,并且它有2个变种,分别对应ODS和FODS。大多数情况下,格式之间的区别是标签和属性的名称。 Other Single-Worksheet Formats(其他单一工作表格式)大多数较老的浏览器仅支持一种工作表: dBASE and Visual FoxPro (DBF)(点击显示) DBF实际上是一种类型化的表格格式:每一列只能保存一种数据类型,并且每条记录忽略类型信息。解析器生成标题行并且在工作表的第二行开始插入记录。编写器让文件和Visual FoxPro兼容。 多文件的扩展,比如内部示例和表格,目前不支持,会被在web浏览器中读取任意文件的普通能力所限制。读取器理解DBF level 7的扩展,比如DATETIME。 Symbolic Link(符号链接) (SYLK)(点击显示) 没有真正的文档。通过各种版本的Excel中保存文件来收集所有知识,以推断出字段的含义。注意:
Lotus Formatted Text (PRN)(点击显示) 没有真正的文档。事实上Excel把PRN视为一种只能输出的文件格式。然而我们能够猜测列宽并且反向还原原始布局。Excel 240个字符宽度的限制不会被强制执行。 Data Interchange Format(数据交换格式) (DIF)(点击显示) 没有统一标准的定义。 Visicalc DIF与Lotus DIF不同,并且两者都与Excel DIF不一样。在不明确的情况下,解析器/编写器遵循Excel中的预期行为。特别地,Excel以不兼容的方式扩展DIF:
HTML(点击显示) Excel HTML工作表包含以样式编码的特殊元数据。例如`mso-number-format`是一个包含数字格式的本地化字符串。尽管元数据的输出是有效的HTML,但是他不接受空的`&`符号。 编写器通过t标签添加类型元数据到TD元素中去。解析器检查这些标签,并且覆盖默认的解释。例如文本<td>12345</td>将会被解析成数字,不过<td t="s">12345</td>将会被解析成文本。 Rich Text Format(富文本格式) (RTF)(点击显示) 当复制工作表内的单元格或者范围时,Excel RTF工作表会被存储在剪贴板内。支持的编码是单词RTF支持的一个子集。 Ethercalc Record Format (ETH)(点击显示) Ethercalc是一种开源的web电子表格,由记录格式驱动,让人联想到包含在MIME多部分消息中的SYLK。 测试Node(点击显示) `make test`将会运行node基础的测试。默认情况下,它以各种支持的格式对文件运行测试。要测试一种指定的文件类型,设置`FMTS`为你想要测试的类型。使用`make test_misc`可以获得指定功能的测试。 $ make test_misc # run core tests$ make test # run full tests$ make test_xls # only use the XLS test files$ make test_xlsx # only use the XLSX test files$ make test_xlsb # only use the XLSB test files$ make test_xml # only use the XML test files$ make test_ods # only use the ODS test files1234567 要想启用所有的错误,请设置环境变量WTF=1: $ make test # run full tests$ WTF=1 make test # enable all error messages12 flow and eslint checks are available: $ make lint # eslint checks$ make flow # make lint + Flow checking$ make tslint # check TS definitions123 浏览器(点击显示) 核心浏览器内测试可在此repo中的`tests/index.html`中找到。启动一个本地服务器并且导航到那个目录去运行测试。`make ctestserv`将会在8080端口启动一个服务。 make ctest将生成浏览器装置。要添加更多的文件,编辑tests/fixtures.lst并且添加路径。 要运行完整的浏览器内测试,从oss.sheetjs.com克隆这个repo,并且替换xlsx.js文件(然后打开一个浏览器窗口跳转到stress.html)。 $ cp xlsx.js ../SheetJS.github.io $ cd ../SheetJS.github.io $ simplehttpserver # or "python -mSimpleHTTPServer" or "serve"$ open -a Chromium.app http://localhost:8000/stress.html1234 测试环境(点击显示)
测试使用mocha测试框架。Travis-CI 和 Sauce Labs 链接:
Travis-CI测试组合也包括用于多种时区的测试。改变本地的时区,设置TZ环境可用: $ env TZ="Asia/Kolkata" WTF=1 make test_misc1 测试文件测试文件被封装在另一个仓库。 运行make init将会刷新test_files子模块并获取子模块的文件。注意这个可能需要svn, git, hg以及其它可能不可用的命令。如果make init失败,请从仓库下载测试文件快照的最新版本。 最新快照 (点击显示) 最新的测试文件快照: (下载并解压到test_files子目录) 贡献由于开放规范承诺的不稳定性,确保代码是洁净室非常重要。贡献记录 文件组织 (点击显示) 在最高级别,最终脚本是`bits`文件夹中各个文件的串联。运行`make`应该在所有平台上重现最终输出。同样,README被分成了`docbits`文件夹中的位。 文件夹:
克隆仓库之后,运行make help将会显示一个命令列表。 OSX/Linux(点击显示) xlsx.js文件由来自于bits子目录的文件构建。构建脚本(运行make)将会连接各个位来产生脚本。提交一个贡献之前,确保运行将会准确地产生xlsx.js文件。测试的最简单方式就是添加下面的脚本: $ git add xlsx.js $ make clean $ make$ git diff xlsx.js1234 运行make dist产生dist文件。每一个版本中的dist文件都会被更新,并且不应该在版本之间提交。 Windows(点击显示) 包含make.cmd的脚本将会从bits目录中构建xlsx.js。构建很简单: > make1 准备开发环境: > make init1 windows中可用命令的完整列表显示在make help中: make init -- 安装依赖和全局模块 make lint -- 运行 eslint linter make test -- 运行mocha测试组合 make misc -- 运行更小的测试组合 make book -- 重新构建README 和 summary make help -- 显示命令信息123456 与测试文件中解释的一样,在windows中发布ZIP文件必须要下载和提取。如果Bash在windows内可用,可能会运行 OSX/Linux工作流。下面额步骤准备环境: # Install support programs for the build and test commandssudo apt-get install make git subversion mercurial# Install nodejs and NPM within the WSLwget -qO- https://deb.nodesource.com/setup_8.x | sudo bashsudo apt-get install nodejs# Install dev dependenciessudo npm install -g mocha voc blanket xlsjs123456789 测试(点击显示) `test_misc`(Linux/OSX用`make test_misc`/windows用`make misc`)目标运行定向的功能测试。执行功能测试需要5-10秒而无需对整个测试电池进行测试。新功能应附带相关文件格式和功能的测试。 对于涉及读取端的测试,一个合适的功能测试会包括读取一个存在的文件并且检查工作簿对象的结果。如果涉及参数,文件应该读取不同的值以确保功能如预期所料工作。 对于涉及已经可以解析的新写入功能的测试,恰当的功能测试包括用这个功能写入工作簿,在之后打开并确认功能已经被保存。 对于涉及没有现有读取能力的新写入功能的测试,请添加功能测试到kitchen sinktests/write.js。 证书更多细节请查阅相关的证书。原始作者保留未由Apache 2.0许可证明确授予的所有权利。 引用OSP覆盖的规格(OSP-covered Specifications) (点击显示)
|
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com