html2canvas插件我相信很多人都用过,在使用的时候有很多坑,文章最后我会附上完整的vue3版本的代码(其实跟vue2代码差别很小,改一改就能拿去用)
关于vue 把页面转换成图片导出(html2canvas导出不全问题)我们首先要查看的是获取一下当前元素的高度,因为导出不全的问题很有可能是会被元素样式影响。
如:当我们使用项目中定义的全局class名,样式可能是这样的:
.flex-page {
display: flex;
flex-direction: column;
height: 100vh;
}
.flex-page-content {
flex: 1 1 auto;
overflow-y: auto;
}
解决办法就是:
.flex-page-content {
overflow-y: visible !important ;
}
.flex-page {
height: auto;
}
当我们使用ref获取页面元素的时候可能会出现获取不到的问题,请注意写法,vue3-ref是这样:
const postHtml = ref();
const posterHtml = postHtml.value;
页面中一定要把数据return出去;
return {
postHtml,
};
在调用html2canvas函数时,我们最好获取元素高度,确保生成图片时不会出现问题,height: domObj.clientHeight,
html2canvas(postHtml.value, {
height: postHtml.value.clientHeight,
})
关于报错:跨域问题解决 No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.,我们首先要确保html2canvas的调用函数中写了useCORS: true
html2canvas(postHtml.value, {
useCORS: true,
})
如果发现问题没有解决,那么我们要考虑把页面中的png格式改为base64
const imgTag = document.querySelectorAll('img');
// 获取base64编码
let base64 = '';
// 将页面的img的src值改为base64格式
imgTag.forEach((item, i) => {
const img = new Image();
img.src = imgTag[i].src;
img.onload = () => {
base64 = image2Base64(img);
imgTag[i].setAttribute('src', base64);
};
});
完整代码如下:
import html2canvas from 'html2canvas';
// 图片转为base64编码
function image2Base64(img: HTMLImageElement) {
// eslint-disable-next-line prefer-const
let canvas = document.createElement('canvas'); // 一定要设置为let,不然图片不显示
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx!.drawImage(img, 0, 0, img.width, img.height);
const dataURL = canvas.toDataURL('image/png');
return dataURL;
}
/** 导出/下载 二维码 */
const exportCodeConfirm = () => {
setTimeout(() => {
const event = new MouseEvent('click');
/** 触发a的单击事件 */
document.getElementById('myLink')!.dispatchEvent(event);
}, 0);
};
/** 根据URL下载图片 */
const downloadQRImg = (canvas: any, name: string) => {
/** 新Image对象,可以理解为DOM */
const image = new Image();
/** 解决跨域 Canvas 污染问题 */
image.setAttribute('crossOrigin', 'anonymous');
// image.onload = function() {
/** canvas.toDataURL 返回的是一串Base64编码的URL,指定格式 PNG */
const imgUrl = canvas.toDataURL('image/png');
image.src = imgUrl;
/** 生成一个a元素,并创建一个单击事件 */
const a = document.createElement('a');
a.download = name || 'photo'; // 设置图片名称
a.href = imgUrl; // 将生成的URL设置为a.href属性
a.setAttribute('id', 'myLink');
// 开发者工具查看生成的链接href的值是否是一个完整的base64格式图片
// console.log('标签', a);
document.body.appendChild(a);
exportCodeConfirm();
// }
};
/** 将html元素转换成海报图片 */
const createPoster = async () => {
const name = `会诊详情`;
const posterHtml = postHtml.value;
const imgTag = document.querySelectorAll('img');
// 获取base64编码
let base64 = '';
// 将页面的img的src值改为base64格式
imgTag.forEach((item, i) => {
const img = new Image();
img.src = imgTag[i].src;
img.onload = () => {
base64 = image2Base64(img);
imgTag[i].setAttribute('src', base64);
};
});
// 生成图片
const domObj = posterHtml;
await nextTick();
// 确保页面渲染完毕
setTimeout(() => {
html2canvas(domObj, {
allowTaint: true,
useCORS: true,
scrollY: -18,
scrollX: -0,
height: domObj.clientHeight,
}).then((itsCanvas) => {
// document.body.appendChild(itsCanvas);
downloadQRImg(itsCanvas, name);
});
}, 100);
};
整体页面代码:
肿瘤类型
{{ preSummary.tumorTypeName || '无' }}
临床分期
{{ preSummary.clinicalStages || '无' }}
本次主诉
{{ preSummary.chiefComplaint || '无' }}
主任建议
{{ preSummary.suggestion || '无' }}
建议解读
{{ preSummary.suggestionDetail || '无' }}
结合各专家意见如下
{{ summary[0].reasonName }}
会诊总结.pdf
{{ summary[0]?.providerName }}