vue实现html转化pdf并复制文字

 更新时间:2024年10月22日 09:56:41   作者:Z_Xshan  
这篇文章主要为大家详细介绍了vue实现html转化pdf的两种方式,分别为能复制文字和不能复制文字的方法,有需要的小伙伴可以跟随小编一起学习一下

一、html2canvas 和 jsPDF(图片插入pdf不可复制

创建pdf.js文件

代码如下

import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
import Vue from 'vue'
export const downloadPDF = (page, ne, isDownload) => {
  html2canvas(page, {
    allowTaint: true,
    taintTest: false,
    useCORS: true,
    // width:960,
    // height:5072,
    dpi: window.devicePixelRatio * 8, // 将分辨率提高到特定的DPI 提高四倍
    scale: 10 // 按比例增加分辨率
  }).then(function(canvas) {
    canvas2PDF(canvas, ne, isDownload)
  })
}
const canvas2PDF = (canvas, ne, isDownload) => {
  var contentWidth = canvas.width
  var contentHeight = canvas.height
  // 一页pdf显示html页面生成的canvas高度;
  var pageHeight = (contentWidth / 592.28) * 841.89
  // 未生成pdf的html页面高度
  var leftHeight = contentHeight
  // 页面偏移
  var position = 0
  // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
  var imgWidth = 595.28
  var imgHeight = (592.28 / contentWidth) * contentHeight
  var pageData = canvas.toDataURL('image/jpeg', 1.0)
  var 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();
      }
    }
  }
  console.log('PDF', PDF)
  if (isDownload) {
    PDF.save(ne + '.pdf') // 这里是导出的文件名
  } else {
    var pdfData = PDF.output('datauristring')
    Vue.prototype.$baseURL = pdfData
    // sessionStorage.setItem('base64URL',pdfData);
    console.log(1)
  }
}

使用

      <div class="pdf">
        <div ref="pdf" class="page">你好</div>
    </div>
 
//引入
import { downloadPDF, canvas2PDF } from '../../utils/pdf' // 工具方法,导出操作
 
 
handleExport() {  
  var zhis = this
      var dsq = setTimeout(() => {
        downloadPDF(this.$refs.pdf, `CUKH Tax Invoice - ${this.form.invoiceNo}`, true)
 
      }, 100)
}

二、window.print();方法打印(可复制)

安装

npm install vue-print-nb --save

手动下载插件到本地 

插件地址:https://github.com/xyl66/vuePlugs_printjs

在src下新建文件夹plugs,将下载好的print.js放入plugs文件夹下

printjs代码

//print.js 里的代码
// 打印类属性、方法定义
/* eslint-disable */
const Print =function(dom, options) {
    if (!(this instanceof Print)) return new Print(dom, options);
  
    this.options = this.extend({
      'noPrint': '.no-print'
    }, options);
  
    if ((typeof dom) === "string") {
      this.dom = document.querySelector(dom);
    } else {
      this.dom = dom;
    }
  
    this.init();
  };
  Print.prototype = {
  
    init: function () {
      var content = this.getStyle() + this.getHtml();
      this.writeIframe(content);
    },
    
    extend: function (obj, obj2) {
      for (var k in obj2) {
        obj[k] = obj2[k];
      }
      return obj;
    },
  
    getStyle: function () {
      var str = "",
        styles = document.querySelectorAll('style,link');
      for (var i = 0; i < styles.length; i++) {
        str += styles[i].outerHTML;
      }
      str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";
  
      return str;
    },
  
    getHtml: function () {
      var inputs = document.querySelectorAll('input');
      var textareas = document.querySelectorAll('textarea');
      var selects = document.querySelectorAll('select');
  
      for (var k in inputs) {
        if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
          if (inputs[k].checked == true) {
            inputs[k].setAttribute('checked', "checked")
          } else {
            inputs[k].removeAttribute('checked')
          }
        } else if (inputs[k].type == "text") {
          inputs[k].setAttribute('value', inputs[k].value)
        }
      }
  
      for (var k2 in textareas) {
        if (textareas[k2].type == 'textarea') {
          textareas[k2].innerHTML = textareas[k2].value
        }
      }
  
      for (var k3 in selects) {
        if (selects[k3].type == 'select-one') {
          var child = selects[k3].children;
          for (var i in child) {
            if (child[i].tagName == 'OPTION') {
              if (child[i].selected == true) {
                child[i].setAttribute('selected', "selected")
              } else {
                child[i].removeAttribute('selected')
              }
            }
          }
        }
      }
  
      return this.dom.outerHTML;
    },
  
    writeIframe: function (content) {
      var w, doc, iframe = document.createElement('iframe'),
          f = document.body.appendChild(iframe);
      iframe.id = "myIframe";
      iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
      
      w = f.contentWindow || f.contentDocument;
      doc = f.contentDocument || f.contentWindow.document;
      doc.open();
      doc.write(content);
      doc.close();
      this.toPrint(w);
      
      setTimeout(function () {
        document.body.removeChild(iframe)
      }, 100)
    },
    
    toPrint: function (frameWindow) {
      try {
        setTimeout(function () {
          frameWindow.focus();
          try {
            if (!frameWindow.document.execCommand('print', false, null)) {
              frameWindow.print();
            }
          } catch (e) {
            frameWindow.print();
          }
          frameWindow.close();
        }, 10);
      } catch (err) {
        console.log('err', err);
      }
    }
  };
  
  const MyPlugin = {}
  MyPlugin.install = function (Vue, options) {
    Vue.prototype.$print = Print
  }
  
  export default MyPlugin

