Vue3 + Vite + TS,使用 ExcelJS导出excel文档,生成水印,添加背景水印,dom转图片,插入图片,全部代码

Vue3 + Vite + TS,使用 ExcelJS导出excel文档,生成水印,添加背景水印,dom转图片,插入图片,全部代码

  • ExcelJS
    • 生成文档并导出
      • 导出表头其他函数
    • 生成水印
    • 设置文档的背景水印
    • dom 转图片
    • 插入图片
    • 全部代码

ExcelJS

读取,操作并写入电子表格数据和样式到 XLSX 和 JSON 文件。
一个 Excel 电子表格文件逆向工程项目。
exceljs 中文API 传送门

生成文档并导出

import * as ExcelJS from "exceljs";// 创建文档对象
const workbook = new ExcelJS.Workbook();
// 创建工作本
const worksheet = workbook.addWorksheet('Sheet 1');
// 冻结表头
worksheet.views = [{state: 'frozen', // 可以设置为 'frozen' 来固定首行或首列,模拟滚动条效果xSplit: 0, // 从第二列开始冻结(模拟滚动条效果)ySplit: 9, // 从第二行开始冻结(模拟滚动条效果)topLeftCell: 'A1' // 设置起始位置为 B2,模拟滚动效果从第二行第二列开始
}];
// 1. 构建表头结构
const headerDepth = buildHeaders(filterColumns,7);
// 递归生成表头行
generateHeaderRows(worksheet,headerDepth,filterColumns,7);
// 2. 填充数据
// salesTable.value.tableData.forEach(item => {
//     worksheet.addRows(item);
// })
// 触发下载
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = name+'.xlsx';
link.click();

导出表头其他函数

