ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

将Vue页面导出为pdf格式并进行下载

2022-02-23 15:04:47  阅读:413  来源: 互联网

标签:canvas Vue const setup html props pdf 页面


1.使用npm下载两个插件

a.将html页面转换成图片
npm install --save html2canvas 
b.将图片生成pdf
npm install jspdf --save

或者直接使用cdn

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-alpha1/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.min.js"></script> 

html部分

<template>
  <div class="">
    <div @click="downLoadPdf">下载pdf文件</div>
    <!--  -->
    <button type="button" class="btn btn-primary" v-on:click="getPdf()">导出PDF分页</button>
    <div class="pdf_warp">
      <div id="pdfDom">
        <h1>vue项目中使用pdf.js预览pdf文件(流)</h1>
        <p class="">
          好一段时间没有来简书写东西了,因为来到了平安银行(橙信)工作了,工作也比较忙,上班也没得外网,最近公司给配置了一个mac电脑,终于可以有外网权限了,但还是有很多限制,微信,百度云盘等等吧,都用不了,
          最近项目中需要显示保险的电子保单,但给的地址是一个pdf文件流,遇到了各种问题,跨域、android手机打不开......,最终选择了pdf.js插件,viewer.html?file=的形式打开,下面详情介绍一下开发步骤,
          
        </p>
        <p>一、 首先是导入插件,从官网直接下载,链接:官网直接下载,在vue项目中,注意放在static文件目录下</p>
        <div class="img_warp">
          <img src="../../../assets/4369687-c90a77c68fc6e04a.webp" alt="">
        </div>
        <p>简单介绍一下pdf.js目录,核心的pdf.js和pdf.worker.js,以及展示pdf的viewer.html页面,把它们作为静态资源来编译,基本想要的build和web这两个重要文件夹的东西都正常编译。</p>
        <p>二、重点介绍一下viewer.html?file=打开pdf文件</p>
        <p>1、打开viewer.js看看</p>
        <div class="js_warp">
          <p>"use strict";</p>
          <p>var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf';</p>
          <p>var pdfjsWebApp = void 0;</p>
        </div>
        <p>里面有配置项,DEFAULT_URL 是默认的pdf路径,继续看源代码,发现他可以通过file参数用来指定pdf的路径</p>
        <p>用viewer.html?file= 的方式,我是iframe进行嵌套</p>
        <!-- <div class="js_warp">
          <p><iframe :src="url" width="100%" height="100%"></iframe></p>
        </div> -->
        <p>2、当viewer.html页面的域和pdf文件域不一致的时候,会报 “file origin does not match viewer”错误。 所以我们得改变一下源码</p>
        <div class="img_warp">
          <img src="../../../assets/cw1.webp" alt="">
        </div>
        <p>3、file=后面跟的pdf地址也有参数,所以必须选择 encodeURIComponent 进行对url的编码</p>
        <div class="js_warp">
          <p>this.url = `${baseUrl.pageRoot}pdf/web/viewer.html?file=${encodeURIComponent(pdfUrl)}`</p>
        </div>
        <p>viewer.js里有方法parseQueryString(query)取到这个pdf文件地址后,会进行decodeURIComponent解码</p>
        <p>4、如果还是打不开pdf文件,pdf.js插件可能无法识别pdfUrl,所以的在最后加上 &.pdf 来骗过插件</p>
        <p>Q: 目前还遇到一个问题,GET请求pdfUrl时,cookie信息没有带给后端,目前是让后端直接屏蔽了登录验证,请各位指教。GET请求源码如下:</p>

        <h1>vue3基础</h1>
        <h2>一、setup</h2>
        <p>1.setup函数可以被理解为函数的入口</p>
        <p>2.setup函数接收两个参数:props、context(包含attrs、slots、emit)</p>
        <p>3.setup函数是处于生命周期函数 beforeCreate之前执行,执行setup函数时组件实例并未被创建,this不指向vue实例</p>
        <p>4.与模板一起使用:须在ref或reactive中声明然后return出去使用才是响应式的</p>
        <p>5.使用渲染函数:可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态</p>
        <h2>二、setup第一个参数props</h2>
        <p>props 是响应式的,当传入新的 prop 时,它将被更新。</p>
        <div class="js_warp">
          <p>export default {</p>
          <p>props: {</p>
          <p>title: String</p>
          <p> },</p>
          <p>setup(props) {</p>
          <p>console.log(props.title)</p>
          <p>}</p>
          <p>}</p>
        </div>
        <h2>因为 props 是响应式的,不能使用 ES6 解构,会消除 prop 的响应性。</h2>
        <p>如果需要解构 prop,可以在 setup 函数中使用 [toRefs]函数来完成此操作:</p>
        <div class="js_warp">
          <p>setup(props) {</p>
          <p> const { title } = toRefs(props)</p>
          <p> return{ title  }</p>
          <p> },</p>
        </div>
        <h2>三、setup第二个参数context</h2>
        <p>context 是一个普通 JavaScript 对象,暴露了其它可能在 setup 中有用的值</p>
        <div class="js_warp">
          <p>setup(props, context) {</p>
          <p>// Attribute (非响应式对象,等同于 $attrs)</p>
          <p>console.log(context.attrs)</p>
          <p> // 插槽 (非响应式对象,等同于 $slots)</p>
          <p>console.log(context.slots)</p>
          <p>// 触发事件 (方法,等同于 $emit)</p>
          <p>console.log(context.emit)</p>
          <p>// 暴露公共 property (函数)</p>
          <p>console.log(context.expose)</p>
          <p>}</p>
        </div>
        <h2>context不是响应的,可以用ES6进行解构</h2>

        <div ref="footer"></div>
      </div>
    </div>
 
  </div>
