前端导出 excel ,设置字体,列宽,行高,对其方式,合并单元格等效果
一、先看实现后的图
二、技术
这个表格主要采用了 xlsx-style 来实现
https://www.npmjs.com/package/xlsx-style
https://github.com/protobi/js-xlsx/tree/beta
三、入门
由于 npm 和 git 上的文档都是英文,看过一遍之后就不想再看了,所以这里做一个记录。
xlsx-style 是一个纯 javascript 实现的读取和生成 excel 的 npm 包。
xlsx-style 来源于 SheetJs/xlsx,并在其非付费版上添加了很多功能,其中最主要的功能是设置 excel 的样式。
PS: 土豪就不用看了,直接使用 SheetJs/xlsx 的付费版 : )
如果大家在使用过程中有任何问题,可以去这里看看或者提交。
1、支持的文件类型
-
支持读取的文件类型
- Excel 2007+ XML Formats (XLSX/XLSM)
- Excel 2007+ Binary Format (XLSB)
- Excel 2003-2004 XML Format (XML “SpreadsheetML”)
- Excel 97-2004 (XLS BIFF8)
- Excel 5.0/95 (XLS BIFF5)
- OpenDocument Spreadsheet (ODS)
-
支持生成的文件类型
- XLSX
- CSV (and general DSV)
- JSON and JS objects (various styles)
2、兼容
支持 ES5 的浏览器,如果是比较老的浏览器,需要引入 polyfill
3、安装
npm安装:
npm install xlsx-style --save
浏览器中使用:
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
// 只有核心包
<script lang="javascript" src="dist/xlsx.full.min.js"></script>
// 包括依赖包
CDN直接引入:
http://cdnjs.com/libraries/xlsx
4、读取文件
在 node 中使用
if(typeof require !== 'undefined')
XLSX = require('xlsx')
var workbook = XLSX.readFile('test.xlsx');
/* DO SOMETHING WITH workbook HERE */
ajax 获取 excel
var url = "test_files/formula_stress_test_ajax.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.onload = function(e) {
var arraybuffer = oReq.response;
var data = new Uint8Array(arraybuffer);
var arr = new Array();
for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
var workbook = XLSX.read(bstr, {type:"binary"});
/* DO SOMETHING WITH workbook HERE */
}
oReq.send();
H5 拖拽上传
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
var i, f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
/* if binary string, read with type 'binary' */
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
drop_dom_element.addEventListener('drop', handleDrop, false);
H5 input 上传
function handleFile(e) {
var files = e.target.files;
var i, f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
input_dom_element.addEventListener('change', handleFile, false);
⚠️
XLSX.read(data, read_opts) 是用来解析一段数据.
XLSX.readFile(filename, read_opts) 会从一个文件中解析一段数据.
4.1 read_opts
read_opts 是读取 excel 的选项,其可选的配置有如下几项:
key | 描述 | 默认值 |
---|---|---|
cellFormula | 将公式保存到 .f 字段上 | true |
cellHTML | 解析富文本并将 HTML 保存到 .h 字段 | true |
cellNF | 将数字格式的字符串保存到 .z 字段 | false |
cellStyles | 将样式/主题信息保存到 .s 字段 | false |
cellDates | 将日期存储为类型 d(默认类型为 n) | false |
sheetStubs | 为存根单元创建单元格对象 | false |
sheetRows | 如果 >0,则读取第一个 sheetRows 行 | 0 |
bookDeps | 如果为真,解析计算链 | false |
bookFiles | 如果为 true,则将原始文件添加到 book object | false |
bookProps | 如果为 true,则仅解析以获取书籍元数据 | false |
bookSheets | 如果为 true,则仅解析足以获取工作表名称 | false |
bookVBA | 如果为 true,则将 vbaProject.bin 暴露给 vbaraw 字段 | false |
password | 如果已定义且文件已加密,则保存密码 | - |
这里有一些需要注意的点不是很好翻译,为了避免歧义,我将原文放在下面
5、写入文件
在 node 中使用
if(typeof require !== 'undefined')
XLSX = require('xlsx')
XLSX.writeFile(workbook, 'out.xlsx');
利用 FileSaver.js 写入 binary
/* bookType can be 'xlsx' or 'xlsm' or 'xlsb' */
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
var wbout = XLSX.write(workbook,wopts);
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;
}
/* saveAs 函数会在本地机器上下载一个文件 */
saveAs(new Blob([s2ab(wbout)],{type:""}), "test.xlsx")
⚠️
XLSX.write(data, read_opts) 用来写一份 workbook.
XLSX.writeFile(filename, read_opts) 会将 workbook 写入文件.
6、单元格对象
在 excel 中,每一个单元格可以看作一个对象,用户可以填充原始数据,设置文本类型,背景色,边框,甚至可以绘图,使用富文本,数学公式,以及指定与其他单元格的关联等。
单元格的地址可以用 {c:C, r:R}
来表示,其中 C 代表第几列,R代表第几行
假如我们选择 B5 这个单元格,该怎么表示呢?
{c:1, r:4}
//第一列第四行
这是因为列和行默认都从 0 开始计数,而 A、B、C、D…Z… 字母占据了第 0 行 ,1、2、3、4…则占据了第 0 列
6.1 单元格属性
属性 | 描述 |
---|---|
v | 原始数据 |
w | 格式化的文本 |
t | 单元格文本类型:b Boolean, n Number, e Error, s String, d Date |
f | 公式 |
r | 富文本编码 |
h | 富文本的HTML |
c | 与单元格关联的注释 |
z | 与单元格关联的数字格式的字符串(已废弃) |
l | 单元格超链接,.Target holds link, .tooltip is tooltip |
s | 单元格具体的样式设置 |
⚠️:默认的导出(比如导出csv)读取的是 w ,如果想更改值,可以在导出前delete cell.w
或者cell.w=undefined
6.2 单元格样式
上一节中说到cell.s
用来设置单元格的样式。
在 xlsx-style 中,单元格样式共有五个顶级的属性,分别是:fill
, font
, numFmt
, alignment
和 border
。
顶级属性 | 子属性 | 描述 | 类型或可选值 | 默认值 |
---|---|---|---|---|
fill | patternType | 填充模式 | “solid” or “none” | - |
fgColor | 前景色 | COLOR_SPEC | - | |
bgColor | 背景色 | COLOR_SPEC | { indexed: 64} | |
font | name | 字体名称 | string | “Calibri” |
sz | 字体大小 | number | 12 | |
color | 字体颜色 | COLOR_SPEC | - | |
bold | 加粗 | boolean | - | |
underline | 下划线 | boolean | - | |
italic | 斜体 | boolean | - | |
strike | 瞄边 | boolean | - | |
outline | 轮廓 | boolean | - | |
shadow | 阴影 | boolean | - | |
vertAlign | 垂直对齐 | boolean | - | |
numFmt | - | 数字格式化 | “0” // 内置格式的整数索引 "0.00%" // 匹配内置格式的字符串,见下文 "0.0%" // 格式化为自定义格式的字符串 "0.00%;\(0.00%\);\-;@" // 格式化的时候转义特殊字符 "m/dd/yy" // 格式化为日期 | - |
alignment | vertical | 垂直对齐 | “bottom”、“center”、“top” | - |
horizontal | 水平对齐 | “left”、“center”、“right” | - | |
wrapText | 换行 | boolean | - | |
readingOrder | 文字方向 | 1、2 // for right-to-left | - | |
textRotation | 旋转 | Number from 0 to 180 or 255 | 0 | |
border | top | 上边框 | { style: BORDER_STYLE, color: COLOR_SPEC } | - |
bottom | 下边框 | { style: BORDER_STYLE, color: COLOR_SPEC } | - | |
left | 左边框 | { style: BORDER_STYLE, color: COLOR_SPEC } | - | |
right | 右边框 | { style: BORDER_STYLE, color: COLOR_SPEC } | - | |
diagonal | 对角线 | { style: BORDER_STYLE, color: COLOR_SPEC } | - | |
diagonalUp | 上对角线 | boolean | - | |
diagonalDown | 下对角线 | boolean | - |
6.2.1 COLOR_SPEC
COLOR_SPEC用于实现字体、边框以及填充的颜色,可以选择以下几种写法:
- { auto: 1} // 指定自动值
- { rgb: “FFFFAA00” } // 指定十六进制 ARGB 值
- { theme: “1”, tint: “-0.25”} 指定主题颜色的整数索引和色调值 (默认为 0)
- { indexed: 64} // fill.bgColor 的默认值
6.2.2 BORDER_STYLE
border_style 用于指定边框的样式,excel中边框样式有很多种,其中的可选值为:
- thin
- medium
- thick
- dotted
- hair
- dashed
- mediumDashed
- dashDot
- mediumDashDot
- dashDotDot
- mediumDashDotDot
- slantDashDot
6.2.3 numFmt 的内置选项
代码里内置了一些格式化选项,用户可以通过索引,或者值的形式来选定
var table_fmt = {
0: 'General',
1: '0',
2: '0.00',
3: '#,##0',
4: '#,##0.00',
9: '0%',
10: '0.00%',
11: '0.00E+00',
12: '# ?/?',
13: '# ??/??',
14: 'm/d/yy',
15: 'd-mmm-yy',
16: 'd-mmm',
17: 'mmm-yy',
18: 'h:mm AM/PM',
19: 'h:mm:ss AM/PM',
20: 'h:mm',
21: 'h:mm:ss',
22: 'm/d/yy h:mm',
37: '#,##0 ;(#,##0)',
38: '#,##0 ;[Red](#,##0)',
39: '#,##0.00;(#,##0.00)',
40: '#,##0.00;[Red](#,##0.00)',
45: 'mm:ss',
46: '[h]:mm:ss',
47: 'mmss.0',
48: '##0.0E+0',
49: '@',
56: '"上午/下午 "hh"時"mm"分"ss"秒 "',
65535: 'General'
};
7、Worksheet 对象
Worksheet对象指代当前的 excel 表,其中包含了一些当前表的设置选项,比如:合并单元格、渲染区域、列宽、打印头等信息。
Worksheet 对象的所有属性都要以 !
开头
key | 描述 | 示例 |
---|---|---|
!ref | excel的渲染区域 | “A1: E12” |
!cols | 设置列宽 | [{hpx: 40}] |
!rows | 设置行高 | [{hpx: 40}] |
!merges | 合并单元格 | {s:{c:0, r:2}, e:{c:1, r:6}} |
!printHeader | 打印的时候要重复的行,比如 table 的表头信息 | [1:1] // 重复第一行 |
页眉页脚以及分页在文档上没有看到相关的信息, 可能目前还不支持。
后续如果有任何补充,我会及时更新
四、demo
github 上的 xlsx-style 如果不支持设置行高,或者需要 demo 代码的请到这里下载。