需求:给出一份excel表格(1000条数据),要将表格中的字段数据渲染到一张背景图片上,然后再下载图片,貌似浏览器做了限制,当连续下载10张图片后就不在下载了,然后用异步操作解决了这个问题。
// excel表格中对应的字段
const fields = ['姓名', '年龄', '性别', '手机号', '邮箱', '籍贯', '爱好'];
//背景图片路径
bgImage.src = '../imgs/mobanpg.png'; // 确保路径正确
//传递三个参数,(字段名,x距离,y距离),控制文本在背景图中显示的位置
ctx.fillText(row[2], 620, 270);
废话不多说,直接上全码:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Excel to Image</title><script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js"></script>
</head><body><input type="file" id="fileInput" accept=".xlsx, .xls"><canvas id="canvas" style="display:none;"></canvas><script>document.getElementById('fileInput').addEventListener('change', async (event) => {const file = event.target.files[0];// 获取用户选择的文件if (!file) return;// 如果没有选择文件,则直接返回// 创建一个FileReader对象,用于读取文件内容const reader = new FileReader();reader.onload = async (e) => {// 将读取的文件内容转换为Uint8Array类型const data = new Uint8Array(e.target.result);// 使用xlsx库读取Excel文件内容,得到一个工作簿对象const workbook = XLSX.read(data, { type: 'array' });// 获取工作簿中的第一个工作表名称和工作表对象const sheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[sheetName];// 将工作表内容转换为JSON格式的数据const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });// 获取画布元素和绘图上下文const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 创建一个新的Image对象,用于加载背景图const bgImage = new Image();bgImage.src = '../imgs/mobanpg.png'; // 确保路径正确let rowIndex = 1; // 从第一行数据开始(跳过标题行)const processRow = async () => {if (rowIndex > jsonData.length - 1) return; // 如果已经处理完所有数据,则退出const row = jsonData[rowIndex];console.log(row);ctx.clearRect(0, 0, canvas.width, canvas.height); // 重置画布内容ctx.drawImage(bgImage, 0, 0); // 在画布上绘制背景图const fields = ['姓名', '年龄', '性别', '手机号', '邮箱', '籍贯', '爱好'];ctx.font = '15px Arial';ctx.fillStyle = 'white'; // 公共字体颜色// 绘制各个字段(这里根据您的需求调整坐标和字段)ctx.fillText(row[0], 166, 42);//第一个字段ctx.fillText(row[1], 130, 270);//第二个字段// 绘制第二个字段的横线(如果需要)const textWidth2 = ctx.measureText(row[1]).width;// 测量第二个字段的文本宽度ctx.beginPath();// 开始新的路径ctx.moveTo(130, 274);// 横线起点ctx.lineTo(130 + textWidth2, 274);// 横线终点ctx.lineWidth = 1;// 横线宽度ctx.strokeStyle = 'white';// 设置横线颜色ctx.stroke();// 绘制路径ctx.restore(); // 恢复画布到之前保存的状态ctx.fillText(row[2], 620, 270);//第三个字段ctx.fillText(row[3], 830, 270);//第四个字段ctx.fillText(row[4], 1020, 270);//第五个字段ctx.fillText(row[5], 1230, 270);//第六个字段ctx.fillText(row[6], 1380, 270);//第七个字段// 创建临时画布并转换为Blob对象,生成下载链接const tempCanvas = document.createElement('canvas');tempCanvas.width = canvas.width;tempCanvas.height = canvas.height;const tempCtx = tempCanvas.getContext('2d');tempCtx.drawImage(canvas, 0, 0);tempCanvas.toBlob((blob) => {const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = `image_${row[0]}.png`;a.click();URL.revokeObjectURL(url);}, 'image/png');rowIndex++; // 更新行索引// 检查是否需要暂停if (rowIndex % 10 === 0) {await new Promise(resolve => setTimeout(resolve, 2000)); // 暂停2秒}// 继续处理下一行processRow();};// 等待背景图加载完成bgImage.onload = () => {canvas.width = bgImage.width;canvas.height = bgImage.height;processRow(); // 开始处理第一行};};reader.readAsArrayBuffer(file);});</script><!-- 确保背景图片路径正确,或者将图片放在与HTML文件相同的目录下 -->
</body></html>