解决vue中html2canvas图⽚跨域问题HTML代码
<div id="pdfDom">
</div>
<script>
import htmlToPdf from '@/components/utils/htmlToPdf' //页⾯打印
export default {
methods: {
gethtmlToPdf(){
var title = 'tttt';//PDF的⽂件名
htmlToPdf.downloadPdf(title)
},
}
}
</script>
PDF打印插件
src/components/utils/htmlToPdf.js
//该部分代码是从⽹上的,然后根据我⾃⼰的需求,调试修改得来。
//本⼈系后端开发,前端接⼿不久,所以部分代码都是百度得来,请见谅。
// 导出页⾯为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default{
/
/有分页
getPdf(name){
window.pageYoffset = 0;
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
let shareContent = document.querySelector('#pdfDom'),//需要截图的包裹的(原⽣的)DOM 对象
width = shareContent.clientWidth, //获取dom 宽度
height = shareContent.clientHeight, //获取dom ⾼度
// height = canvas.height, //获取dom ⾼度
canvas = ateElement("canvas"), //创建⼀个canvas节点
scale = 1.5; //定义任意放⼤倍数⽀持⼩数
html2Canvas(shareContent, {
allowTaint: true,
// scale: scale, // 添加的scale 参数
// canvas: canvas, //⾃定义 canvas
logging: false, //⽇志开关,便于查看html2canvas的内部执⾏流程
// width: width, //dom 原始宽度
// height: height,
useCORS: true, // 【重要】开启跨域配置
scale : 1.5
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
//设置图⽚跨域访问
// img.setAttribute('crossOrigin', 'anonymous');
let pageData = DataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(name + '.pdf')
}
)
},
//test -- ⽆分页
downloadPdf(name) {
window.pageYoffset = 0;
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
let shareContent = document.querySelector('#pdfDom'),//需要截图的包裹的(原⽣的)DOM 对象
width = shareContent.clientWidth, //获取dom 宽度
height = shareContent.clientHeight, //获取dom ⾼度
// height = canvas.height, //获取dom ⾼度
canvas = ateElement("canvas"), //创建⼀个canvas节点
scale = 1.5; //定义任意放⼤倍数⽀持⼩数
// console.log(tt)
setTimeout(() => {
html2Canvas(shareContent, {
// allowTaint: false,这部分,最好还是不⽤,原因是,容易污染画布。
scale: 2.5, // 提升画⾯质量,但是会增加⽂件⼤⼩
useCORS: true, // 【重要】开启跨域配置
backgroundColor: "#fff", // ⼀定要添加背景颜⾊,否则出来的图⽚,背景全部都是透明的
/
/ foreignObjectRendering: true,
}).then(function (canvas) {
/**jspdf将html转为pdf⼀页显⽰不截断,整体思路:
* 1. 获取DOM
* 2. 将DOM转换为canvas
* 3. 获取canvas的宽度、⾼度(稍微⼤⼀点)
* 4. 将pdf的宽⾼设置为canvas的宽⾼
* 5. 将canvas转为图⽚
* 6. 实例化jspdf,将内容图⽚放在pdf中(因为内容宽⾼和pdf宽⾼⼀样,就只需要⼀页,也防⽌内容截断问题)
*/
登录页面背景图// 得到canvas画布的单位是px 像素单位
var contentWidth = canvas.width
var contentHeight = canvas.height
// 将canvas转为base64图⽚
var pageData = DataURL('image/jpeg', 1.0)
// 设置pdf的尺⼨,pdf要使⽤pt单位已知 1pt/1px = 0.75 pt = (px/scale)* 0.75
// 2为上⾯的scale 缩放了2倍
var pdfX = (contentWidth + 10) / 2 * 0.75
var pdfY = (contentHeight + 10) / 2 * 0.75 // 10为底部留⽩
// 设置内容图⽚的尺⼨,img是pt单位
var imgX = pdfX;
var imgY = (contentHeight / 2 * 0.75); //内容图⽚这⾥不需要留⽩的距离
/
/ 初始化jspdf 第⼀个参数⽅向:默认''时为纵向,第⼆个参数设置pdf内容图⽚使⽤的长度单位为pt,第三个参数为PDF的⼤⼩,单位是pt var PDF = new JsPDF('', 'pt', [pdfX, pdfY])
// 将内容图⽚添加到pdf中,因为内容宽⾼和pdf宽⾼⼀样,就只需要⼀页,位置就是 0,0
PDF.addImage(pageData, 'jpeg', 0, 0, imgX, imgY)
PDF.save(name+'.pdf')
})
}, 200);
},
}
以上代码,虽然可以打印成PDF,但是,如果页⾯中有引⼊外链的图⽚,⼊OSS上的图⽚,往往会出现跨域的问题。具体原因见下链接这是⼀个我觉得写得相对⽐较详细的⽂章
后来做了各种尝试,到了⼀个解决办法
修改HTML⾥的代码
gethtmlToPdf
<div id="pdfDom">
</div>
<script>
import htmlToPdf from '@/components/utils/htmlToPdf' //页⾯打印
export default {
methods: {
gethtmlToPdf(){
var title = this.$route.query.billNumber
let shareContent = document.querySelector('#pdfDom'); //定义任意放⼤倍数⽀持⼩数
let imgList = shareContent.querySelectorAll('img')
if (imgList){
var i;
for (i = 1; i < imgList.length; i++) {
imgList[i].src += '&timeSign='+w().toString()
console.log(imgList[i].src)
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open("get", imgList[i].src, true);
xhr.send();
}
}
// console.log(1)
htmlToPdf.downloadPdf(title)
},
} } </script>
如此即可,按我的理解,应该是此部分代码会重新打开⼀次图⽚,然后会直接刷新缓存中的连接,使其信息得以保全,所以在此访问不会出现跨域问题。
本⼈较懒,且前端专业知识不⾜,如果有⼤佬能够更详细的解释,请留下链接,谢谢!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论