首页 > 其他分享 >VUE框架中实现HTML页面(局部)内容转PDF下载

VUE框架中实现HTML页面(局部)内容转PDF下载

时间:2023-04-14 20:48:10浏览次数:53  
标签:style VUE fileName HTML scale pdf var PDF

有一朋友想把网页内容变成PDF下载下来。问我有没有好办法。

这还真巧了,咱公司也有这个需求,就是网页生成合同,然后可以直接打印合同内容。最早吧,就是可以直接打印就好了。

当时为解决完美打印的问题,挺费劲的,当时第三方插件还有BUG(当然把解决放给发给作者了,作者早已经修复了),正经反复折腾了好一阵子。

就留了篇帖子《VUE实现HTML页面局部内容的打印(print.js),出现多打印一个空白页的问题》记录一下当时踩的坑,也希望能帮到更有需要的人。

后来校区门店想要可以选择,要么直接打印,要么保存PDF,以备日后存档和打印。

这次比较顺利,至少没怎么采坑,直接就搞定了。借着这次机会,也简单整理下,希望可以帮助有需要的人吧。

 

简单步骤如下:

一、先下载JS文件(文末附源码),保存到项目目录中

二、下载两个类库

cnpm install --save html2canvas
cnpm install jspdf --save

三、引入下载的htmlToPdf.js文件,在_main.js文件中导入

import htmlToPdf from '../libs/js/htmlToPdf.js';
Vue.use(htmlToPdf);

四、直接使用 this.getPdf() 调用函数即可

// nodeName:节点名称(要打印的内容)
// fileName:要生成的pdf文件名,不包含(.pdf)扩展名
// scale:PDF文字的清晰度
// style:自定义样式,根据需要,可以传入样式对要打印的对象进行一定的设定
let fileName = '合同' + EUtils.dateFormat(new Date(), 'yyyymmddhhiiss');// 生成pdf文件名,格式:合同年月日时分秒
this.getPdf('#auditionOrder', fileName);// nodeName, fileName, scale, style 此方法一共四个参数,一般前两个参数基本就满足绝大部分需求了

看上去够简单了吧?对于这次问题的解决,相对的,前期确实比较顺利,但是生成的PDF文件的内容样式调整确实还需要耗费精力去精雕细琢。

当然,这就没有技术难度了,就是一个经验和耐心的活了,不在这里描述了。

 

附htmlToPdf.js源码

/**
 * 通用html转PDF文件
 * 
 * 需要先下载两个插件,才可以正常使用
 * cnpm install --save html2canvas
 * cnpm install jspdf --save
 * 
 * 在需要使用的地方,直接调用this.getPdf(nodeName, fileName, scale, style);
 * nodeName,页面中需要转成PDF文件的内容部分定义id属性,id属性值
 * fileName,要生成的pdf文件名,不包含(pdf)扩展名
 * scale,PDF文字的清晰度
 * style,自定义样式,根据需要,可以传入样式对要打印的对象进行一定的设定
 * 例如:this.getPdf('#nodeId' 'PDF文件名');
 */
/* eslint-disable */
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';

export default {
    install(Vue, options) {
        Vue.prototype.getPdf = function(nodeName, fileName, scale, style) {
            // 导出之前先将滚动条置顶,不然会出现数据不全的现象
            window.pageYOffset = 0;
            document.documentElement.scrollTop = 0
            document.body.scrollTop = 0

            // loading提示信息
            this.$Message.config({top:500});
            var downloadPdfMsg = this.$Message.loading({
                content : 'PDF文件生成中...',
                duration : 0,
            });
            // 要转化的数据
            var html2Pdf = nodeName ? document.querySelector(nodeName) : document.body;// 要转换的数据(没有传入指定节点,则默认转换整个页面)
            
            if (style) { // 如果传入自定义样式
                html2Pdf.style.cssText = style;
            }
 
            // 参数配置
            var opts = {
                allowTaint: true,//允许加载跨域的图片
                taintTest: true, //检测每张图片都已经加载完成
                scale: scale || 3, // 添加的scale 参数
                logging: false, //日志开关,发布的时候记得改成false
                useCORS: false
            };
            html2Canvas(html2Pdf, opts).then((canvas) => {
                var contentWidth = canvas.width;
                var contentHeight = canvas.height;
                var pageHeight = contentWidth / 592.28 * 841.89;//一页pdf显示html页面生成的canvas高度
                var leftHeight = contentHeight;
                var position = 0;
                var imgWidth = 595.28;// A4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                var imgHeight = 592.28 / contentWidth * contentHeight;
 
                var pageData = new Image();
                //设置图片跨域访问
                pageData.setAttribute('crossOrigin', 'Anonymous');
 
                setTimeout(() => {
                    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();
                            }
                        }
                    }
                    setTimeout(downloadPdfMsg, 500);// 关闭loading提示
                    PDF.save((fileName ? fileName : new Date().getTime()) + '.pdf');// 如果没有传入要生成的文件名,则默认使用当前时间戳作为文件名
                }, 1000);
            })
        }
    }
}

 

