官网地址:

mirrors / rockboom / sheetjs-docs-zh-cn · GitCode

安装

在浏览器里使用,增加一个script标签:

<script lang="javascript" src="dist/xlsx.full.min.js"></script>

使用CDN (点击显示详情)

CDNURL
unpkgUNPKG - xlsx
jsDelivrxlsx CDN by jsDelivr - A CDN for npm and GitHub
CDNjsxlsx - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers
packdhttps://bundle.run/xlsx@latest?name=XLSX

unpkg提供最新的版本:

<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>

使用 npm:

$ npm install xlsx

使用 bower:

$ bower install js-xlsx

JS生态示例

示例 目录 包括了一些简单的项目:

框架和APIS

打包工具

集成平台

可选模块

可选特点 (点击显示详情) node版本自动要求模块提供其他的特性。某些模块的文件相当大而且仅在一些特殊的场景下才会用到,因此不应该把他们当做核心部分一起加载。在浏览器中用到这些模块时,可以用下面的方式进行加载:

<!-- international support from js-codepage -->
<script src="dist/cpexcel.js"></script>

每一个依赖合适的版本可以放在 dist/directory 目录下。 完整的单文件版本在 dist/xlsx.full.min.js 文件里面。 默认情况下,Webpack和Browserify构建包含可选的模块。可以通过配置Webpack移除对 resolve.alias 的支持:

  /* uncomment the lines below to remove support */
  resolve: {
    alias: { "./dist/cpexcel.js": "" } // <-- omit international support
  }

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>

shim.min.js也包括了在IE6-9中用于加载和保存文件的 IE_LoadFileIE_SaveFile。对于适用于Photoshop和其它的Adobe产品的格式,xlsx.extendscript.js脚本会绑定shim。

原理

原理 (点击显示详情) 在SheetJS之前,处理电子表格文件的接口只能用于特定的格式。许多第三方库要么支持一种格式,要么为每一种支持的文件类型提供一个不同的类集。虽然在Excel 2007里面引入了XLSB,但只有Sheet和Excel支持这种格式。

为了提高不可知格式的显示,js-xlsx使用了被称作["Common Spreadsheet Format"]的纯JS的显示方法(#common-spreadsheet-format)。强调一种统一的显示方式,能够有一些特点,比如格式转换和嵌套class tap。通过提取出各种格式的复杂性,工具没有必要担心特定的文件类型。

一个简单的的对象显示和细心的代码练习相结合,能让示例运行在较老的浏览器以及像ExtendScriptWeb 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 */

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 */

一个网页里面的多张表可以被转换成单个的工作表。

/* 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 */

另一种选择,HTML代码也可以被提取和解析。

var htmlstr = document.getElementById('tableau').outerHTML;
var workbook = XLSX.read(htmlstr, {type:'string'});

浏览器下载文件(ajax) (点击显示详情) 注意:对于运行在老版浏览器里更完整的例子,请查看示例 。xhr示例包含`XMLHttpRequest` 和 `fetch`更多的例子。

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();

浏览器拖拽 (点击显示详情) 拖拽使用了HTML5 的 `FileReader` API,加载数据时使用`readAsBinaryString` 或 `readAsArrayBuffer`。但并不是所有的浏览器都支持全部的 `FileReader` API,因此非常推荐动态的特性检测。

var rABS = true; // true: readAsBinaryString ; false: readAsArrayBuffer
function 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);

浏览器通过form元素上传文件 (点击显示详情)

来自file input元素的数据能够被和拖拽例子中相同的FileReaderAPI处理。

var rABS = true; // true: readAsBinaryString ; false: readAsArrayBuffer
function 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);

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);
  });
}

使用像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);
  });
}

使用工作簿

完整的对象格式会在本文件的后面部分进行介绍。

读取指定的单元格 (点击显示详情)

这个例子提取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);

在工作簿中增加新的工作表 (点击显示详情)

例子中使用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);

从头开始创建工作簿 (点击显示详情)

工作簿对象包含一个SheetNames名称数组和一个Sheets对象,用来将表名映射到表对象。XLSX.utils.book_new工具函数创建一个新的工作簿对象:

/* create a new blank workbook */
var wb = XLSX.utils.book_new();

新的工作簿是空白的而且不包含工作表。如果工作簿,那么写入函数将会出错。

解析和编写示例

node安装一个能够读取电子数据表和输出各种格式的命令行工具 xlsx。源码可以在 bin 目录下的xlsx.njs里面找到。

XLSX.utils中的一些辅助函数会生成不同的工作表视图。

  • XLSX.utils.sheet_to_csv 生成CSV文件
  • XLSX.utils.sheet_to_txt 生成UTF16的格式化文本
  • XLSX.utils.sheet_to_html 生成HTML
  • XLSX.utils.sheet_to_json 生成一个对象数组
  • XLSX.utils.sheet_to_formulae 生成一张公示列表

编写工作簿

对编写而言,第一步是生成导出数据。辅助函数writewriteFile将会生成各种适合分发的数据格式。第二步是和端点实际的共享数据。假设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 */

Photoshop ExtendScript 写入文件 (点击显示详情)

writeFileFile包裹在 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 */

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

