vue页面生成pdf 完整demo 及其踩得坑

bug

  1. 导出图片不显示这里是图片跨域了 这里一般情况下都是用的html2canvas自带的方法 useCORS: true,(ps): 一般情况下不行看脸也有说是阿里的图片上传限制了只要去后置设置下请求限制就行了这也是一种方式ps:还是看脸我是不行,最后我的处理方式是直接将图片转为base64的编码形式就ok了
  2. 导出的内容多了会额外加一页这里的内容会被截断像这样u[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7ZF4Rzr-1656043014460)(https://itmg-blog.csdnimg.cn/276bed137984448c812208b88fceae78.png)]
    第二页就截断了这样不行

废话不多说直接上代码

一、添加依赖模块
npm install html2canvas --save
npm install jspdf --save
二、创建pdf.js全局函数文件

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install(Vue, options) {
    Vue.prototype.getPdf = function(idStr, title,callback) {
      html2Canvas(document.querySelector('#' + idStr), {
        // allowTaint: true,
        useCORS: true,
        allowTaint: true,
        taintTest: false,
        //width:960,
        //height:5072,
        dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
        scale: 4 //按比例增加分辨率
      }).then((canvas) => {
        const contentWidth = canvas.width
        const contentHeight = canvas.height
        // 一页pdf显示html页面生成的canvas高度;
        const pageHeight = contentWidth / 592.28 * 841.89
        // 生成pdf的html页面高度
        let leftHeight = contentHeight
        // 页面偏移
        let position = 0
        // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        const imgWidth = 595.28
        const imgHeight = 592.28 / contentWidth * contentHeight +100
        // canvas.crossOrigin="Anonymous";
        const pageData = canvas.toDataURL('image/jpeg', 1.0)
        // canvas.setAttribute("crossOrigin",'Anonymous')
        console.log(pageData);
        const PDF = new JsPDF('', 'pt', 'a4')
        console.log(PDF);
        // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
        // 当内容未超过pdf一页显示的范围,无需分页
        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(title + '.pdf')
      })
    }
  },




}

 ## 


三.引用方面

export(){

this.getPdf(‘content’, this.userInfos.username + ‘的简历’, async (file) => {
// file对象
})

}
第一个参数: content 是你要导出pdf的盒子的id
第二个参数是 导出简历的文件名
第三个回调没有用到可以忽略

第一个bug 导出没有图片跨域问题

imageUrl: ‘https://fcapp.fcw-china.com’, // 跨域地址
screenshotImage: ‘’, // 保存的base64地址

async shareHandle() {
const opts = {
useCORS: true
}
const ele = this. r e f s . s c r e e n s h o t c o n s t c a n v a s = a w a i t h t m l 2 C a n v a s ( t h i s . refs.screenshot const canvas = await html2Canvas(this. refs.screenshotconstcanvas=awaithtml2Canvas(this.refs.screenshot, opts)
this.screenshotImage = canvas.toDataURL(‘image/jpg’)
},
调用即可

这个是导出的图片这里要转为base64 的编码在导出pdf ps 其实导出pdf也是转为base64我直接复制base64 的编码直接浏览器请求就可以得到这个图片

第一个bug 导出内容会被截断

     outPutPdfFn () {
              let vm = this
              const A4_WIDTH = 592.28
              const A4_HEIGHT = 841.89
              vm.$nextTick(async () => {
                let target = vm.$refs.content
                let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT
                let lableListID = document.getElementsByClassName('userItem')
                for (let i = 0; i < lableListID.length; i++) {
                  let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight)
                  if (this.isSplit(lableListID, i, multiple * pageHeight)) {
                    let divParent = lableListID[i].parentNode // 获取该div的父节点
                    let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight)
                    let newNode = vm.getFooterElement(_H)
                    let next = lableListID[i].nextSibling // 获取div的下一个兄弟节点
                    // 判断兄弟节点是否存在
                    if (next) {
                      // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
                      divParent.insertBefore(newNode, next)
                    } else {
                      // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
                      divParent.appendChild(newNode)
                    }
                  }
                }
                vm.getPdf('content', this.userInfos.username + '的简历', async (file) => {
                  // file对象
                })
              })
            },

//这个方法是为了截取底部的距离然后插入一个白底本来是
getFooterElement (remainingHeight, fillingHeight = 85) {
let newNode = document.createElement(‘div’);
newNode.className=‘cutArea’
// newNode.style.background = ‘#ffffff’
newNode.style.width = ‘calc(100% + 8px)’
newNode.style.marginLeft = ‘-4px’
newNode.style.marginBottom = ‘0px’
// newNode.style.borderTop = ‘1px solid #7F7F7F’
newNode.style.height = (remainingHeight + fillingHeight) + ‘px’ // pdf截断需要一个空白位置
this.timer = setInterval(() => {
$(“.cutArea”).css(‘display’, ‘none’);
}, 1000);
return newNode
},

每一个元素的高度都是不一样的所以这里只能根据useritem 去截 然后插入一个div隔断

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值