// 递归生成表头行
export const generateHeaderRows = (worksheet:Worksheet,headerDepth:number,cols:tableColumn[], currentRow = 0, startCol = 0) => {cols.forEach(col => {const cell = {header: col.label,key: col.dataIndex,width: col.minWidth?parseInt(col.minWidth)/8 : 20,colSpan: col.childrens ? col.childrens.length : 1,rowSpan: col.childrens ? 1 : headerDepth - currentRow + 1};const tempCell = worksheet.getCell(currentRow + 1, startCol + 1);// 设置单元格文案tempCell.value = col.label;// 设置单元格字体与大小tempCell.font = { name: 'Arial', size: 10 }// 设置列宽度worksheet.getColumn(startCol+1).width = cell.width;// 设置行高worksheet.getRow(currentRow+1).height = 20;// 合并单元格worksheet.mergeCells(currentRow + 1,startCol + 1,currentRow + (cell.rowSpan || currentRow+1), startCol + (cell.colSpan || 1));// 有子级递归if (col.childrens) {generateHeaderRows(worksheet,headerDepth,col.childrens, currentRow + 1, startCol);}startCol += cell.colSpan;});
}// 递归处理表头层级
export const buildHeaders = (columns:tableColumn[], depth = 0, parentSpan = 0) => {let maxDepth = depth;columns.forEach((col:tableColumn) => {if (col.childrens) {const childDepth = buildHeaders(col.childrens, depth + 1, parentSpan + (col.colSpan|| 0));maxDepth = Math.max(maxDepth, childDepth);}});return maxDepth;
};

生成水印

export const createWatermark = () => {// 创建 Canvas 元素并绘制水印const canvas = document.createElement('canvas');const context:CanvasRenderingContext2D | null  = canvas.getContext('2d');canvas.width = 500;canvas.height = 200;context?context.font = '14px Arial':'';// 旋转角度context?context.rotate(-25 * Math.PI / 180):'';// 设置文本内容的当前对齐方式context?context.textAlign = 'center':'';context?context.fillStyle = 'rgba(0, 0, 0, 0.1)':''; // 半透明水印context?context.fillText('midea', canvas.width / 2 - 100, canvas.height / 2):'';// 将 Canvas 转换为图片数据 URLreturn canvas.toDataURL('image/png');
}

设置文档的背景水印

// 将 Canvas 水印 转换为图片数据 URL
const imageDataUrl = createWatermark();
// 添加图片到工作簿中
const imageId = workbook.addImage({base64: imageDataUrl.replace(/^data:image\/[a-z]+;base64,/, ''),extension: 'png',
});
// 设置文档水印
worksheet.addBackgroundImage(imageId)

dom 转图片

import domToImage from 'dom-to-image';// 把查询条件转为图片
domToImage.toPng(captureRef.value).then(async (dataUrl) => {const image = new Image();image.src = dataUrl;})
.catch(function (error) {console.error('Failed to generate image:', error);
});

插入图片

const imageId2 = workbook.addImage({ base64: dataUrl, extension: 'png' });
// 工作本插入查询条件图片
worksheet.addImage(imageId2, {tl: { col: 0, row: 0 },ext: { width: 1900 / 1.3, height: 800 / 6 }
});

全部代码


// 递归生成表头行
export const generateHeaderRows = (worksheet:Worksheet,headerDepth:number,cols:tableColumn[], currentRow = 0, startCol = 0) => {cols.forEach(col => {const cell = {header: col.label,key: col.dataIndex,width: col.minWidth?parseInt(col.minWidth)/8 : 20,colSpan: col.childrens ? col.childrens.length : 1,rowSpan: col.childrens ? 1 : headerDepth - currentRow + 1};const tempCell = worksheet.getCell(currentRow + 1, startCol + 1);// 设置单元格文案tempCell.value = col.label;// 设置单元格字体与大小tempCell.font = { name: 'Arial', size: 10 }// 设置列宽度worksheet.getColumn(startCol+1).width = cell.width;// 设置行高worksheet.getRow(currentRow+1).height = 20;// 合并单元格worksheet.mergeCells(currentRow + 1,startCol + 1,currentRow + (cell.rowSpan || currentRow+1), startCol + (cell.colSpan || 1));// 有子级递归if (col.childrens) {generateHeaderRows(worksheet,headerDepth,col.childrens, currentRow + 1, startCol);}startCol += cell.colSpan;});
}// 递归处理表头层级
export const buildHeaders = (columns:tableColumn[], depth = 0, parentSpan = 0) => {let maxDepth = depth;columns.forEach((col:tableColumn) => {if (col.childrens) {const childDepth = buildHeaders(col.childrens, depth + 1, parentSpan + (col.colSpan|| 0));maxDepth = Math.max(maxDepth, childDepth);}});return maxDepth;
};
export const createWatermark = () => {// 创建 Canvas 元素并绘制水印const canvas = document.createElement('canvas');const context:CanvasRenderingContext2D | null  = canvas.getContext('2d');canvas.width = 500;canvas.height = 200;context?context.font = '14px Arial':'';// 旋转角度context?context.rotate(-25 * Math.PI / 180):'';// 设置文本内容的当前对齐方式context?context.textAlign = 'center':'';context?context.fillStyle = 'rgba(0, 0, 0, 0.1)':''; // 半透明水印context?context.fillText('midea', canvas.width / 2 - 100, canvas.height / 2):'';// 将 Canvas 转换为图片数据 URLreturn canvas.toDataURL('image/png');
}// 点击下载const downLoadList = () => {// 创建文档对象const workbook = new ExcelJS.Workbook();// 创建工作本const worksheet = workbook.addWorksheet('Sheet 1');// 冻结表头worksheet.views = [{state: 'frozen', // 可以设置为 'frozen' 来固定首行或首列,模拟滚动条效果xSplit: 0, // 从第二列开始冻结(模拟滚动条效果)ySplit: 9, // 从第二行开始冻结(模拟滚动条效果)topLeftCell: 'A1' // 设置起始位置为 B2,模拟滚动效果从第二行第二列开始}];// 1. 构建表头结构const headerDepth = buildHeaders(filterColumns,7);// 递归生成表头行generateHeaderRows(worksheet,headerDepth,filterColumns,7);emit('downLoadList',workbook,worksheet);}const downLoadListFn = async (workbook:Workbook,worksheet:Worksheet,name:string) => {// 把查询条件转为图片domToImage.toPng(captureRef.value).then(async (dataUrl) => {const image = new Image();image.src = dataUrl;const imageId2 = workbook.addImage({ base64: dataUrl, extension: 'png' });// 工作本插入查询条件图片worksheet.addImage(imageId2, {tl: { col: 0, row: 0 },ext: { width: 1900 / 1.3, height: 800 / 6 }});// 2. 填充数据// salesTable.value.tableData.forEach(item => {//     worksheet.addRows(item);// })// 将 Canvas 水印 转换为图片数据 URLconst imageDataUrl = createWatermark();// 添加图片到工作簿中const imageId = workbook.addImage({base64: imageDataUrl.replace(/^data:image\/[a-z]+;base64,/, ''),extension: 'png',});// 设置文档水印worksheet.addBackgroundImage(imageId)// 触发下载const buffer = await workbook.xlsx.writeBuffer();const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });const link = document.createElement('a');link.href = URL.createObjectURL(blob);link.download = name+'.xlsx';link.click();}).catch(function (error) {console.error('Failed to generate image:', error);});}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/80661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

devops自动化容器化部署

devops 一、简单案例体验gitlabrunner部署静态文件二、devops企业级部署方案1、流程图2、依赖工具3、流程图4、主机规划5、安装工具软件1、安装git2、安装gitlab3、安装jenkins-server4、安装harbor5、安装web-server,也就是部署服务的机子,需要安装dock…

高级 SQL 技巧:提升数据处理能力的实用方法

在数据驱动的时代,SQL 作为操作和管理关系型数据库的标准语言,其重要性不言而喻。基础的 SQL 语句能满足日常的数据查询需求,但在处理复杂业务逻辑、进行数据分析和优化数据库性能时,就需要掌握一些高级 SQL 技巧。这些技巧不仅能提高查询效率,还能实现复杂的数据处理任务…

21.disql命令登录达梦数据库,查询并操作数据库

目录 1.连接达梦数据库 1.1 windows或linux系统 步骤(1):打开终端窗口 步骤(2):进入梦数据库安装目录下的 bin 文件夹 步骤(3):用disql命令进行登录 1.2 docker部署…

N8N MACOS本地部署流程避坑指南

最近n8n很火,就想在本地部署一个,尝尝鲜,看说明n8n是开源软件,可以在本地部署,于是就尝试部署了下,大概用了1个多小时,把相关的过程记录一下: 1、基础软件包 abcXu-MacBook-m2-Air…

qt之开发大恒usb3.0相机一

1.在大恒相机给的sample里没有看见qt开发的demo. 第一步先运行c sdk中中的demo,看了下代码,大恒使用的UI框架是MFC.然后 vs2022编译。运行结果 第一步,先用qt进行坐下页面布局,如下图(保存图片的地方做了些更改&#…

leetcode-枚举

枚举 3200. 三角形的最大高度 题目 给你两个整数 red 和 blue,分别表示红色球和蓝色球的数量。你需要使用这些球来组成一个三角形,满足第 1 行有 1 个球,第 2 行有 2 个球,第 3 行有 3 个球,依此类推。 每一行的球必…

DeepSeek智能时空数据分析(三):专业级地理数据可视化赏析-《杭州市国土空间总体规划(2021-2035年)》

序言:时空数据分析很有用,但是GIS/时空数据库技术门槛太高 时空数据分析在优化业务运营中至关重要,然而,三大挑战仍制约其发展:技术门槛高,需融合GIS理论、SQL开发与时空数据库等多领域知识;空…

如何用WordPress AI插件自动生成SEO文章,提升网站流量?

1. 为什么你需要一个WordPress AI文章生成插件? 每天手动写文章太耗时?SEO优化总是不达标?WordPress AI插件能帮你24小时自动生成原创内容,从关键词挖掘到智能排版,全程无需人工干预。 痛点:手动写作效率低…

鼠标指定范围内随机点击

鼠标指定范围内随机点击 点赞神器 将鼠标移动到相应位置后按F5 F6键,设置点击范围, F8开始,ESC中止。 有些直播有点赞限制,例如某音,每小时限制3千次,可以设置1200毫秒,3000次。 软件截图&#…

数据库设置外键的作用

数据库外键(Foreign Key)是关系型数据库中用于建立表与表之间关联关系的重要约束,其核心作用是确保数据的一致性、完整性和关联性。以下是外键的主要作用及相关说明: 1. 建立表间关联关系 外键通过引用另一张表的主键&#xff0…

发币流程是什么,需要多少成本?

这是一个专注于Web3相关开发的账号,具体会讲解步骤以及开发方案 偶尔会有科普,有兴趣的可以点右上角关注一下 发币(发行数字货币)的流程通常涉及技术实现、法律合规、经济模型设计等多个环节,以下是关键步骤的简要说明…

测试常用的Linux系统指令详解

为什么测试工程师需要掌握Linux命令? 在现代软件测试领域,约75%的服务端应用运行在Linux环境中,能够熟练使用Linux命令的测试工程师,其工作效率比仅依赖GUI工具的测试人员高出40%以上。本文将系统介绍测试工作中最实用的Linux命令…

Java学习手册:Web 安全基础

一、常见 Web 安全威胁 在 Web 开发中,安全问题至关重要。以下是一些常见的 Web 安全威胁: 1. SQL 注入 SQL 注入是一种攻击方式,攻击者通过在输入字段中插入恶意的 SQL 代码,从而操纵数据库。例如,假设有一个登录表…

游戏引擎学习第246天:将 Worker 上下文移到主线程创建

回顾并为今天的工作做准备 关于GPU驱动bug的问题,目前本地机器上没有复现。如果有问题,昨天的测试就应该已经暴露出来了。当前演示的是游戏的过场动画,运行正常,使用的是硬件渲染。 之前使用软件渲染时没有遇到太多问题&#xff…

2025.4.26总结

今天把马良老师的《职场十二法则》看完后,感触极大,这们课程就是一场职场启蒙课。 虽然看过不少关于职场的书籍,但大多数是关于职场进阶,方法方面的。并没有解答“面对未来二三十年的职场生涯,我该怎么去看待自己的工…

路由器转发规则设置方法步骤,内网服务器端口怎么让异地连接访问的实现

在路由器上设置端口转发(Port Forwarding)可以将外部网络流量引导到特定的局域网设备,这对于需要远程访问服务器、摄像头、游戏主机等设备非常有用。 登录路由器管理界面,添加端口转发规则让外网访问内网的实现教程分享。以下是设…

Linux基础命令总结

Linux系统命令 1. systemctl 1. 基本语法 systemctl start | stop | restart | status 服务名 2. 经验技巧查看服务的方法:/usr/lib/systemd/system 3. 案例实操 (1)查看防火墙服务的状态 systemctl status firewalld (2)停止防火墙服务 systemctl stop firewalld (…

【PVCodeNet】《Palm Vein Recognition Network Combining Transformer and CNN》

[1]吴凯,沈文忠,贾丁丁,等.融合Transformer和CNN的手掌静脉识别网络[J].计算机工程与应用,2023,59(24):98-109. 文章目录 1、Background and Motivation2、Related Work3、Advantages / Contributions4、Method5、Experiments5.1、Datasets and Metrics5.2、Hyper-parameters5.…

《企业级 Java EE 架构设计精深实践》内容详解

《企业级 Java EE 架构设计精深实践》内容详解 1. 书籍核心主题 《企业级 Java EE 架构设计精深实践》是一本深入探讨Java EE 企业级架构设计的实战指南,涵盖分层架构、设计模式、分布式系统、微服务、性能优化、安全与监控等核心内容,结合 Java EE 技术…

Ragflow新建的知识库完成后刷新却没有显示,报错MethodNotAllowed: 405 Method Not Allowed:

环境: Ragflow17.2 debian12.8 问题描述: Ragflow新建的知识库完成后刷新却没有显示,报错MethodNotAllowed: 405 Method Not Allowed: The method is not allowed for the requested URL. 后台日志: 2025-04-25 13:54:25,988 ERROR 235204 405 Method Not Allowed:…