浏览器上传文件(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 name
formdata.append('data', wbout); // <-- `data` holds the base64-encoded data
req.send(formdata);

浏览器保存文件 (点击显示详情)

XLSX.writeFile 包含了一些用于触发文件保存的方法。

  • URL浏览器API为文件创建一个URL对象,通过创建a标签并给他添加click事件就可以使用URL对象。现代浏览器都支持这个方法。
  • msSaveBlob是IE10及IE10以上用来触发文件保存的API。
  • 对于Windows XP 和 Windows 7里面的IE6和IE6以上的以上浏览器,IE_FileSave 使用 VBScript 和 ActiveX 来写入文件。s补充程序(shim)必须包含在包含的HTML页面中。

并没有标准的方法判断是否真实的文件已经被下载了。

/* output format determined by filename */
XLSX.writeFile(workbook, 'out.xlsb');
/* at this point, out.xlsb will have been downloaded */

浏览器保存文件(兼容性) (点击显示详情)

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");

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'
});

oldie示例展示了IE向后兼容的场景。

included demos包含了移动app和其他专门的部署。

写入示例

流式写入

XLSX.stream对象中可以使用流式写入函数。流式函数像普通的函数一样传入相同的参数,不过返回一个可读流。但是他们只暴露在Nodejs中。

  • XLSX.stream.to_csvXLSX.utils.sheet_to_csv的流式版本。
  • XLSX.stream.to_htmlXLSX.utils.sheet_to_html的流式版本。
  • XLSX.stream.to_jsonXLSX.utils.sheet_to_json的流式版本。

nodejs转换成CSV并写入文件 (点击显示详情)

var output_file_name = "out.csv";
var stream = XLSX.stream.to_csv(worksheet);
stream.pipe(fs.createWriteStream(output_file_name));

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

GitHub - SheetJS/sheetaki: Spreadsheet CSV conversion microservice pips将可写流写入nodejs响应。

接口

XLSX是浏览器暴露出来可以使用的方法,导出到node中能够使用的XLSX.versionXLSX库的版本(通过构建脚本添加)。XLSX.SSF格式化库的嵌入版本。

解析函数

XLSX.read(data, read_opts) 用来解析数据 dataXLSX.readFile(filename, read_opts) 用来读取文件名 filename 并且解析。解析选项会在解析选项部分阐述。

写入函数

XLSX.write(wb, write_opts) 用来写入工作簿 wbXLSX.writeFile(wb, filename, write_opts)wb 写入到特定的文件 filename 中。如果是基于浏览器的环境,此函数会强制浏览器端下载。 XLSX.writeFileAsync(filename, wb, o, cb)wb 写入到特定的文件 filename 中。如果 o 被省略,写入函数会使用第三个参数作为回调函数。

XLSX.stream 包含一组流式写入函数的集合。

写入选项会在写入选项部分部分进行阐述。

工具

XLSX.utils对象中的工具函数都可以使用,工具函数在工具函数部分进行阐述。

导入:

  • aoa_to_sheet 把转换JS数据数组的数组为工作表。
  • json_to_sheet 把JS对象数组转换为工作表。
  • table_to_sheet 把DOM TABLE元素转换为工作表。
  • sheet_add_aoa 把JS数据数组的数组添加到已存在的工作表中。
  • sheet_add_json 把JS对象数组添加到已存在的工作表中。

导出:

  • sheet_to_json 把工作表转换为JS对象数组。
  • sheet_to_csv 生成分隔符隔开值的输出。
  • sheet_to_txt 生成UTF16格式化的文本。
  • sheet_to_html 生成HTML输出。
  • sheet_to_formulae 生成公式列表(带有值回退)。

单元格和单元格地址的操作:

  • format_cell 生成文本类型的单元格值(使用数字格式)。
  • encode_row / decode_row 在0索引行和1索引行之间转换。
  • encode_col / decode_col 在0索引列和列名之间转换。
  • encode_cell / decode_cell 转换单元格地址。
  • encode_range / decode_range 转换单元格的范围。

常用的数据表格式(Common Spreadsheet Format)

js-xlsx符合常用的数据表格式(CSF)。

一般结构

单元格地址对象的存储格式为{c:C, r:R},其中CR分别代表的是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);
  }
}

单元格对象

单元格对象是纯粹的JS对象,它的keys和values遵循下列的约定:

KeyDescription
v原始值(查看数据类型部分获取更多的信息)
w格式化文本(如果可以使用)
t内行: b Boolean, e Error, n Number, d Date, s Text, z Stub
f单元格公式编码为A1样式的字符串(如果可以使用)
F如果公式是数组公式,则包围数组的范围(如果可以使用)
r富文本编码 (如果可以使用)
h富文本渲染成HTML (如果可以使用)
c与单元格关联的注释
z与单元格关联的数字格式字符串(如果有必要)
l单元格的超链接对象 (.Target 长联接, .Tooltip 是提示消息)
s单元格的样式/主题 (如果可以使用)

如果w文本可以使用,内置的导出工具(比如CSV导出方法)就会使用它。要想改变单元格的值,在打算导出之前确保删除cell.w(或者设置 cell.wundefined)。工具函数会根据数字格式(cell.z)和原始值(如果可用)重新生成w文本。

真实的数组公式存储在数组范围中第一个单元个的f字段内。此范围内的其他单元格会省略f字段。

