导入excel动态生成海报

需求:给出一份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>
相关推荐
Jelena技术达人4 分钟前
1688接口探索:商品详情和关键字搜索API接口
前端·数据库
m0_7482338813 分钟前
前端对接fastGPT流式数据+打字机效果
前端
DevUI团队13 分钟前
开源开发者获奖,MateChat即将发布,快来看DevUI在华为云开源开发者论坛的精彩回顾吧
前端·人工智能
GIS开发特训营21 分钟前
0帧起手《Vue零基础教程》,从前端框架到GIS开发系列课程
前端·vue.js·前端框架
只会HelloWorld的华娃43 分钟前
【Excel学习记录】01-认识Excel
学习·excel
羊小猪~~1 小时前
前端入门之VUE--vue组件化编程
前端·javascript·css·vue.js·vscode·vue·html
web135085886351 小时前
VS2022 ASP.NET core Web API 示例代码解释
前端·后端·asp.net
阿智@111 小时前
跨域 Cookie 共享
java·开发语言·javascript
GIS开发特训营1 小时前
Vue零基础教程|从前端框架到GIS开发系列课程(二)
前端·vue.js·前端框架
Afanda…1 小时前
JS API&日期对象
前端·javascript