</template>
dom转pdf-转出内容

可以有两种方式导出 

引入基础模块

import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
  data() { 
    return {
      htmlTitle: '页面导出PDF文件名',  //这个也是固定写法,pdf文件下载的名称
  },

  1:第一种不分页面

 methods:{
  // 下载pdf文件 不分页
    downLoadPdf(){
        window.scrollTo(0, 0);  
        const element = document.querySelector('#pdfDom')  ;// 这个dom元素是要导出pdf的div容器
        setTimeout(() => { 
          html2canvas(element, {  
            height: this.$refs.footer.offsetTop,
            useCORS: true // 如果说所生成的页面中带有跨域的图片,这个useCors需要设置为True 否则画布被污染不会显示
          }).then((canvas) => {
            console.log(canvas);
            const contentWidth = canvas.width;
            const contentHeight = canvas.height;
            // 一页pdf显示html页面生成的canvas高度;
            const pdfX = (contentWidth + 100) / 2 //* 0.975;
            const pdfY =  (contentHeight + 100) / 2 //* 0.975;// 500为底部留白
            const imgX = pdfX;
            const imgY = (contentHeight / 2);// 内  * 0.75
            const pageData = canvas.toDataURL('image/png', 1.0);
            const pdf = new jsPDF('', 'pt', [pdfX, pdfY]);
            // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
            // 内容未超过pdf一页显示的范围,无需分页
            pdf.addImage(pageData, 'png', 0, 0, imgX, imgY);
            pdf.save(12 + '.pdf'); // 生成的文件名字
          })
        },10)
    },
}

导出效果:

 

 

 

 2:第二种 导出pdf分页

 methods:{
    
    // 下载pdf文件 分页
    getPdf(){
      var title = this.htmlTitle
      html2canvas(document.querySelector('#pdfDom'), {
        allowTaint: true,
        useCORS: true
      }).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 = 580.28 / contentWidth * contentHeight
        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(title + '.pdf')
      }
      )
    },
}

导出效果:

 

标签:canvas,Vue,const,setup,html,props,pdf,页面
来源: https://www.cnblogs.com/lst619247/p/15927408.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有