数据类型

原始值被存储在v值属性中,用来解释基于t类型的属性。这样的区别允许用于数字和数字类型文本的展示。下面有6种有效的单元格类型。

TypeDescription
bBoolean: 值可以理解为JS boolean
eError: 值是数字类型的编码,而且w属性存储共同的名称 **
nNumber: 值是JS number **
dDate: 值是 JS Date 对象或者是被解析为Date的字符串 **
sText: 值可以理解为 JS string 并且被写成文本 **
zStub: 被数据处理工具函数忽略的空白子单元格 **

Error 值以及含义 (点击显示详情)

ValueError 含义
0x00#NULL!
0x07#DIV/0!
0x0F#VALUE!
0x17#REF!
0x1D#NAME?
0x24#NUM!
0x2A#N/A
0x2B#GETTING_DATA

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-yySSF模块了解数字格式并进行适当的转换。

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)

数据表对象

每一个不以!开始的key都会映射到一个单元格(用A-1符合)。sheet[address] 返回指定地址的单元格对象。

指定的数据表属性(通过 sheet[key]访问, 每一个都以 !开始):

  • sheet['!ref']:A-1的范围是基于表示数据表的范围。操作数据表的函数应该使用这个参数来决定操作范围。此范围之外指定的单元格不会被处理。尤其是手动编写数据表时,范围之外的单元格不会被包含在其中。

处理数据表的函数应该对!ref的存在进行检测。如果!ref被忽略或者不是有效的范围,函数就可以吧数据表看做是空表或者尝试猜范围。词库附带的工具函数会将工作表视为空(例如CSV的输出是空字符串)。

当用sheetRows属性集读取工作表时,ref参数会使用限制的范围。最初的范围通过ws['!fullref']设置。

  • sheet['!margins']sheet['!margins']对象表示页面的边距。默认值遵循Excel的常规设置。Excel也有"wide"和"narrow"的设置,不过他们都被存储为原生的尺寸。主要的属性已在下表列出:

页面边距详情 (点击显示详情)

keydescription"normal""wide""narrow"
leftleft margin (inches)0.71.00.25
rightright margin (inches)0.71.00.25
toptop margin (inches)0.751.00.75
bottombottom margin (inches)0.751.00.75
headerheader margin (inches)0.30.50.3
footerfooter margin (inches)0.30.50.3
/* 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}

工作表对象

除了基本的数据表关键字之外,工作表还增加了下面的内容:

  • ws['!cols']:返回列属性对象的数组。实际上的列宽使用统一的方式存储在文件里,宽度的测量依据最大数字宽度(在像素中,最大的渲染宽度是数字0-9)。渲染时,列对象用wpx字段存储像素宽度,用wch存储字符宽度,用MDW字段存储最大数字宽度。

  • ws['!rows']: 返回行属性对象的数组,后面的文档会进行阐述。每一个行对象编码属性包括行高和能见度。

  • ws['!merges']: 返回与工作表中合并单元格相对应的范围对象的数组。纯文本格式不支持合并单元格。如果合并的单元格存在,CSV导出将会把所有的单元格写入合并范围,因此确保在合并的范围内只有第一个单元格(左上角的单元格)被设置。

  • ws['!protect']: 写入数据表保护属性的对象。password键为支持密码保护的数据表(XLSX/XLSB/XLS)指定密码。写入函数会使用XOR模糊方式。下面key控制数据表保护--数据表被锁定时设置key为false可以使用feature,或者设为true禁用feature。

工作表保护详情 (点击显示详情)

keyfeature (true=disabled / false=enabled)default
selectLockedCellsSelect locked cellsenabled
selectUnlockedCellsSelect unlocked cellsenabled
formatCellsFormat cellsdisabled
formatColumnsFormat columnsdisabled
formatRowsFormat rowsdisabled
insertColumnsInsert columnsdisabled
insertRowsInsert rowsdisabled
insertHyperlinksInsert hyperlinksdisabled
deleteColumnsDelete columnsdisabled
deleteRowsDelete rowsdisabled
sortSortdisabled
autoFilterFilterdisabled
pivotTablesUse PivotTable reportsdisabled
objectsEdit objectsenabled
scenariosEdit scenariosenabled
  • ws['!autofilter']: 自动筛选下面的模式:
type AutoFilter = {
  ref:string; // A-1 based range representing the AutoFilter table range
}

图表对象

图表会被显示为标准的数据表。要注意和!type被设置为"chart"的属性进行区分。

底层数据和!ref指的是图表中的缓存数据。 图表的第一行是底层标题。

宏对象

宏对象会被显示为标准的数据表。注意与!type设置为"macro"的属性进行区分。

对话框对象

对话框对象会被显示为标准的数据表。注意与!type设置为"dialog"的属性进行区分。

工作簿对象

workbook.SheetNames 是工作簿内工作表的有序列表。

wb.Sheets[sheetname] 返回一个表示工作表的对象。

wb.Props 是一个存储标准属性的对象。wb.Custprops 存储自定义的属性。因为XLS标准属性偏离了XLSX标准,所以XLS解析把核心的属性存储在两个属性中。

wb.Workbook 存储工作簿级别的特性.

工作簿文件属性

各种各样的文件格式为不同的文件属性使用不同的内置名称。工作簿的Props对象用来规范这些名称。

文件属性 (点击显示详情)

JS NameExcel Description
TitleSummary tab "Title"
SubjectSummary tab "Subject"
AuthorSummary tab "Author"
ManagerSummary tab "Manager"
CompanySummary tab "Company"
CategorySummary tab "Category"
KeywordsSummary tab "Keywords"
CommentsSummary tab "Comments"
LastAuthorStatistics tab "Last saved by"
CreatedDateStatistics tab "Created"

例如设置工作簿的title属性:

if(!wb.Props) wb.Props = {};
wb.Props.Title = "Insert Title Here";

自定义的属性会被添加到工作簿的Custom对象中:

if(!wb.Custprops) wb.Custprops = {};
wb.Custprops["Custom Property"] = "Custom Value";

写入函数将会处理选项对象的Props键:

/* force the Author to be "SheetJS" */
XLSX.write(wb, {Props:{Author:"SheetJS"}});

