说实话 公司 闲着很无聊 不知道干嘛 写写博客记录一下
一、环境搭建
环境搭建暂时不多说本人是使用自己的简易脚手架搭建的,与excel无关的代码很多,建议大家还是使用自己搭建的脚手架好一点。这是我的github项目地址掘金Demo。自行百度
create-react-app
等官方推荐的脚手架吧。这里只对excel核心功能进行讲解。
二、excel导入
1.新建tsx文件
其实本人不太熟悉ts,所以对于tsx就当做乐呵乐呵。空有ts的后缀,实际上是js(语法)。总共就一个页面,页面地址tsx文件。
2.引用antd部分组件
为了简洁大方明了 我们这里直接引用了antd的部分组件
import { Button,Table,Upload } from 'antd';
<Upload {...uploadProps}>
<Button type="primary" >Excel导入</Button>
</Upload>
<Button type="primary" onClick={this.handleExportAll}>Excel导出数据</Button>
<Button type="primary" onClick={this.handleExportDocument}>Excel导出格式文件</Button>
<Table columns={columns} dataSource={data} bordered></Table>
3.核心插件xlsx
介绍
1.安装
npm install xlsx --save-dev
2.使用api介绍
1.XLSX.read(data,type)
尝试解析data数据 解析的类型
2.workbook.Sheets[workbook.SheetNames[0]]
是工作簿中的工作表的有序列表
3.XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });
将工作簿对象转换为JSON对象数组
更多api可查看 xlsx git 官网
3.导入实现
1.首先react render部分写入antd组件
/*组件部分*/
<Upload {...uploadProps}>
<Button type="primary" >Excel导入</Button>
</Upload>
/*js部分*/
const uploadProps={
onRemove: file => {
this.setState(state => ({
data:[],
fileList:[]
}));
},
accept: ".xls,.xlsx,application/vnd.ms-excel",
beforeUpload: (file) => {
const _this=this;
const f = file;
const reader = new FileReader();
reader.onload = function (e) {
const datas = e.target.result;
const workbook = XLSX.read(datas, {
type: 'binary'
});//尝试解析datas
const first_worksheet = workbook.Sheets[workbook.SheetNames[0]];//是工作簿中的工作表的有序列表
const jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });//将工作簿对象转换为JSON对象数组
_this.handleImpotedJson(jsonArr, file);
};
reader.readAsBinaryString(f);
return false;
},
fileList,
};
onRemove
是当移除文件时触发的操作,这里的操作就是清除数据。accept
是接受上传的文件类型。beforeUpload
是上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传,此处只是进行数据的转化,没有真实上传。fileList
是文件列表。
更多api请看antd upload官网
2.核心代码理解
总共就那么几行
const f = file;
const reader = new FileReader();
reader.onload = function (e) {
const datas = e.target.result;
const workbook = XLSX.read(datas, {
type: 'binary'
});//尝试解析datas
const first_worksheet = workbook.Sheets[workbook.SheetNames[0]];//是工作簿中的工作表的有序列表
const jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });//将工作簿对象转换为JSON对象数组
_this.handleImpotedJson(jsonArr, file);
};
reader.readAsBinaryString(f);
1 .首先FileReader对象实例化一个file对象
2 .在file对象onload事件里进行处理
3 .使用XLSX.read解析data
4 .first_worksheet是解析的数据
5 .XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });将工作簿对象转化为JSON对象
6 .handleImpotedJson方法可以将json对象进行一系列操作 转化到表格里
handleImpotedJson = (array, file) => {
const header = array[0];//头部数据 ["姓名",...]
const entozh = this.formatTitleOrFileld('title', 'dataIndex');//将表字段数组形式转化为对象形式,如:{"姓名":"name",...}
const firstRow = header.map(item => entozh[item]);//可以获取到行属性 ["name",...]
const newArray = [...array];
newArray.splice(0, 1);//去除表头
const json = newArray.map((item, index) => {
const newitem = {};
item.forEach((im, i) => {
const newKey = firstRow[i] || i;
newitem[newKey] = im
})
return newitem;
});//将存在表头定义字段的值赋值
const formatData = json.map(item => ({
name: item.name,
age: item.age,
address: item.address,
}))//筛选出自己需要的属性
this.setState({ data: formatData, fileList: [file] });
return formatData;
}
formatTitleOrFileld = (a, b) => {
const entozh = {};
this.state.columns.forEach(item => {
entozh[item[a]] = item[b]
})
return entozh;
}
3.效果图
三、excel导出
1.excel导出表格数据
1.先上代码
<Button type="primary" onClick={this.handleExportAll}>Excel导出数据</Button>
handleExportAll = (e) => {
const entozh = {
"name":"姓名",
"age":"年龄",
"address":"地址"
}
const nowdata = this.state.data;
const json = nowdata.map((item) => {
return Object.keys(item).reduce((newData, key) => {
const newKey = entozh[key] || key
newData[newKey] = item[key]
return newData
}, {})
});
const sheet = XLSX.utils.json_to_sheet(json);
this.openDownloadDialog(this.sheet2blob(sheet,undefined), `全部信息.xlsx`);
}
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);
}
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;
}
2.核心代码讲解
1.XLSX.utils.json_to_sheet
字面意思,可以将工作簿对象转化为json对象
2.openDownloadDialog
此方法创建了a标签 利用a标签的download属性进行下载文件
3.sheet2blob
可以将工作簿对象转化为我们需要的
3.效果图
2.表格导出标准格式文件
其实和上面一样 唯独把表头数据保存下来就行唯一的区别就是
let nowdata = [
{"name":""},
{"age":""},
{"address":""},
];
将state中的data对象转化为空数组形式即可。
有不懂的可以加我微信询问我