这是渲染的数据

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

需要安装和npm依赖和引入封装的pdf.js文件
npm install --save html2canvas
npm install jspdf --save
pdf.js文件
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
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;
let imgWidth = 595.28;
let imgHeight = 595.28 / contentWidth * contentHeight;
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>姓名: {{ item.name }}</div>
<div>考号: {{ item.kaohao }}</div>
<div>司职: {{ 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">
考试类别
</td>
<td style="width: 180px; border: 1px solid #2d2822">
序号
</td>
</tr>
<tr>
<td style="width: 250px; border: 1px solid #2d2822">
理论测试
</td>
<td style="width: 180px; border: 1px solid #2d2822">
{{ item.liLunZw }}
</td>
</tr>
<tr>
<td
style="width: 250px; border: 1px solid #2d2822"
v-if="item.fangzhen[1] != undefined"
>
{{ item.fangzhen[0] }}
</td>
<td
style="width: 180px; border: 1px solid #2d2822"
v-if="item.uuid[1] != undefined"
>
{{ item.uuid[0] }}
</td>
</tr>
<tr>
<td
style="width: 250px; border: 1px solid #2d2822"
v-if="item.fangzhen[1] != undefined"
>
{{ item.fangzhen[1] }}
</td>
<td
style="width: 180px; border: 1px solid #2d2822"
v-if="item.uuid[1] != undefined"
>
{{ item.uuid[1] }}
</td>
</tr>
<tr>
<td
style="width: 250px; border: 1px solid #2d2822"
v-if="item.fangzhen[2] != undefined"
>
{{ item.fangzhen[2] }}
</td>
<td
style="width: 180px; border: 1px solid #2d2822"
v-if="item.uuid[2] != undefined"
>
{{ item.uuid[2] }}
</td>
</tr>
<tr>
<td
style="width: 250px; border: 1px solid #2d2822"
v-if="item.fangzhen[3] != undefined"
>
{{ item.fangzhen[3] }}
</td>
<td
style="width: 180px; border: 1px solid #2d2822"
v-if="item.uuid[3] != undefined"
>
{{ 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";
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: {
handleExport() {
this.downloadPDFs();
},
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];
var content = pdfElement.textContent;
const startIndex = content.indexOf("考号:") + 4;
const endIndex = content.indexOf("工种:");
const examNumber = content.substring(startIndex, endIndex).trim();
const ZhongName = item + "," + examNumber;
await this.delay(1000);
const downloadPromise = downloadPDF(pdfElement, ZhongName);
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;
display: flex;
justify-content: center;
}
.box_son {
width: 425px;
height: 600px;
margin-top: 30px;
}
.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;
}
.contents {
width: 70%;
height: 160px;
line-height: 56px;
}
.photos {
width: 30%;
height: 160px;
}
.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
综上就是全部的实现的内容