实现页面以pdf的形式展示和html以pdf形式导出

vue-pdf的使用

相关链接:https://www.cnblogs.com/lodadssd/p/10297989.html
之前的博客写过,所以这一次我就不废话,直接贴代码

<!--
 * @Descripttion: your project
 * @version: 1.0
 * @Author: Aidam_Bo
 * @Date: 2021-08-23 15:29:15
 * @LastEditors: Aidam_Bo
 * @LastEditTime: 2021-08-25 11:02:36
-->
<template>
  <div class="pdf" v-show="fileType === 'pdf'">
    <p class="arrow">
      <!-- // 上一页 -->
      <span
        @click="changePdfPage(0)"
        class="turn"
        :class="{ grey: currentPage == 1 }"
        >上一页</span
      >
      {{ currentPage }} / {{ pageCount }}
      <!-- // 下一页 -->
      <span
        @click="changePdfPage(1)"
        class="turn"
        :class="{ grey: currentPage == pageCount }"
        >下一页</span
      >
      <router-link :to="{name:'changepdf'}">pdf导出1</router-link>
      <router-link :to="{name:'pdfshow'}">pdf导出2</router-link>
      <!-- <router-link :to="{name:'changeword'}">word导出</router-link> -->
    </p>
    <!-- // 自己引入就可以使用,这里我的需求是做了分页功能,如果不需要分页功能,只要src就可以了 -->
    <div class="pdf" style="width='60%'">
      <pdf
        id="exportPdf"
        ref="exportPdf"
        :src="src"
        :page="currentPage"
        @num-pages="pageCount = $event"
        @page-loaded="currentPage = $event"
        @loaded="loadPdfHandler"
      >
      </pdf>
    </div>
  </div>
</template>

<script>
import pdf from "vue-pdf";
export default {
  components: {
    pdf,
  },
  data() {
    return {
      printObj:{
        id:'printer',
        popTitle:'11',
          extraCss: 'https://www.google.com,https://www.google.com',
        extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>'
      },
      currentPage: 0,
      pageCount: 0,
      fileType: "pdf",
      src: "http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf",
    };
  },
  created() {
    // 有时PDF文件地址会出现跨域的情况,这里最好处理一下
    this.src = pdf.createLoadingTask(this.src);
  },
  methods: {
    // 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
    changePdfPage(val) {
      // console.log(val)
      if (val === 0 && this.currentPage > 1) {
        this.currentPage--;
        // console.log(this.currentPage)
      }
      if (val === 1 && this.currentPage < this.pageCount) {
        this.currentPage++;
        // console.log(this.currentPage)
      }
    },

    // pdf加载时
    loadPdfHandler(e) {
      this.currentPage = 1; // 加载的时候先加载第一页
    },
  },
};
</script>

html转pdf导出

相关链接:https://www.cnblogs.com/taohuaya/p/10805585.html
我在各个网站找到了三个方法
第一种:html2canvas.js
插件:npm i html2canvas jspdf --save-dev

<template>
    <div class="pdf-demo">

        <button @click="handleDown">jsPDF方式下载</button>

        <div id="demo" >

                #demo 中的内容导出成 PDF


        </div>


    </div>
</template>

创建htmlToPdf.js

import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';

/**
 * @param  ele          要生成 pdf 的DOM元素(容器)
 * @param  padfName     PDF文件生成后的文件名字
 * */

function downloadPDF(ele, pdfName){

    let eleW = ele.offsetWidth;// 获得该容器的宽
    let eleH = ele.offsetHeight;// 获得该容器的高


    let eleOffsetTop = ele.offsetTop;  // 获得该容器到文档顶部的距离
    let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离

    var canvas = document.createElement("canvas");
    var abs = 0;

    let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)
    let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)

    if(win_out>win_in){
        // abs = (win_o - win_i)/2;    // 获得滚动条长度的一半
        abs = (win_out - win_in)/2;    // 获得滚动条宽度的一半
        // console.log(a, '新abs');
    }

    canvas.width = eleW * 2;    // 将画布宽&&高放大两倍
    canvas.height = eleH * 2;




    var context = canvas.getContext("2d");

    context.scale(2, 2);

    context.translate(-eleOffsetLeft -abs, -eleOffsetTop);
    // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此
    // translate的时候,要把这个差值去掉

    // html2canvas(element).then( (canvas)=>{ //报错
    // html2canvas(element[0]).then( (canvas)=>{
    html2canvas( ele, {
        dpi: 300,
        // allowTaint: true,  //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的
        useCORS:true  //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
    } ).then( (canvas)=>{

        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 = 595.28/contentWidth * contentHeight;

        var pageData = canvas.toDataURL('image/jpeg', 1.0);



        var pdf = new JsPDF('', 'pt', 'a4');

        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围,无需分页
        if (leftHeight < pageHeight) {
            //在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示;
            pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
            // pdf.addImage(pageData, 'JPEG', 20, 40, 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(pdfName);
    })


}


export default {
    downloadPDF
}

引入到需要的页面

import htmlToPdf from "../untils/htmlToPdf";

methods: {
    handleDown() {
      //导出PDF
      htmlToPdf.downloadPDF(document.querySelector("#demo"), "我的PDF");
    },
   }

