需求:给出一份excel表格(1000条数据),要将表格中的字段数据渲染到一张背景图片上,然后再下载图片,貌似浏览器做了限制,当连续下载10张图片后就不在下载了,然后用异步操作解决了这个问题。
javascript
// excel表格中对应的字段
const fields = ['姓名', '年龄', '性别', '手机号', '邮箱', '籍贯', '爱好'];
//背景图片路径
bgImage.src = '../imgs/mobanpg.png'; // 确保路径正确
//传递三个参数,(字段名,x距离,y距离),控制文本在背景图中显示的位置
ctx.fillText(row[2], 620, 270);
废话不多说,直接上全码:
html
<!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>