工作簿级别的特性

wb.Workbook 存储工作簿级别的特性。

定义名称

wb.Workbook.Names 是一个定义名称对象的数组,这些名称对象都有键:

定义名称属性 (点击显示)

KeyDescription
Sheet名称的范围。 数据表的索引 (0 = 第一章张数据表) 或null (工作簿)
Name区分大小写的名称。 标准的规则应用**
RefA1单元格样式的引用 ("Sheet1!$A$1:$D$20")
Comment注释 (只适用于XLS/XLSX/XLSB)

Excel 允许两个表格范围定义的名称共享相同的名称。但是一个表格范围的名称不能和一个工作簿范围的名称相冲突。工作簿写入函数不强制这样的约束。

工作簿视图

wb.Workbook.Views 是一个工作簿视图对象数组,这些视图对象有keys。

KeyDescription
RTL如果值为true,从左到右的显示

混合的工作簿属性

KeyDescription
CodeNameVBA Project Workbook Code Name
date1904时间: 0/false 表示1900系统时间, 1/true 表示1904系统时间
filterPrivacy警告或去除存储的个人验证信息

文档特点

即使是想存储数据这样的基本特点,官方的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' }
}

共享的公式会被解压缩,并且每一个单元格都有相应的公式。编写器通常不会尝试去生成共享公式。

有公式记录但是没有值的单元格会被序列化,序列化的方式能够被Excel和其他电子表格工具将会识别。这个代码库将不会自动计算公式结果!例如去计算工作表中的BESSELJ

没有已知值的公式 (点击显示详情)

{
  "!ref": "A1:A3",
  A1: { t:'n', v:3.14159 },
  A2: { t:'n', v:2 },
  A3: { t:'n', f:'BESSELJ(A1,A2)' }
}

数组公式

数组公式被存储在数组块左上角的单元格内。一个数组公式的所有单元格都会有于该范围对应的F字段。一个单一的单元格公式要注意于F字段所存储的纯公式进行区分。

数组公式示例 (点击显示详情)

例如设置单元格C1为数组公式{=SUM(A1:A3*B1:B3)}

worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };

对于多个单元格的数组公式,每一个单元格都有相同的数组范围,不过只有第一个单元格指定公式。考虑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" };

工具函数和编写器被用来检查F字段的存在,并且忽略单元格内任何可能的公式元素f,这些单元格并不包含起始单元格。这些操作函数并不会被要求执行公式的校验。

公式输出工具函数 (点击显示详情)

sheet_to_formulae方法生成为每个公式或者是数组公式生成一行。数组公式被渲染在range=formula的表格内,而纯单元格被渲染在cell=formula or value的表格内。注意字符串的迭代会有前缀符号',与Excel公式栏显示的一致。

公式文件格式细节 (点击显示详情)

Storage RepresentationFormatsReadWrite
A1-style stringsXLSX
RC-style stringsXLML and plain text
BIFF Parsed formulaeXLSB and all XLS formats
OpenFormula formulaeODS/FODS/UOS

因为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
};

为什么有三种宽度类型? (点击显示详情) 有三种不同的宽度类型对应于电子数据表存储列宽的三种不同方式。

SYLK和其他的纯文本格式使用原生的字符计算。像Visicalc和Multiplan这样的同时期的工具是基于字符的。因为字符有相同的宽度,足以存储一个计数。这样的传统也延续到了BIFF格式。

SpreadsheetML (2003) 尝试通过标准化整个文件中的屏幕像素计数来与HTML对齐。列宽、行高以及其他的测量使用像素。当像素和字符数量不一致时,Excel四舍五入结果。

XLSX内部用一个模糊的"最大数位宽度"表存储列宽。最大数字宽度是渲染时最大数字的宽度,通常字符"0"是最宽的。内部的宽度必须是宽度除以256的整数倍。ECMA-376介绍了一个公式用于像素和内部宽度之间的转换。这代表一种混合的方式。

读取函数尝试去填充全部的三种属性。写函数努力尝试将指定值循环到所需类型。为了阻止潜在的冲突。首先操作应该要删除其他的属性。列入,当改变像素宽度时,删除wchwidth属性。

执行细节 (点击显示详情)

