有关於ExcelJS这个套件的教学与说明,请先看我的上一篇文章:
[前端/ES6] 实作汇出excel下载按钮的超好用套件:ExcelJS(上)- 基础介绍
这一篇呢,我们着重於在react中使用这个套件
以及要来发挥我们react的优点,把这个按钮包装成一个通用的 UI component
会特别写这篇的原因也主要是我自己一开始在查 「react export excel」、「react 汇出excel」
找到的文件我觉得不够详尽,而且没有一个现成的、包装好的UI可以使用
好啦,废话不多说,先来做一个最基础的范例吧!
让我们把上次的onClick function和react直接做一个简单的结合如下
react + 事件定义 (js版本)
线上 codesandbox Demo: 简易react + onClick范例
import React from "react";
import ExcelJs from "exceljs";
function ExportExcelButton (){
function onClick(){
const workbook = new ExcelJs.Workbook(); // 创建试算表档案
const sheet = workbook.addWorksheet('工作表范例1'); //在档案中新增工作表 参数放自订名称
sheet.addTable({ // 在工作表里面指定位置、格式并用columsn与rows属性填写内容
name: 'table名称', // 表格内看不到的,算是key值,让你之後想要针对这个table去做额外设定的时候,可以指定到这个table
ref: 'A1', // 从A1开始
columns: [{name:'名字'},{name:'年龄'},{name:'电话'}],
rows: [['小明','20','0987654321'],['小美','23','0912345678']]
});
// 表格里面的资料都填写完成之後,订出下载的callback function
// 异步的等待他处理完之後,创建url与连结,触发下载
workbook.xlsx.writeBuffer().then((content) => {
const link = document.createElement("a");
const blobData = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = '测试的试算表.xlsx';
link.href = URL.createObjectURL(blobData);
link.click();
});
}
return (
<button onClick={onClick}> 下载excel </button>
)
};
你会发现其实这个就是把那些上次的function直接复制过来
然後render 一个button ,按下後会触发
一样是按下之後,就会得到这样的档案
TS版本
(markdown好像没有支援TSX所以我只能先选typescript, 最後面return元件的语法颜色有点跑掉)
import React, { CSSProperties } from "react";
import ExcelJs from "exceljs";
export type SheetData = {
sheetName: string, // 工作表名称
thead: Array<string>, // 栏位标题,例如:['姓名','年龄','电话']
tbody: Array<Array<string>>,
// 内容,例如:[['小明','20','0987654321'],['小美','23','0912345678']]
columnWidths?: Array<{number: number, width: number}> //用来指定栏宽的
}
interface ExportExcelButtonProps {
fileName: string, // 档案名称
sheetDatas:Array<SheetData> , // 要汇出的表格资料
disabled?: boolean, // 是不是要禁止按钮动作
buttonRef?: React.MutableRefObject<any>, // 外面用useRef传进来
style?: CSSProperties // 按钮的style
}
export function ExportExcelButton (props: ExportExcelButtonProps){
function onClick(){
const workbook = new ExcelJs.Workbook();
props.sheetDatas.forEach((sheetData: SheetData)=>{
const sheet = workbook.addWorksheet(sheetData.sheetName);
sheet.addTable({
name: sheetData.sheetName,
ref: `A1`, // 从A1开始
headerRow: true,
columns: sheetData.thead.map((s)=>{ return {name: s}}),
rows: sheetData.tbody
});
if (sheetData.columnWidths) {
sheetData.columnWidths.forEach((column)=>{
sheet.getColumn(column.number).width = column.width
});
}
})
// 表格里面的资料都填写完成之後,订出下载的callback function
// 异步的等待他处理完之後,创建url与连结,触发下载
workbook.xlsx.writeBuffer().then((content: ExcelJs.Buffer) => {
const link = document.createElement("a");
const blob = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = `${props.fileName}.xlsx`;
link.href = URL.createObjectURL(blob);
link.click();
});
};
const style: CSSProperties = {
borderRadius: '5px',
...props.style
}
return (
<button
ref={props.buttonRef}
disabled={props.disabled}
onClick={onClick}
style={style}
>
汇出excel
</button>
)
};
export default ExportExcelButton;
JS版本
import React from "react";
import ExcelJs from "exceljs";
export function ExportExcelButton (props){
function onClick(){
const workbook = new ExcelJs.Workbook();
props.sheetDatas.forEach((sheetData)=>{
const sheet = workbook.addWorksheet(sheetData.sheetName);
sheet.addTable({
name: sheetData.sheetName,
ref: `A1`, // 从A1开始
headerRow: true,
columns: sheetData.thead.map((s)=>{ return {name: s}}),
rows: sheetData.tbody
});
if (sheetData.columnWidths) {
sheetData.columnWidths.forEach((column)=>{
sheet.getColumn(column.number).width = column.width
});
}
})
// 表格里面的资料都填写完成之後,订出下载的callback function
// 异步的等待他处理完之後,创建url与连结,触发下载
workbook.xlsx.writeBuffer().then((content) => {
const link = document.createElement("a");
const blob = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = `${props.fileName}.xlsx`;
link.href = URL.createObjectURL(blob);
link.click();
});
};
const style = {
borderRadius: '5px',
...props.style
}
return (
<button
ref={props.buttonRef}
disabled={props.disabled}
onClick={onClick}
style={style}
>
汇出excel
</button>
)
};
export default ExportExcelButton;
使用范例
import ExportExcelButton from "./ExportExcelButton";
function App(){
const downloadData = [
{
sheetName: `工作表1`,
thead: ['姓名','年龄','电话'],
tbody: [['小明','20','0987654321'],['小美','23','0912345678']],
columnWidths: [{number: 1, width:20},{number: 2, width:10},{number: 3, width:40}]
},
{
sheetName: `工作表2`,
thead: ['姓名','座号'],
tbody: [['小明','1'],['小美','2']],
columnWidths: [{number: 1, width:20}]
}
];
return (
<ExportExcelButton
fileName={'测试的试算表'}
sheetDatas={downloadData}
/>
)
}
如此一来,就可以将JSON格式的资料,转成excel下载
而且对component外来说,只要整理好格式,试算表里面就能够有好几张工作表
这边也一样提供以上的完整范例
线上codesandbox demo: TS component 、JS component
也欢迎大家根据这个示范,去准备自己的UI库
我个人是使用react搭配 nx 这套toolchain 来进行开发的
题外话提一下nx这套toolchain
他有好用的环境建置,能做应用整合、共用LIB、方便搭配jest、e2e等优点
创建应用之後会有设置production这个configurations,帮忙分出测试的打包配置与正式发布的配置
但事情就这麽发生了。
错误讯息:webpack.WebpackError is not a constructor
使用环境: 使用nx 这套toolchain 建置react专案
问题发生: import 这个套件之後,就发现build专案时,只要选择production 配置
就会执行失败,并喷出错误讯息: webpack.WebpackError is not a constructor
解决方式:
主要是引入该套件之後,会产生大量warning
而预设设定在webpack.json
中的production参数如下
注意到budgets的部分,里面的maximumWarning 设置了最大warning为2mb
所以只要把这个数值拉高就可以了 (个人把他直接拉高到10mb)
等等,就这样?
对。就这样。我从错误讯息中根本看不出来是喷很多警告的关系,所以他花了我一小时在那边爬文
如果各位引入套件之後,有类似的情形,可以先找找你家的webpack.json
档
把警告和错误讯息的上限拉高看看
exceljs这个套件就介绍到这边
本来有想要示范怎麽用react做一个可以异步取得资料的按钮
不过想想感觉已经跟这个套件本身脱离关系了
比较像是迁就他 触发
=> 建立表格、塞资料、触发下载
这个机制所必须做的行为,跟..react 还有promise比较有关
如果有人有留言敲碗的话,我再写一篇好了
就这样!希望文章都有帮助到大家~让大家少踩一点坑
还有让exceljs的文章多一点繁体字的介绍...
喜欢这篇文的话可以帮我点一个喜欢~ 我会很开心XDD (真是虚荣的女人
以上!
<<: [前端/JavaScript] 实作汇出excel下载按钮的超好用套件:ExcelJS(上)- 基础介绍与教学
使用 KubeEye 为你的 K8s 集群安全保驾护航 其他 2022-04-24 18:51:30...
学习资源整理-资安社团 决定好要学习哪个面向,那要去哪里学呢??是不是要花大钱去补习才能学得会呢? ...
现在就让我们回到Inputs的部分继续讲解,今天会讲解表单中常用的多选(checkbox)的作法。 ...
确定了offer也确定了报到时间後,距离到职日大概还有两周多的时间,因为自己是北漂青年因此开始寻找後...
前言 (因为最近时间有点少XD,所以偷偷选了比较短的影片来硬塞XD) 这篇显然就是个蛮一般的top...