标签:style,VUE,fileName,HTML,scale,pdf,var,PDF
From: https://www.cnblogs.com/leafinwind/p/17319864.html

相关文章

  • vue3微信公众号商城项目实战系列(4)第一个页面
    在开始写第一个页面之前,先简单看下index.html、App.vue、main.js、HelloWorld.vue、TheWelcome.vue、WelcomeItem.vue这几个页面及文件是怎么运作的,然后再新建2个页面,完成从一个页面跳转到另一个页面这个最简单的操作。 index.html和main.js代码如下:index.html文件的......
  • Vue Props 定义类型时报对象属性 unknown 错误
    如上图所示,在模板中使用itemprop时,surface属性是unknown类型。下面是props类型定义:typeIWorks=Partial<{id:string;text:string;content:string;desc:string;date:string;view:string;comm:string;digg:string;surface:string;......
  • 【专题】2022年中国制造业数字化转型研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=32145原文出处:拓端数据公众号本文中所说的制造业数字化转型,指的是在制造企业的设计、生产、管理、销售及服务的每一个环节中,将新一代信息技术应用到制造企业的设计、生产、管理、销售及服务的每一个环节中,并可以以每一个环节中产生的数据为基础,展开......
  • Vue之 vue-router
    目录简介安装vue-router使用vue-routerrouter的方法路由跳转方法一使用js控制方法二使用标签控制路由跳转携带参数方法一使用问号携带方法二使用斜杠分隔符携带方法三使用对象的方式跳转方法四标签方式跳转携带参数router与route的区别多级路由路由守卫全局路由守卫前置路由......
  • eclipse把非标准类型的html加进去
    把非标准的html类型加进去......
  • vue路由传值总结
    路由传值总结1.路由导航:在router.js中配置路由的path为/XXX/:id的方式,在路由跳转的时候,设置路径/XXX/123即可跳转接收通过this.$route.params.id 即可拿到1232.params传参:通过this.$router.push传参,配置name匹配路由name属性,设置params对象,内部为传入......
  • vue中使用jsx
    前言相对来说有些时候用jsx更合适,更灵活些安装依赖有对应的包支持yarnadd--dev@vitejs/plugin-vue-jsx配置插件在vite.config.jsimport{defineConfig}from"vite";importvuefrom"@vitejs/plugin-vue";importvueJsxfrom"@vitejs/plugin-vue-jsx";//ht......
  • vue列表渲染之for循环
    vue列表渲染之for循环前端开发中,如果涉及列表渲染,都会提示或要求每个列表项使用唯一的key,那很多开发者就会直接使用数组的index作为key的值,而并不知道key的原理。那么以下会讲解key的作用以及为什么最好不要使用index作为key的属性值。1、作用在虚拟DOM中,key是虚......
  • vue通过Export2Excel.js进行导入excel,获取数据
    <!--封装的模板下载和导入按钮和功能组件--><template><spanstyle="margin-left:10px"><el-buttonsize="mini"class="el-icon-download"@click="downFiles">下载模板</el-button><el-upload......
  • Vue2总结
    笔记脚手架文件结构├──node_modules├──public│├──favicon.ico:页签图标│└──index.html:主页面├──src│├──assets:存放静态资源││└──logo.png││──component:存放组件││└──HelloWorld.vue│......