vue 生成 证书模板 并支持 图片下载和导出PDF的demo
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue

·
demo 使用的是html2canvas 和jspdf 插件, 不明白的先去看这个
插件使用
下面是我的一个例子,大家可以参考:
注意: 请先看上面文章,安装插件和配置,这里不重复说了哦
index.vue
<template>
<div>
<h3>html转pdf下载</h3>
<el-button type="primary" @click="preview">预览证书</el-button>
<el-dialog
title="证书预览和下载"
:visible.sync="dialogVisible"
width="60%"
:before-close="handleClose"
>
<div id="pdfDom">
<div class="proBox">
<p class="tit">结业证书</p>
<p class="proid"><span>编号:</span> <span>xxjj2021412</span></p>
<p class="con">
<span class="con-name">xxx</span>
同志于<span>2021年6月-2022年五月</span>参加首批小鱼哈哈教师工作室培养(主持人:<span>小鱼</span>)培养,经考核,成绩合格,准予结业。
</p>
<div class="con-unit">
<p>小鱼哈哈教师继续教育中心</p>
<p class="time">2021年12月30号</p>
</div>
<p class=" con-footer">小鱼教育局 监制</p>
<div class="chapter" v-show="isShow">
<canvas id="chapterCanvas" width="150" height="150"></canvas>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-switch
inactive-color="#67c23a"
v-model="downType"
active-text="图片下载"
inactive-text="pdf下载"
style="margin-right: 20px;"
>
</el-switch>
<el-checkbox v-model="isShow" style="margin-right: 20px;"
>添加盖章</el-checkbox
>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="getPdf('#pdfDom')">下载</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialogVisible: false,
pageData: null, //接收html格式代码
htmlTitle: "结业证书",
isShow: true,
isCanvas: false,
downType: true // false为 pdf , true为图片
};
},
methods: {
handleClose() {
this.dialogVisible = false;
},
preview() {
this.dialogVisible = true;
this.$nextTick(()=> {
if(!this.isCanvas) {
// 只绘画一次
this.isCanvas = true
this.getChapter()
}
})
},
// 生成印章
getChapter() {
var canvas = document.getElementById("chapterCanvas");
var context = canvas.getContext("2d");
var text = "xxx专用章";
var companyName = "小鱼哈哈教师继续教育中心";
// context.translate(0, 0);
// context.clearRect(0, 0, 200, 200);//清除整个画布
// 绘制印章边框
var width = canvas.width / 2;
var height = canvas.height / 2;
context.lineWidth = 3;
context.strokeStyle = "#cf0c0c";
context.beginPath();
context.arc(width, height, 60, 0, Math.PI * 2); //宽、高、半径
context.stroke();
//画五角星
create5star(context, width, height, 15, "#cf0c0c", 0);
// 绘制印章名称
context.font = "20px 宋体";
context.textBaseline = "middle"; //设置文本的垂直对齐方式
context.textAlign = "center"; //设置文本的水平对对齐方式
context.lineWidth = 1;
context.strokeStyle = "#cf0c0c";
// context.strokeText(text, width, height + 30); // 名称 xx专用章
// 绘制印章单位
context.translate(width, height); // 平移到此位置,
context.font = "20px 宋体";
var count = companyName.length; // 字数
var angle = (5 * Math.PI) / (3 * (count - 1)); // 字间角度
var chars = companyName.split("");
var c;
for (var i = 0; i < count; i++) {
c = chars[i]; // 需要绘制的字符
if (i == 0) {
context.rotate((4 * Math.PI) / 6);// 文字起始位置
} else {
context.rotate(angle);
}
context.save();
context.translate(45, 0); // 平移到此位置,此时字和x轴垂直,公司名称和最外圈的距离
context.rotate(Math.PI / 2); // 旋转90度,让字平行于x轴
context.strokeText(c, 0, 0); // 此点为字的中心点
context.restore();
}
//绘制五角星
function create5star(context, sx, sy, radius, color, rotato) {
context.save();
context.fillStyle = color;
context.translate(sx, sy); //移动坐标原点
context.rotate(Math.PI + rotato); //旋转
context.beginPath(); //创建路径
var x = Math.sin(0);
var y = Math.cos(0);
var dig = (Math.PI / 5) * 4;
for (var i = 0; i < 5; i++) {
//画五角星的五条边
var x = Math.sin(i * dig);
var y = Math.cos(i * dig);
context.lineTo(x * radius, y * radius);
}
context.closePath();
context.stroke();
context.fill();
context.restore();
}
}
}
};
</script>
<style scoped >
::v-deep .el-dialog__body {
padding: 0px;
display: flex;
justify-content: center;
}
#pdfDom {
/* 要想pdf周边留白,要在这里设置 */
padding: 20px;
width: 750px;
}
.proBox {
background: url("../../assets/zs.jpg") no-repeat;
background-size: cover;
width: 750px;
height: 525px;
padding: 90px 94px;
box-sizing: border-box;
margin: 0 auto;
position: relative;
color: #000;
font-family: SimSun;
}
.tit {
color: #cf0c0c;
font-size: 36px;
font-weight: 700;
position: relative;
top: -6px;
left: 8px;
letter-spacing: 20px;
font-family: STHeiti;
margin: 20px 0;
}
.proid {
text-align: right;
margin: 0;
font-weight: 500;
/* margin-right: 5px; */
}
.con {
font-size: 20px;
font-weight: 700;
text-align: left;
margin: 10px 0;
line-height: 32px;
text-indent: 2em;
}
.con-name {
font-family: 华文行楷, STXingkai;
border-bottom: 2px solid #000;
}
.con-unit {
font-size: 18px;
font-weight: 700;
position: absolute;
right: 100px;
bottom: 100px;
text-align: center;
letter-spacing: 3px;
}
.con-unit p {
margin: 5px 0;
}
.con-footer {
font-size: 18px;
font-weight: 700;
position: absolute;
bottom: 45px;
left: 0;
right: 0;
text-align: center;
}
.chapter {
border-radius: 50%;
position: absolute;
bottom: 75px;
right: 134px;
}
</style>
效果如下:
图片下载没啥问题,PDF就有多余的白边,大家根据自己情况调节大小吧,我的暂时效果如下:




vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:5 个月前 )
9e887079
[skip ci] 3 个月前
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 7 个月前
更多推荐
所有评论(0)