以浏览器形式导出

<button @click="handleWindowPrint('#demo', '电子合同')">
<div id="demo">需要的代码</div>
methods:{
	handleWindowPrint(ele, fileName) {
      var oIframe = document.createElement("iframe");
      var oScript = document.createElement("script");

      document.body.appendChild(oIframe);

      var titleText = document.head.getElementsByTagName("title")[0].innerText;
      document.head.getElementsByTagName("title")[0].innerText = `${fileName}`;

      oIframe.contentDocument.head.innerHTML = `<meta charset="utf-8">
                                              <title>${fileName}</title>
                                              <meta name="format-detection" content="telephone=no">
                                              <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                                              <meta name="viewport" content="width=device-width,initial-scale=1.0">`;

      // oIframe.contentWindow.document.body.innerHTML = document.querySelector(ele).outerHTML;
      oIframe.contentDocument.body.innerHTML =
        document.querySelector(ele).outerHTML;
      oScript.innerHTML = "window.print();";
      oIframe.contentDocument.body.appendChild(oScript);
      document.body.removeChild(oIframe);
      document.head.getElementsByTagName("title")[0].innerText = titleText;
    },
}

第三种
插件npm i vue-to-pdf --save
main.js

import vueToPdf from 'vue-to-pdf';
Vue.use(vueToPdf);
<template>
  <div>
    <button @click="goBack()">返回</button>
    <button @click="savePdf()">导出pdf</button>
    <div style="width: 100%; padding: 10px">
      <table
        style="width: 1000px"
        align="center"
        width="100%"
        border="1"
        ref="exportPdf"
      >
        <tbody>
          <tr>
            <th colspan="10" class="zxstyle ly">
              计算机专业(专业代码:456454)
            </th>
          </tr>
          <tr>
            <th class="zxstyle">课程类型</th>
            <th class="zxstyle">序号</th>
            <th class="zxstyle">课程代码</th>
            <th class="zxstyle">课程名称</th>
            <th class="zxstyle">学分</th>
            <th class="zxstyle">教材名称</th>
            <th class="zxstyle">主编</th>
            <th class="zxstyle">出版社</th>
            <th class="zxstyle">版次</th>
            <th class="zxstyle">备注</th>
          </tr>
          <tr v-for="(item, index) in sjList" :key="item.id">
            <td
              align="center"
              :rowspan="item.kclxspan"
              :class="{ hidden: item.kclxdis }"
            >
              {{ item.kclx }}
            </td>
            <td>{{ index + 1 }}</td>
            <td>{{ item.kcdm }}</td>
            <td>{{ item.kcmc }}</td>
            <td>{{ item.xf }}</td>
            <td>{{ item.cjmc }}</td>
            <td>{{ item.zb }}</td>
            <td>{{ item.cbs }}</td>
            <td>{{ item.bc }}</td>
            <td>{{ item.bz }}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>
<script>
export default {
  name: "pdf",
  data: function () {
    return {
      sjList: [
        {
          kclx: "公共课",
          kcdm: "000015",
          kcmc: "语文",
          xf: "14",
          cjmc: "语文",
          zb: "张宏",
          cbs: "北京大学出版社",
          bc: "2025",
          bz: "无",
        },
        {
          kclx: "公共课",
          kcdm: "000013",
          kcmc: "英语",
          xf: "52",
          cjmc: "英语",
          zb: "张近东",
          cbs: "北京大学出版社",
          bc: "2027",
          bz: "无",
        },
        {
          kclx: "公共课",
          kcdm: "000019",
          kcmc: "数学",
          xf: "14",
          cjmc: "数学",
          zb: "阿斯蒂",
          cbs: "北京大学出版社",
          bc: "2028",
          bz: "无",
        },
        {
          kclx: "考核课",
          kcdm: "000056",
          kcmc: "物理",
          xf: "11",
          cjmc: "物理",
          zb: "萨蒂",
          cbs: "北京大学出版社",
          bc: "2029",
          bz: "无",
        },
        {
          kclx: "考核课",
          kcdm: "000045",
          kcmc: "化学",
          xf: "14",
          cjmc: "化学",
          zb: "名点",
          cbs: "北京大学出版社",
          bc: "2027",
          bz: "无",
        },
        {
          kclx: "公共课",
          kcdm: "000085",
          kcmc: "生物",
          xf: "36",
          cjmc: "生物",
          zb: "张炯",
          cbs: "北京大学出版社",
          bc: "2028",
          bz: "无",
        },
      ],
    };
  },

  methods: {
    // 导出为pdf
    savePdf() {
      this.$PDFSave(this.$refs.exportPdf, "文件名称");
    },
    goBack() {
      this.$router.go(-1);
    },
  },
};
</script>
<style scoped>
.hidden {
  display: none;
}

table {
  border-collapse: collapse;
  margin: 0 auto;
  text-align: center;
}
table td,
table th {
  border: 1px solid #cad9ea;
  color: #666;
  height: 30px;
}
table thead th {
  background-color: #cce8eb;
  width: 100px;
}
table tr:nth-child(odd) {
  background: #fff;
}
table tr:nth-child(even) {
  background: #f5fafa;
}
</style>

效果图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值