分享

纯前端导出pdf (完全不需要后端)

 hncdman 2023-02-14 发布于湖南

一、vue-print-nb插件

npm install vue-print-nb --save

1

//在main.js中

import Print from 'vue-print-nb'

Vue.use(Print);

1

2

直接在vue中使用即可

<template>

  <div class="home">

    <button v-print="printObj">导出pdf</button>

    <div id="printMe" style="background:red;">

      <p style="color:green;">评标区</p>

      <h1 style="font-size:20px;color:blue;">标题</h1>

      <img alt="Vue logo" src="../assets/logo.png" />

      <HelloWorld msg="Welcome to Your Vue.js App" />

    </div>

  </div>

</template>


二、window.print()方法

//直接使用

function printpage(){

    window.print();

    }


三、html2canvas+jspdf(分页+ 不分页)

使用这种方式需要注意的是 根据需求, 如果需求的每页有一定的高度可以使用分页的方式更加美观, 但如果高度是动态的 建议使用不分页的方式 不会造成页面被裁切.

分页

// 导出页面为PDF格式

import html2Canvas from 'html2canvas'

import JsPDF from 'jspdf'

export default{

    install (Vue, options) {

        Vue.prototype.getPdf = function () {

            allowTaint: true;

            var title = this.htmlTitle;

            var element = document.getElementById("printMe");    // 这个dom元素是要导出pdf的div容器

            var w = element.offsetWidth;    // 获得该容器的宽

            var h = element.offsetWidth;    // 获得该容器的高

            var offsetTop = element.offsetTop;    // 获得该容器到文档顶部的距离

            var offsetLeft = element.offsetLeft;    // 获得该容器到文档最左的距离

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

            var abs = 0;

            var win_i =  document.body.clientWidth;    // 获得当前可视窗口的宽度(不包含滚动条)

            var win_o = window.innerWidth;    // 获得当前窗口的宽度(包含滚动条)

            if (win_o > win_i) {

                abs = (win_o - win_i) / 2;    // 获得滚动条长度的一半

            }

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

            canvas.height = h * 2;

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

            context.scale(2, 2);

            context.translate(-offsetLeft - abs, -offsetTop);

            // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此

            // translate的时候,要把这个差值去掉

            html2Canvas(element,{

                allowTaint: true,  //允许跨域

                useCORS: true,  //允许图片跨域

                scale: 2 // 提升画面质量,但是会增加文件大小

            }).then(function (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 = 592.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', 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');

            });

        }

    }

}


不分页

 toImage() {

      // 第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等

      window.pageYoffset = 0;

      document.documentElement.scrollTop = 0;

      document.body.scrollTop = 0;

      html2canvas(document.getElementById("printMe"), {

        backgroundColor: "white",

        useCORS: true, //支持图片跨域

        scale: 1, //设置放大的倍数

        width: 1136,

        scrollY: 0,

        scrollX: 0,

        // height:100000,

        windowHeight: document.getElementById("printMe").scrollHeight,

      }).then((canvas) => {

        // 生成图片导出

        // const a = document.createElement("a");

        // a.href = canvas.toDataURL("image/png");

        // a.download = this.title;

        // a.click();

        // 生成pdf导出

        var shareContent = document.querySelector("#printMe");

        var width = shareContent.offsetWidth / 4;

        var height = shareContent.offsetHeight / 4;

        // console.log(height);

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

        var img = new Image();

        img.setAttribute("src", pageData);

        img.onload = function () {

          // 获取dom高度、宽度

          img.width = img.width / 2;

          img.height = img.height / 2;

          img.style.transform = "scale(0.5)";

          if (width > height) {

            // 此可以根据打印的大小进行自动调节

            // eslint-disable-next-line

            var pdf = new jsPDF("l", "mm", [width * 0.3, height * 0.3]);

          } else {

            // eslint-disable-next-line

            var pdf = new jsPDF("p", "mm", [width * 0.3, height * 0.3]);

          }

          pdf.addImage(pageData, "jpeg", 0, 0, width * 0.3, height * 0.3);

          pdf.save("导出的报表名字" + ".pdf");

        };

      });

    },

使用 html2canvas+jspdf 踩坑记

在vue项目中用html2canvas遇到因为有滚动条截图不完整问题的解决方法(设置height和windowHeight)

在生成图片前让页面滚动到最顶端.

window.pageYoffset = 0;

document.documentElement.scrollTop = 0;

document.body.scrollTop = 0;


如果仍然无法解决,则可以:

html2canvas(document.getElementById('dialog'), {

      backgroundColor: 'white',

      useCORS: true, //支持图片跨域

      scale: 1, //设置放大的倍数

      height: document.getElementById('dialog').scrollHeight,

      windowHeight: document.getElementById('dialog').scrollHeight

    })


图片跨域问题

1.在img标签上添加 crossorigin=“anonymous” 属性。允许图片跨域 不过设置这个之后,图片会无法显示 会报错

Redirect at origin 'http://sub1.' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://sub2.' is therefore not allowed access.

1

这是因为你img是在缓存数据中 读取的 并没有访问远程这个图片的时候没有携带请求头。可以在图片路径上拼接上固定 字符串 '?any_string_is_ok’

 <img

        class="companyLogo"

       

        :src="indexPreviewData.companyInfo.logo + '?any_string_is_ok'"

      />


注意一定是固定字符串 。如果是随机字符串的话会导致CDN的缓存被击穿

2.使用 html2Canvas的时候 需要配置useCORS为 true

这个属性是 html2Canvas 开启跨域用的 可以在html2Canvas的文档上找到

canvas画布在主流浏览器中的尺寸限制

在IOS10下,自带浏览器和微信下,超过40964096像素则显示不了红色方块;

HUAWEI NXT-TL00手机自带浏览器和UC浏览器下,不能超过81928192像素;

在PC,CHROME浏览器,360浏览器,不能超过1638416384像素;

搜狗浏览器,要比1638416384稍微小一些;

firefox,最大数在11164*11164左右;

IE11、EDGE浏览器,没找到极限,只不过越大电脑越慢内存消耗严重;

总结

各有各的优势与缺陷, 一般情况下最好前后端使用文件流的方式导出最合适!!!

————————————————

版权声明:本文为CSDN博主「今天秃头了吗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/m0_54967474/article/details/123820384

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多