Vue纯前端技术:自动生成并下载特定页面为图片至本地
最编程
2024-08-01 18:02:10
...
需求:制作名片并把名片导出下载到本地
首先想到的是如何把部分页面内容转换为图片,经过查询文档发现html2canvas这个插件可以实现该功能
解决步骤:
1.安装html2canvas 官方文档可以参考html2canvas
引入方式:
npm install --save html2canvas
或者:
yarn add html2canvas
2..将html2canvas引入到组件中
该插件安装完毕后,在你需要使用的vue组件中,按照以下方式,将插件引入:
import html2canvas from "html2canvas" 3.将制定区域内转成图片 首先,你需要让html2canvas获取到你想要转换的节点内容,因此,你需要添加ref标记。 示例如下(必须把想要导出的内容放到ref的div里):
<div class="scan-card-container" ref="imageWrapper">
<div class="scan-card">
<div class="header">
<img :src="`${logoUrl}?${new Date().getTime()}`"
class="logo-img"
crossOrigin="anonymous"
>
<img :src="`${avatarUrl}?${new Date().getTime()}`"
class="img-avatar"
crossOrigin="anonymous"
>
</div>
</div>
</div>
完整代码
html
<div class="scan-card-container" ref="imageWrapper">
<div class="scan-card">
<div class="header">
<img :src="`${logoUrl}?${new Date().getTime()}`"
class="logo-img"
crossOrigin="anonymous"
>
<img :src="`${avatarUrl}?${new Date().getTime()}`"
class="img-avatar"
crossOrigin="anonymous"
>
</div>
<div class="card-info">
<div class="card-name">
{{ form.name }}
</div>
<div>
{{ form.post }}
</div>
<div class="line" />
<div>
{{ form.address }}
</div>
<div class="card-phone">
{{ form.phone }}
</div>
<div class="qr-code" id="qrCodeCard" ref="qrCodeCardUrl" />
</div>
</div>
</div>
<div class="dialog-footer">
<el-button size="small" type="primary" @click="onExport" id="onExport">
导出
</el-button>
</div>
script
import html2canvas from 'html2canvas';
onExport() {
const clientWidth = this.$refs.imageWrapper.offsetWidth;
const clientHeight = this.$refs.imageWrapper.offsetHeight;
const kh = [clientWidth, clientHeight];
html2canvas(this.$refs.imageWrapper, { useCORS: true, logging: true }).then((canvas) => {
const dataURL = canvas.toDataURL('image/png');
this.download(dataURL, kh);
});
},
getUrlBase64(url, kh) {
return new Promise((resolve) => {
let canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.crossOrigin = 'Anonymous'; // 允许跨域
img.src = url;
img.onload = () => {
// eslint-disable-next-line prefer-destructuring
canvas.height = kh[1];
// eslint-disable-next-line prefer-destructuring
canvas.width = kh[0];
ctx.drawImage(img, 0, 0, kh[0], kh[1]);
const dataURL = canvas.toDataURL('image/png');
canvas = null;
resolve(dataURL);
};
});
},
download(imgUrl, kh) {
this.getUrlBase64(imgUrl, kh).then((base64) => {
const link = document.createElement('a');
link.href = base64;
link.download = `${this.currentRobot.nickname}名片.png`;
link.click();
});
},
建议
生成的图片背景默认为白色,可以通过backgroundColor属性修改背景颜色,使用如下:
html2canvas(this.$refs.imageDom, {
backgroundColor: null // null 表示设置背景为透明色
})
开发过程中遇到的坑 1.图片是远程服务器的,展示没有问题 但是导出的话会出现图片不显示。 解决办法:
html2canvas(this.$refs.imageWrapper ).then((canvas) => {
const dataURL = canvas.toDataURL('image/png');
this.download(dataURL, kh);
});
加上{ useCORS: true, logging: true }变成:
html2canvas(this.$refs.imageWrapper, { useCORS: true, logging: true }).then((canvas) => {
const dataURL = canvas.toDataURL('image/png');
this.download(dataURL, kh);
});
然后给图片的src加上动态的时间,并加上crossOrigin="anonymous"允许跨域
<img :src="`${avatarUrl}?${new Date().getTime()}`"
class="img-avatar"
crossOrigin="anonymous"
>
2.有些css的样式不能识别,比如box-shadow,(具体可查看文档)
目前不支持这些 CSS 属性
背景混合模式 * 边框图像 *盒子装饰打破 盒子阴影 筛选 字体变体连字 * 混合模式 对象适合 重复线性梯度() 写作模式 * 飞涨
上一篇: 深度剖析H5移动设备的精准适配技巧
下一篇: 移动设备端网页中iframe遇到了问题