• Vue生成多文件pdf准考证


    这是渲染的数据

    在这里插入图片描述

    这是生成的pdf文件,直接可以打印

    在这里插入图片描述

    需要安装和npm依赖和引入封装的pdf.js文件

    npm install --save html2canvas  // 页面转图片
    npm install jspdf --save  // 图片转pdf
    
    • 1
    • 2

    pdf.js文件

    import html2canvas from "html2canvas";
    import jsPDF from "jspdf";
    // 为传的pdf名称动态fileName
    export const downloadPDF = (page, fileName) => {
        html2canvas(page).then(function (canvas) {
            canvas2PDF(canvas, fileName);
        });
    };
    const canvas2PDF = (canvas, fileName) => {
        let contentWidth = canvas.width;
        let contentHeight = canvas.height;
    
        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        let imgWidth = 595.28;
        let imgHeight = 595.28 / contentWidth * contentHeight;
        // 第一个参数: l:横向  p:纵向
        // 第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px")
        let pdf = new jsPDF("p", "pt");
        pdf.addImage(
            canvas.toDataURL("image/jpeg", 1.0),
            "JPEG",
            0,
            0,
            imgWidth,
            imgHeight
        );
    
        pdf.save(fileName + ".pdf");
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    具体实现

    Tempalte

    <template>   
    	<div> 
        <div v-for="(item, index) in listDatas" :key="index">
          <div class="boss">
            <div class="box" :ref="`pdf-${index}`">
              <div class="box_son">
                <div class="titles">"XXX"竞赛</div>
                <div class="zhunasd">准考证</div>
                <div class="once">
                  <div class="contents">
                    <div>姓名: &nbsp;{{ item.name }}</div>
                    <div>考号: &nbsp;{{ item.kaohao }}</div>
                    <div>司职: &nbsp;{{ item.gongzhongTitle }}</div>
                  </div>
    
                  <div class="photos">
                    <img :src="item.sfzhimgs" alt="" width="100%" height="150px" />
                  </div>
                </div>
    
                <table
                  border="1px solid #2D2822"
                  cellpadding="0"
                  cellspacing="0"
                  class="tables"
                >
                  <tr>
                    <td style="width: 250px; border: 1px solid #2d2822">
                      &nbsp;考试类别
                    </td>
    
                    <td style="width: 180px; border: 1px solid #2d2822">
                      &nbsp;序号
                    </td>
                  </tr>
    
                  <tr>
                    <td style="width: 250px; border: 1px solid #2d2822">
                      &nbsp;理论测试
                    </td>
                    <td style="width: 180px; border: 1px solid #2d2822">
                      &nbsp;{{ item.liLunZw }}
                    </td>
                  </tr>
    
                  <tr>
                    <td
                      style="width: 250px; border: 1px solid #2d2822"
                      v-if="item.fangzhen[1] != undefined"
                    >
                      &nbsp;{{ item.fangzhen[0] }}
                    </td>
                    <td
                      style="width: 180px; border: 1px solid #2d2822"
                      v-if="item.uuid[1] != undefined"
                    >
                      &nbsp;{{ item.uuid[0] }}
                    </td>
                  </tr>
                  <tr>
                    <td
                      style="width: 250px; border: 1px solid #2d2822"
                      v-if="item.fangzhen[1] != undefined"
                    >
                      &nbsp;{{ item.fangzhen[1] }}
                    </td>
                    <td
                      style="width: 180px; border: 1px solid #2d2822"
                      v-if="item.uuid[1] != undefined"
                    >
                      &nbsp;{{ item.uuid[1] }}
                    </td>
                  </tr>
                  <tr>
                    <td
                      style="width: 250px; border: 1px solid #2d2822"
                      v-if="item.fangzhen[2] != undefined"
                    >
                      &nbsp;{{ item.fangzhen[2] }}
                    </td>
                    <td
                      style="width: 180px; border: 1px solid #2d2822"
                      v-if="item.uuid[2] != undefined"
                    >
                      &nbsp;{{ item.uuid[2] }}
                    </td>
                  </tr>
                  <tr>
                    <td
                      style="width: 250px; border: 1px solid #2d2822"
                      v-if="item.fangzhen[3] != undefined"
                    >
                      &nbsp;{{ item.fangzhen[3] }}
                    </td>
                    <td
                      style="width: 180px; border: 1px solid #2d2822"
                      v-if="item.uuid[3] != undefined"
                    >
                      &nbsp;{{ item.uuid[3] }}
                    </td>
                  </tr>
                </table>
    
                <div class="footers">
                  <div>注意事项:</div>
    
                  <div class="footers_one">
                    1、考生凭准考证和身份证进入考场,对号入座,并将准考证、<br />
                    <div class="footers_two">身份证放在桌面上</div>
                  </div>
                  <div class="footers_two">
                    2、准考证如有涂改或者损坏严重情况,将视为无效证件。
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <button @click="handleExport">导出PDF</button>
    
    </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    Script

    1.转换为base64的图片才能生效 http和https的图片生成都不生效

    2.这里用到的是Google Chrome浏览器多文件下载一次最多只有10个,这里我们有做异步处理延迟1秒下载

    <script>
    
    import { downloadPDF } from "../utils/pdf"; //创建一个utils文件夹 下放封装的pdf
    export default {
      data() {
        return {
          listDatas: [
            {
              kaohao: "2100",
              liLunZw: "D106",
              sfzh: "2110",
              name: "Stephen Curry",
              uuid: ["GS01", "GA02", "GF03"],
              gongzhongTitle: "后卫",
              fangzhen: ["运球训练", "投篮训练", "上篮训练"],
              sfzhimgs: "转换为base64的图片才能生效 http和https的图片生成都不生效",
            },
            {
              kaohao: "2100",
              liLunZw: "D107",
              sfzh: "2110",
              name: "Andrew Wiggins",
              uuid: ["GS01", "GA02", "GF03"],
              gongzhongTitle: "小前锋",
              fangzhen: ["运球训练", "投篮训练", "上篮训练"],
              sfzhimgs: "",
            },
            {
              kaohao: "2100",
              liLunZw: "D107",
              sfzh: "2110",
              name: "Andrew Wiggins",
              uuid: ["GS01", "GA02", "GF03"],
              gongzhongTitle: "小前锋",
              fangzhen: ["运球训练", "投篮训练", "上篮训练"],
              sfzhimgs: "",
            },
            {
              kaohao: "2100",
              liLunZw: "D107",
              sfzh: "2110",
              name: "Andrew Wiggins",
              uuid: ["GS01", "GA02", "GF03"],
              gongzhongTitle: "小前锋",
              fangzhen: ["运球训练", "投篮训练", "上篮训练"],
              sfzhimgs: "",
            },
          ],
        };
      },
    
      methods: {
        // 导出pdf
        handleExport() {
          this.downloadPDFs();
        },
        // 异步执行下载pdf
        async downloadPDFs() {
          const downloadPromises = [];
          for (let index = 0; index < this.listDatas.length; index++) {
            const item = this.listDatas[index].name; //获取名称
            const pdfElement = this.$refs[`pdf-${index}`][0]; //获取pdf内容循环
            var content = pdfElement.textContent; //获取文本内容
            const startIndex = content.indexOf("考号:") + 4; //截取考号为pdf的名称
            const endIndex = content.indexOf("工种:");
            const examNumber = content.substring(startIndex, endIndex).trim(); //pdf的名字
            const ZhongName = item + "," + examNumber; //名称+考号为pdf名称
            await this.delay(1000); // 延迟1秒
            const downloadPromise = downloadPDF(pdfElement, ZhongName); //获取打印pdf的内容
    
            downloadPromises.push(downloadPromise);
          }
          Promise.all(downloadPromises)
            .then(() => {
              // 全部下载完成后执行的代码
              console.log("全部下载完成");
            })
            .catch((error) => {
              // 处理下载错误
              console.error("下载出错", error);
            });
        },
        delay(ms) {
          return new Promise((resolve) => setTimeout(resolve, ms));
        },
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    Style

    <style>
    .boss {
      width: 100%;
      margin: 0 auto;
      display: flex;
      justify-content: center;
      overflow: hidden;
    }
    .box {
      width: 480px;
      height: 760px;
      // border: 1px solid #000;
      display: flex;
      justify-content: center;
      // margin-top: 50px;
    }
    .box_son {
      width: 425px;
      height: 600px;
      margin-top: 30px;
      // border: 1px solid yellow;
    }
    .titles {
      font-size: 20px;
      font-weight: 800;
      display: flex;
      justify-content: center;
      margin-top: 10px;
    }
    .zhunasd {
      font-size: 20px;
      font-family: Microsoft YaHei;
      font-weight: 800;
      text-align: center;
    }
    .once {
      width: 100%;
      display: flex;
      justify-content: space-between;
      margin-top: 20px;
      font-size: 17px;
      font-family: Microsoft YaHei;
      font-weight: 500;
      // border: 1px solid #000;
    }
    .contents {
      width: 70%;
      height: 160px;
      // border: 1px solid red;
      line-height: 56px;
    }
    .photos {
      width: 30%;
      height: 160px;
      // border: 1px solid blue;
    }
    .tables {
      width: 425px;
      margin-top: 20px;
      height: 180px;
    }
    .footers {
      margin-top: 20px;
    }
    .footers_one {
      margin-top: 10px;
    }
    .footers_two {
      margin-top: 10px;
    }
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    综上就是全部的实现的内容

  • 相关阅读:
    经典算法之希尔排序法(Java实现)
    Java中的线程中断
    【esp32】arduino-数码管
    CV每日论文--2024.4.25
    在线考试系统
    一个普通码农这辈子能掌握这101道算法题就足够了
    京东医疗器械分类汇总
    2022 年杭电多校第五场补题记录
    分布式消息系统Kafka解析
    测绘地理信息毕业生有充足职业选择
  • 原文地址:https://blog.csdn.net/weixin_48193717/article/details/132663603