给出的这些约束可能决定了MDW没有检查字体!解析器通过从宽度转换为像素并返回来猜测像素宽度,重复所有可能的MDW并选择最小化村务的MDW。XLML实际上存储额像素宽度,所以猜想会在相反的方向运行。

即使所有的信息都是可用的,也会期望写入函数遵循下面的优先级顺序:

  1. 如果 width 字段可用,优先使用width
  2. 如果 wpx 字段可用,请使用wpx
  3. 如果 wch 字段可用,请使用wch

行属性

如果!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
};

注意:Excel UI显示基本大纲级别为1,最大级别为8level字段存储基本大纲级别为0,最大级别为7

实现细节 (点击展示详情)

Excel内部以点为单位存储行高。默认的分辨率是72DPI或者是96DPI,所以像素和点的大小应该相同。不同的分辨率他们可能不同,因此库分开了这些概念:

即使所有的信息都可用,写入函数也应该遵循下面的优先级顺序: 1)如果hpx可用,就使用 hpx像素高度。 2) 如果hpx可用,就使用 hpx像素高度。

数字格式

对于每一个单元格而言,cell.w的文本来自于cell.vcell.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
    }
  }
}

这些规则和Excel如何显示自定义的数字格式稍微有些区别。特别是文字字符必须必包含在双引号里面或者在反斜杠之前。更多信息,查看Excel文档Create or delete a custom number format 或者是ECMA-376 18.8.31(数字格式)。

默认的数字格式 (点击展示详情)

ECMA-376 18.8.30里列出的默认格式:

IDFormat
0General
10
20.00
3#,##0
4#,##0.00
90%
100.00%
110.00E+00
12# ?/?
13# ??/??
14m/d/yy (see below)
15d-mmm-yy
16d-mmm
17mmm-yy
18h:mm AM/PM
19h:mm:ss AM/PM
20h:mm
21h:mm:ss
22m/d/yy h:mm
37#,##0 ;(#,##0)
38#,##0 ;[Red](#,##0)
39#,##0.00;(#,##0.00)
40#,##0.00;[Red](#,##0.00)
45mm:ss
46[h]:mm:ss
47mmss.0
48##0.0E+0
49@

格式14(m/d/yy)被Excel本地化:即使文件指明了数字格式,也会根据系统设置用不同的方式绘制。当文件的的生产者和使用者都在相同的区域时这会很有用,不过对于网络上的例子就会不同。为了避免歧义,解析函数接受dateNF选项覆盖指定格式字符串的解释。

超链接

超链接存储在单元格对象的l关键字内。超链接对象的Target字段是连接目标,包括了URI片段。工具提示被存储在Tooltip字段内,当移动鼠标到文字上方就会显示。

例如下方的片段在单元格A3内创建了一个指向SheetJS - Home的链接,提示信息是"Find us @ SheetJS.com!"

ws['A3'].l = { Target:"http://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" };

注意Excel并不会自动为超链接添加样式--他们通常会向普通文本一样显示。

如果链接的目标是一个单元格或者是范围又或者是在相同的工作簿内定义名字("Internal Links"),那么链接的开头会有一个哈希字符标识:

ws['A2'].l = { Target:"#E2" }; /* link to cell E2 */

单元格注释

单元格注释是对象,被存储在单元格对象的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!"});

注意: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"});

数据表能见度

Excel支持将表格隐藏在更低的标签栏。表格数据存储文件内,但是UI不容易让它可以使用。标准的隐藏表格会被显示在"Unhide"菜单内。Excel也有"very hidden"表格,这些表格不能被显示在菜单内。只可以通过Vb编辑器访问。

能见度的设置被存储在表格属性数组的Hidden属性当中。

更多细节 (点击显示详情)

ValueDefinition
0Visible
1Hidden
2Very 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 ] ]

非Excel格式不支持"Very Hidden"状态。测试一个数据比哦啊是否可见的最好方式是检查是否Hidden属性为逻辑truth:

> wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] })
[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]

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');
}

解析选项

导出的readreadFile函数接受选项参数:

