前端实现excel(csv)文件导入导出
js-xlsx是一款非常方便的只需要纯JS即可读取和导出excel的工具库,功能强大,支持格式众多,支持xls、xlsx、ods(一种OpenOffice专有表格文件格式)等十几种格式。本文全部都是以xlsx格式为例。
SheetJS/sheetjsgithub.com![046913aba092fa713c89b7a7761e095a.png](https://img-blog.csdnimg.cn/img_convert/046913aba092fa713c89b7a7761e095a.png)
一、兼容性
几乎兼容所有浏览器,满足不同需求,如图所示:
![069ba4c0c2525133420cdb1d576773f6.png](https://img-blog.csdnimg.cn/img_convert/069ba4c0c2525133420cdb1d576773f6.png)
二、转化图解
转化的基本流程:
![90f6977c8c73fd4c53b27da371540ec5.png](https://img-blog.csdnimg.cn/img_convert/90f6977c8c73fd4c53b27da371540ec5.png)
三、安装及使用
安装
npm install xlsx --save-dev
or,一般情况下用xlsx.core.min.js就够了,xlsx.full.min.js则是包含了所有功能模块
<script type="text/javascript" src="./js/xlsx.core.min.js"></script>
使用
import XLSX from 'xlsx'
四、excel解读
我们创建一个excel会经历一下过程:
- 创建一个工作薄
- 创建一个sheet
- 创建表格行列等
所以我们用js-xlsx创建excel同样的道理
- 创建工作薄(WorkBook)
- 创建sheet(WorkBook.Sheet)
- 创建表格行列(WorkBook.sheet[])
五、读取excel
读取excel主要是通过 XLSX.read(data, {type: type})
方法来实现,返回一个叫WorkBook的对象,type主要取值如下:
base64: 以base64方式读取; binary: BinaryString格式(byte n is data.charCodeAt(n)) string: UTF8编码的字符串; buffer: nodejs Buffer; array: Uint8Array,8位无符号数组; file: 文件的路径(仅nodejs下支持);
- 读取本地excel文件
- 读取excel文件转化wookbook对象
// 读取本地excel文件
function readWorkbookFromLocalFile(file, callback) {
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
// 读取二进制的excel
var workbook = XLSX.read(data, {type: 'binary'});
if(callback) callback(workbook);
};
reader.readAsBinaryString(file);
}
// 读取远程文件
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();
}
六、WorkBook对象
来看读取文件后的wb对象
可以看到,SheetNames里面保存了所有的sheet名字,然后Sheets则保存了每个sheet的具体内容(我们称之为Sheet Object)。每一个sheet是通过类似A1这样的键值保存每个单元格的内容,我们称之为单元格对象(Cell Object)
![dd2c5cf256b922f8d1e94e96d0b4ab0b.png](https://img-blog.csdnimg.cn/img_convert/dd2c5cf256b922f8d1e94e96d0b4ab0b.png)
七、Sheet Object
sheet['!ref']:表示所有单元格的范围,例如从A1到F8则记录为A1:F8;
sheet[!merges]:存放一些单元格合并信息,是一个数组,每个数组由包含s和e构成的对象组成,s表示开始,e表示结束,r表示行,c表示列;
等等
![ec45e7b9442bf7b7c00a5c5ad143fcbe.png](https://img-blog.csdnimg.cn/img_convert/ec45e7b9442bf7b7c00a5c5ad143fcbe.png)
结果如下:
![de38987236f3f8cf9bffa8e056d720da.png](https://img-blog.csdnimg.cn/img_convert/de38987236f3f8cf9bffa8e056d720da.png)
八、XLSX.utils常用导出类型
XLSX对象
![7201c74a0777bc3f2c72acba242b3ffc.png](https://img-blog.csdnimg.cn/img_convert/7201c74a0777bc3f2c72acba242b3ffc.png)
常用的主要是:
- XLSX.utils.sheet_to_csv:生成CSV格式
- XLSX.utils.sheet_to_txt:生成纯文本格式
- XLSX.utils.sheet_to_html:生成HTML格式
- XLSX.utils.sheet_to_json:输出JSON格式
![2c5ba9a0e8136f03776d0bd9117523a5.png](https://img-blog.csdnimg.cn/img_convert/2c5ba9a0e8136f03776d0bd9117523a5.png)
九、excel导出
首先介绍三个方法:
XLSX.utils.aoa_to_sheet: 这个工具类最强大也最实用了,将一个二维数组转成sheet,会自动处理number、string、boolean、date等类型数据;
XLSX.utils.table_to_sheet: 将一个table dom直接转成sheet,会自动识别colspan和rowspan并将其转成对应的单元格合并;
XLSX.utils.json_to_sheet: 将一个由对象组成的数组转成sheet;
以json_to_sheet为例这里介绍一下如何导出excel
- 创建一个工作薄
let wb = XLSX.utils.book_new()
- 创建sheet对象
// 一个简单的sheet
let sheetData = [
{ department: '行政部', count: 2 },
{ department: '技术部', count: 2 }
]
let sheet = XLSX.utils.json_to_sheet(sheetData)
- 如果有合并单元格
sheet['!merges'] = [
{
e: { c: 0, r: 1 }, // 合并结束位置 c:列位置 r:表示行位置
s: { c: 0, r: 0 } // 合并开始位置
}
]
- 如果多个sheetData
XLSX.utils.book_append_sheet(wb, sheet2, sheetName)
XLSX.utils.book_append_sheet(wb, sheet3, sheetName)
...
...
- 转化格式,导出文件
// 创建工作薄blob
const workbookBlob = workbook2blob(wb)
// 导出工作薄
openDownloadDialog(workbookBlob, fn)
附上最后两个方法源码:
// 将workbook装化成blob对象
function workbook2blob(workbook) {
// 生成excel的配置项
var wopts = {
// 要生成的文件类型
bookType: 'xlsx',
// 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
bookSST: false,
// 二进制类型
type: 'binary'
}
var wbout = XLSX.write(workbook, wopts)
var blob = new Blob([s2ab(wbout)], {
type: 'application/octet-stream'
})
return blob
}
// 将字符串转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
}
// 将blob对象创建bloburl,然后用a标签实现弹出下载框
function openDownloadDialog(blob, fileName) {
if (typeof blob == 'object' && blob instanceof Blob) {
blob = URL.createObjectURL(blob) // 创建blob地址
}
var aLink = document.createElement('a')
aLink.href = blob
// HTML5新增的属性,指定保存文件名,可以不要后缀,注意,有时候 file:///模式下不会生效
aLink.download = fileName || ''
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)
URL.revokeObjectURL(blob)
}