因公司需求改动, 但是因为到的地方比较多,所以单独写一个单工作表导出,实际可用多工作表的代码部分
interface IHeader {
k: string;
v: string;
}
export interface IParams<D extends any> {
header: IHeader[];
data: D[];
sheetName: string;
}
/**
*
* 导出 excel(带水印) 公共方法
* @param header v 为头,k 为对应 data 数据的 name
* 例:
const header = [
{
k: 'region',
v: '所属区域',
}
]
* @param data 要导出的数据
例:
const data = [
{
region:'广州'
},
{
region:'深圳'
}
]
* @param filename 导出的 excel 文件名称
* @param sheetName 指定第一个工作表的名称
* @param staff 水印名称
* @param params 导出多个工作表
* 格式为:
* [{header:[],data:[],sheetName:''}]
* @returns
*/
export const createWsSheet = <T, D>(
header: IHeader[],
data: T[],
filename: string,
sheetName = 'sheet1',
params: IParams<D>[] = [],
staff: string = '水印名称',
): void => {
Message.loading('正在导出...');
if (!((header && data) && (header.length && data.length))) {
Message.error('导出失败');
return;
}
// 创建工作簿
const workbook = new ExcelJS.Workbook();
// 获取水印
const base64 = setWatermark(staff);
const imageId1 = workbook.addImage({ base64, extension: 'png' });
// 创建带有红色标签颜色的工作表
const worksheet = workbook.addWorksheet(sheetName, { properties: { tabColor: { argb: 'FFC0000' } } });
// 生成 columns
const columns = header.map((col: IHeader): { name: string } => ({ name: col.v }));
// 生成 rows
const rows = data.map((row: T): T[] => {
return header.map(itm => isNull(row[itm.k]) ? row[itm.k] : '');
});
// 添加背景图片
worksheet.addBackgroundImage(imageId1);
// 添加数据
worksheet.addTable({
name: filename,
ref: 'A1',// 表格左上角位置
columns,
rows
});
// 多工作表
if (params && params.length) {
params.forEach((el: IParams<D>) => {
if (!((el.header && el.data) && (el.header.length && el.data.length))) {
Message.error('导出失败');
return;
}
const worksheetM = workbook.addWorksheet(el.sheetName, { properties: { tabColor: { argb: 'FFC0000' } } });
// 生成 columns
const columnsM = el.header.map((col: IHeader): { name: string } => ({ name: col.v }));
// 生成 rows
const rowsM = el.data.map((row: D): D[] => {
return el.header.map(itm => isNull(row[itm.k]) ? row[itm.k] : '');
});
// 添加背景图片
worksheetM.addBackgroundImage(imageId1);
// 添加数据
worksheetM.addTable({
name: el.sheetName,
ref: 'A1',// 表格左上角位置
columns: columnsM,
rows: rowsM
});
})
}
workbook.xlsx.writeBuffer().then((res) => {
saveAs(new Blob([res], { type: 'application/octet-stream' }), filename)
});
Message.success('导出成功');
};
/**
* 判断该数据是否为空
* @param data 要判断的数据
* @returns 布尔值:true/false
*/
const isNull = (data: any): boolean => {
return (data ?? '') !== '';
}
/**
* 绘画水印
* @param str 要做出水印的文字
* @returns Base64
*/
const setWatermark = (str: string): string => {
let id = '1.23452384164.123412416';
if (document.getElementById(id) !== null) {
document.body.removeChild(document.getElementById(id) as any);
}
// 创建一个画布
let can = document.createElement('canvas');
// 设置画布的长宽
can.width = 500;
can.height = 420;
let cans = can.getContext('2d') as any;
// 旋转角度
cans.rotate(-25 * Math.PI / 180);
// 设置字体大小
cans.font = "800 40px Microsoft JhengHei";
// 设置填充绘画的颜色、渐变或者模式
cans.fillStyle = "rgba(130, 142, 162, 0.2)";
// 设置文本内容的当前对齐方式
cans.textAlign = 'center';
// 设置在绘制文本时使用的当前文本基线
cans.textBaseline = 'Middle';
cans.fillText(str, 180, 350);
const dataURL = can.toDataURL('image/png');
return dataURL;
}