Option NameDefaultDescription
type输入数据编码 (查看下方的输入类型)
rawfalse如果为true,纯文本解析不会解析值 **
codepage如果指定, 合适的时候使用编码页面**
cellFormulatrue保存公式到f字段
cellHTMLtrue解析富文本并把HTML保存到.h 字段
cellNFfalse把数字格式的字符串保存到 .z 字段
cellStylesfalse把样式/主题保存到 .s 字段
cellTexttrue生成格式化文本.w 字段
cellDatesfalse把日期存储为类型 d (默认是 n)
dateNF如果指定,使用代码日期14的字符串 **
sheetStubsfalse为子单元格创建z类型的单元格对象
sheetRows0如果sheetRows的值 >0, 读取第一个sheetRows 行 **
bookDepsfalse值为true,解析计算链
bookFilesfalse如果值为true, 添加原始文件到工作簿对象 **
bookPropsfalse如果值为true, 只有足够的解析才能得到工作簿的元数据**
bookSheetsfalse如果值为true,只有足够的解析才能得到表格名称
bookVBAfalse如果值为true,复制 VBA blob 到 vbaraw 字段 **
password""如果定义了密码并且文件已经加密,就会使用密码 **
WTFfalse如果值为true, 对意外的文件特性抛出错误 **
  • 虽然cellNF为false,但是格式化的文本也会被生成并且保存到.w字段。
  • 在一些情况下,即使bookSheets为false,数据表也可能被解析。
  • Excel积极尝试从CSV和其他纯文本中解释值。这会导致意外的行为!raw选项抑制值解析。
  • bookSheetsbookProps 结合起来提供两套信息集合。
  • Deps将会是一个空对象,如果bookDeps为false。
  • bookFiles的行为依赖于文件类型:
    • keys 数组(ZIP里面的路径)用于基于ZIP基础的格式
    • files哈希(将路径映射到表示文件的的对象)用于ZIP
    • cfb对象用于使用CFB容器的格式
  • sheetRows-1将会在查看JSON对象输出时生成(因为解析数据时,数据头行会被计算成一行)
  • bookVBA仅仅在xl/vbaProject.bin展示原始的VBA CFB对象。不解析数据。XLSM 和 XLSB把VBA CFB对象存储在xl/vbaProject.bin。BIFF8 XLS将VBA条目与核心工作簿条目混合在一起,因此库从XLS CFB容器生成了一个新的XLSB兼容blob。
  • codepage用于没有CodePage记录的BIFF2 - BIFF5文件以及在type:"binary"内没有BOM的CSV文件。
  • 目前仅支持XOR加密。当文件使用其他的加密方法时会抛出不支持的错误。
  • WTF主要用于发展。默认情况下,单一的工作表内,解析器将会抑制读取错误,允许你从解析正确的工作表内读取。设置WTF:1强制这些错误被抛出。

输入类型

字符串能用很多种方式解释。readtype参数告诉库如何解析数据参数:

typeexpected input
"base64"字符串: 文件的Base64编码
"binary"字符串: 二进制字符串 (字节 ndata.charCodeAt(n))
"string"字符串: JS字符串 (字符被解释为UTF8)
"buffer"nodejs Buffer
"array"数组: 8位的无符号型整数数组 (字节 ndata[n])
"file"字符串: 将要被读取的文件的路径 (只在nodejs中可用)

猜测文件类型

实现细节 (点击显示详情)

Excel和其他的电子数据表格工具读取前几个字节并且应用试探法确定稳定类型。这个支持文件类型的双关:用.xls扩展的重命名文件会告诉你的电脑使用Excel打开文件而且Excel知道如何去处理它。这个库应用了相似的逻辑:

Byte 0Raw File TypeSpreadsheet Types
0xD0CFB ContainerBIFF 5/8 or password-protected XLSX/XLSB or WQ3/QPW
0x09BIFF StreamBIFF 2/3/4/5
0x3CXML/HTMLSpreadsheetML / Flat ODS / UOS1 / HTML / plain text
0x50ZIP ArchiveXLSB or XLSX/M or ODS or UOS2 or plain text
0x49Plain TextSYLK or plain text
0x54Plain TextDIF or plain text
0xEFUTF8 EncodedSpreadsheetML / Flat ODS / UOS1 / HTML / plain text
0xFFUTF16 EncodedSpreadsheetML / Flat ODS / UOS1 / HTML / plain text
0x00Record StreamLotus WK* or Quattro Pro or plain text
0x7BPlain textRTF or plain text
0x0APlain textSpreadsheetML / Flat ODS / UOS1 / HTML / plain text
0x0DPlain textSpreadsheetML / Flat ODS / UOS1 / HTML / plain text
0x20Plain textSpreadsheetML / Flat ODS / UOS1 / HTML / plain text

DBF文件会基于前几个字节以及第三个和第四个字节进行检测(对应于文件日期的月和天)。

纯文本格式的猜测遵循下面的优先级顺序:

