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 = document.createElement("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 = canvas.toDataURL('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 = document.createElement("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 = canvas.toDataURL('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='+Date.now().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>
如此即可,按我的理解,应该是此部分代码会重新打开一次图片,然后会直接刷新缓存中的连接,使其信息得以保全,所以在此访问不会出现跨域问题。
本人较懒,且前端专业知识不足,如果有大佬能够更详细的解释,请留下链接,谢谢!