main.js里引入

import Print from './plugs/print'
Vue.use(Print)

使用

      <div class="pdf">
        <div ref="pdf" class="page">你好</div>
    </div>
 
    handleExport() {
 
      setTimeout(() => {
                this.$print(this.$refs.pdf)
          }, 100);
 
    },

修改打印样式

样式可能会有偏差,或者位移可以添加样式去修改

@media print {
  @page {
        margin: 0 !important;
    }
   .pdf{
        position: fixed;
        top: -265px !important;
        left: -150px !important;
        transform: translate(-50%, -50%);
        transform: scale(0.7);
        box-shadow:none !important;
   }
 
  
  }

可能遇到的问题及解决方案

①图片占位置 ---------让它脱离文档流( position: absolute; 不要用fixed 这样内容多的时候只打印第一页)

②页面不想展示打印内容 只打印;------- 给它 z-index:-1 (display:none 的话打印内容也没有)

③指定不打印区域

方法1. 添加no-print样式类

方法2. 自定义类名

this.print( this.print(this.print(this.refs.print,{‘no-print':‘.do-not-print-me-xxx'}) 

到此这篇关于vue实现html转化pdf并复制文字的文章就介绍到这了,更多相关vue html转pdf内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue2.0+SVG实现音乐播放圆形进度条组件

    vue2.0+SVG实现音乐播放圆形进度条组件

    这篇文章主要为大家详细介绍了Vue2.0+SVG实现音乐播放圆形进度条组件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • vue中keep-alive,include的缓存问题

    vue中keep-alive,include的缓存问题

    这篇文章主要介绍了vue中keep-alive,include的缓存问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 详解vue项目打包后通过百度的BAE发布到网上的流程

    详解vue项目打包后通过百度的BAE发布到网上的流程

    这篇文章主要介绍了将vue的项目打包后通过百度的BAE发布到网上的流程,主要运用的技术是vue+express+git+百度的应用引擎BAE。需要的朋友可以参考下
    2018-03-03
  • Vue多布局模式实现方法详细讲解

    Vue多布局模式实现方法详细讲解

    这篇文章主要介绍了Vue多布局模式实现方法,多布局模式可以根据用户角色所在场景切换页面布局,是非常常见的基础功能,感兴趣的同学可以参考下文
    2023-05-05
  • 详解windows下vue-cli及webpack 构建网站(四) 路由vue-router的使用

    详解windows下vue-cli及webpack 构建网站(四) 路由vue-router的使用

    本篇文章主要介绍了windows下vue-cli及webpack 构建网站(四) 路由vue-router的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Vue实现登录以及登出详解

    Vue实现登录以及登出详解

    本篇文章主要介绍了vue实现登陆登出的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09
  • Vue3 组件间通信之mitt实现任意组件间通信的步骤

    Vue3 组件间通信之mitt实现任意组件间通信的步骤

    mitt 主要有4个API:emit(触发某个事件)、on(绑定事件)、off(解绑某个事件)、all(获取所有绑定的事件),这篇文章主要介绍了Vue3 组件间通信之mitt实现任意组件间通信,需要的朋友可以参考下
    2024-05-05
  • vue页面跳转后返回原页面初始位置方法

    vue页面跳转后返回原页面初始位置方法

    下面小编就为大家分享一篇vue页面跳转后返回原页面初始位置方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • Vue3+TS+Vite+NaiveUI搭建一个项目骨架实现

    Vue3+TS+Vite+NaiveUI搭建一个项目骨架实现

    本文主要介绍了Vue3+TS+Vite+NaiveUI搭建一个项目骨架实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Vue简化用户查询/添加功能的实现

    Vue简化用户查询/添加功能的实现

    本文主要介绍了Vue简化用户查询/添加功能的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01

最新评论