FormatTest
XML<?xml 出现在前1024个字符
HTML<开头并且HTML标签出现在前1024个字符 *
XML<开头
RTF{\rt开头
DSV/sep=.$/开头,分隔符是指定的字符串
DSV前1024个字符中未引用的";" 字符比 "\t" 或者 ","
TSV前1024个字符中未引用的"\t"字符比 ","
CSV前1024个字符中的一个是逗号","
ETHsocialcalc:version:开头
PRN(默认)
  • HTML 标签包括:html, table, head, meta, script, style, div

为什么随机的文本文件合法? (点击显示详情) 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;

写入选项

导出的writewriteFile函数接受一个选型参数:

Option NameDefaultDescription
type输出数据编码(查看下面的输出类型)
cellDatesfalse把字节存储为类型d (默认是 n)
bookSSTfalse生成共享的字符串表格 **
bookType"xlsx"工作簿的类型 (查看下方支持的格式)
sheet""单页格式的工作表名称 **
compressionfalse基于ZIP的格式使用ZIP压缩 **
Props写入时覆盖工作簿的属性 **
themeXLSX写入XLSX/XLSB/XLSM时,覆盖主题XML **
ignoreECtrue禁止"数字作为文本"错误 **
  • bookSST 较慢并且有更多的内存密集型,不过与iOS数字老版本有更好的兼容性。
  • 原始数据时唯一保证存储的东西。在README文件中没有描述的功能可能无法序列化。
  • cellDates 仅用于XLSX输出并且不能保证与第三方读取器一起工作。Excel自身不经常用类型d编写单元格,因此非Excel工具会忽视数据或者是有日期错误。
  • Props是一个备份工作簿Props字段的对象。从工作簿文件属性 部分查看表格。
  • 如果指定,来自themeXLSX的字符串会被存储为XLSX/XLSB/XLSM文件的基本主题(ZIP中的xl / theme / theme1.xml)。
  • 由于在程序中有一个bug,一些功能比如"分列"会在忽略错误条件的工作表上使Excel崩溃。默认情况下写入函数将会标记文件忽略错误。设置ignoreECfalse来禁止。

支持的输出格式

与第三方工具的广泛兼容性,这个库支持很多种输出格式。明确的文件类型被bookType选项控制:

bookTypefile extcontainersheetsDescription
xlsx.xlsxZIPmultiExcel 2007+ XML Format(XML 格式)
xlsm.xlsmZIPmultiExcel 2007+ Macro XML Format(宏 XML 格式)
xlsb.xlsbZIPmultiExcel 2007+ Binary Format(二进制格式)
biff8.xlsCFBmultiExcel 97-2004 Worksheet Format(工作簿格式)
biff5.xlsCFBmultiExcel 5.0/95 Worksheet Format(工作簿格式)
biff2.xlsnonesingleExcel 2.0 Worksheet Format(工作簿格式)
xlml.xlsnonemultiExcel 2003-2004 (SpreadsheetML)
ods.odsZIPmultiOpenDocument Spreadsheet(开放文档格式的电子表格)
fods.fodsnonemultiFlat OpenDocument Spreadsheet(平滑的开放文档格式的电子表格)
csv.csvnonesingleComma Separated Values(逗号分隔值)
txt.txtnonesingleUTF-16 Unicode Text (TXT)
sylk.sylknonesingleSymbolic Link (SYLK)
html.htmlnonesingleHTML Document
dif.difnonesingleData Interchange Format (DIF) (数据交换格式)
dbf.dbfnonesingledBASE II + VFP Extensions (DBF)(dBASE II + VFP扩展)
rtf.rtfnonesingleRich Text Format (RTF)
prn.prnnonesingleLotus Formatted Text(Lotus格式化文本。)
eth.ethnonesingleEthercalc Record Format (ETH)(Ethercalc记录格式)
  • compression仅用于带ZIP容器的格式。
  • 格式只支持需要sheet选型指明工作表的单表。如果字符串为空,就会使用第一张工作表。
  • 如果bookType未指定值,那么writeFile会自动根据文件扩展名来猜测输出文件格式。他就会在上表中选择匹配扩展名的第一个格式。

输出类型

write函数的type参数备份read函数的type参数:

typeoutput
"base64"字符串: 文件的Base64编码
"binary"字符串: 二进制字符串 (字节 ndata.charCodeAt(n))
"string"字符串: JS 字符串 (字符被解释成UTF8)
"buffer"nodejs Buffer
"array"ArrayBuffer, 8位无符号整数的回退数组
"file"字符串: 将要创建的文件的地址(仅用于nodejs)

工具函数

sheet_to_*函数接受一张工作表以及一个可选的选项对象。 *_to_sheet函数接受一个数据对象以及一个可选的选项对象。 示例都是基于下面的工作表:

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 |

数组的数组输入

XLSX.utils.aoa_to_sheet获取JS值数组的数组,并且返回一个工作表寻找输入数据。Numbers,Booleans和Strings都被存储为相应的样式。Date被存储为date或者是numbers。跳过数组孔和显式“未定义”值。null值可能被剔除。所有其它值存储为字符串。函数获取选项参数:

Option NameDefaultDescription
dateNFFMT 14字符串输出使用特定的日期格式
cellDatesfalse存储日期为类型 d (默认是 n)
sheetStubsfalsenull值创建类型为z的单元格对象

例子 (点击显示) 生成实例表:

var ws = XLSX.utils.aoa_to_sheet([
  "SheetJS".split(""),
  [1,2,3,4,5,6,7],
  [2,3,4,5,6,7,8]
]);

XLSX.utils.sheet_add_aoa获取JS值的数组的数组,并且更新一个已存在的工作表对象。它遵循和aoa_to_sheet一样的过程,并且接受一个选项参数:

Option NameDefaultDescription
dateNFFMT 14字符串输出使用指定的日期格式
cellDatesfalse存储日期为类型 d (默认是 n)
sheetStubsfalsenull值创建类型为z的单元格对象
origin只用指定的单元格作为指定的起点 (查看下表)

origin应该是以下之一:

originDescription
(cell object)使用指定的单元格 (单元格对象)
(string)使用指定的单元格 (A1样式的单元格)
(number >= 0)从指定行的第一列开始 (0索引)
-1从第一列开始添加到工作表底部
(default)从单元格A1开始

示例 (点击显示)

考虑工作表:

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 |

此工作表可按照顺序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});

对象数组输入

XLSX.utils.json_to_sheet获取对象数组并且返回一张基于对象自动生成"headers"的工作表。默认的列顺序由第一次出现的字段决定,这些字段通过使用Object.keys得到,不过可以使用选项参数覆盖。

Option NameDefaultDescription
header使用指定的列顺序 (默认 Object.keys)
dateNFFMT 14字符串输出使用指定的日期格式
cellDatesfalse存储日期为类型 d (默认是 n)
skipHeaderfalse如果值为true, 输出不包含header行

示例 (点击显示)

原始的表单不能以明显的方法复制,因为JS对象的keys必须是独一无二的。之后用e_1S_1替换第二个eS

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"]});

或者可以跳过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});

XLSX.utils.sheet_add_json获取一个对象数组,并且更新一个已存在的工作表对象。与json_to_sheet一样有相同的过程,并且接受一个选项参数:

Option NameDefaultDescription
header使用指定的列排序 (默认 Object.keys)
dateNFFMT 14字符串输出使用指定的日期格式
cellDatesfalse把存储日期为类型 d (默认是 n)
skipHeaderfalse如果值为true, 输出不包含header行
origin使用指定的单元格作为起点 (查看下方表格)

origin应该是以下之一:

originDescription
(cell object)使用指定的单元格(单元格对象)
(string)使用指定的单元格 (A1样式的单元格)
(number >= 0)从指定行的第一列开始(0索引)
-1从第一列开始添加到工作表底部
(default)从单元格A1开始

例子 (点击展示) 考虑工作表:

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 |

工作表能够以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});

HTML Table 输入

XLSX.utils.table_to_sheet获取一个table DOM元素,并且返回一个工作表寻找输入的table。Numbers会被解析。所有的数据将会被存储为字符串。

XLSX.utils.table_to_book基于工作表会产生一个最小的工作簿。

两个函数接受选项参数:

Option NameDefaultDescription
raw如果值为true, 每一个单元格将会保存原始的字符串
dateNFFMT 14字符串输出使用指定的日期格式
cellDatesfalse把日期存储为类型 d (默认是 n)
sheetRows0如果值 >0, 读取表格的第一个sheetRows
displayfalse如果值为true, 隐藏的行和单元格将不会被解析

例子 (点击显示)

生成示例表单,以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>

处理表格:

var tbl = document.getElementById('sheetjs');
var wb = XLSX.utils.table_to_book(tbl);

注意: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' ]

定界分隔符输出

作为一个writeFile CSV 类型的替代,XLSX.utils.sheet_to_csv也会产生CSV输出。这个函数获取一个选项参数:

Option NameDefaultDescription
FS",""字段分隔符"表示字段之间的分隔符
RS"\n""记录分隔符"表示行之间的分隔符
dateNFFMT 14字符串输出使用指定的日期格式
stripfalse删除每条记录中的尾随字段分隔符**
blankrowstrue包含CSV输出的空白行
skipHiddenfalse跳过CSV输出的隐藏行/列
  • strip将删除默认FS / RS下每行的尾随逗号 blankrows必须设置为false才能跳过空白行。

例子 (点击显示)

示例表:

> console.log(XLSX.utils.sheet_to_csv(ws));
S,h,e,e,t,J,S
1,2,3,4,5,6,7
2,3,4,5,6,7,8
> console.log(XLSX.utils.sheet_to_csv(ws, {FS:"\t"}));
S	h	e	e	t	J	S
1	2	3	4	5	6	7
2	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|

#### 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输出。这个函数接受一个选项参数:

Option NameDefaultDescription
idTABLE元素指定 id 特性
editablefalse如果值为true, 为每一个TD设置 contenteditable="true"
header覆盖 header (默认 html body)
footer覆盖 footer (默认 /body /html)

例子 (点击显示)

示例表格:

> console.log(XLSX.utils.sheet_to_html(ws));
// ...

JSON

XLSX.utils.sheet_to_json生成不同类型的JS对象。这个函数接受一个选项参数:

Option NameDefaultDescription
rawtrue使用原生值 (true) 或者格式化字符串 (false)
rangefrom WS覆盖 Range (查看下面的table)
header控制输出格式 (查看下面的table)
dateNFFMT 14字符串输出使用指定的日期格式
defval使用指定的值替代null或者undefined
blankrows**包含输出的空白行 **
  • raw只影响有格式编码(.z)字段或者格式化文本(.w)字段的单元格。
  • 如果header被指定,第一行就会被当做数据行;如果header未指定,第一行是header并且不作为数据。
  • 当header未指定时,转换将通过添加"_"和一个从"1"开始的计数自动消除标题条目的歧义。例如有三列的标题都是foo,那么输出字段是foo1foo_1foo_2
  • raw值为true时返回nullraw值为false会被跳过。
  • 如果defval没有指定,通常nullundefined会被跳过。如果defval有指定值,所有的nullundefined嗲都将会用defval填充。
  • header1时,默认生成空白行。blankrows必须设置为false来跳过空白行。
  • header不为1时,默认跳过空白行。blankrows必须设置为true来生成空白行。

range是以下之一:

rangeDescription
(number)使用工作表范围,但将起始行设置为值
(string)使用指定的范围 (A1类型的有界范围的字符串)
(default)使用工作表范围 (ws['!ref'])

header是以下之一:

headerDescription
1生成数组类型的数组 ("二维数组")
"A"行对象的键是文字的列标题
array of strings在行对象内使用指定的字符串作为键
(default)读取并消除第一行的歧义作为键

如果header不为1,行对象将会包含不可枚举的属性``rowNum`,这个属性代表与条目相对应的工作表的行。

Logo

前往低代码交流专区

更多推荐