vue页面导出pdf,预览并下载(pc端)

                         vue页面导出pdf,预览并下载(pc端)

Vue前端HTML保存为PDF常用方式有两种。
一,使用html2Canvas和JsPDF库,转化为图片后保存PDF。
二,调用浏览器window.print(),然后手动保存为PDF。

第一种
优点
  • 没有预览点击即可保存
  • 不需要手动配置保存
  • 可选取部分Dom保存
缺点
  • 较不清晰
  • 需要先转化为图片
  • 没有提前预览
  • 不适合保存过长分页内容
  • 依赖html2Canvas和JsPDF库
第二种
优点
  • 可以提前预览
  • 适合保存过长分页内容比较合适
  • 直接由浏览器API保存,内容清晰
  • 开发便利快速。
缺点
  • 第一次需要在预览框手动配置参数
  • 需要手动点击保存
  • 会有Print预览弹窗
  • 不可选取部分Dome,只能保存当前整页面。

一,终端输入命令,添加两个npm

第一个.将页面html转换成图片
npm install --save html2canvas 
第二个.将图片生成pdf
npm install jspdf --save

二,定义全局函数..创建一个htmlToPdf.js文件在指定位置.我个人习惯放在('src/components/utils/htmlToPdf'), getPdf方法和pdfExport方法可以任意使用。正常来写应该使用 PDF.save(title + '.pdf')来进行打印下载,PDF.save(title + '.pdf')下面的代码是使用移动端的时候才加上的,光是pc端可以恢复这行代码,干掉下面的代码。

/**
    path: src/utils/htmlToPdf.js
    name: 导出页面为PDF格式
**/
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

const htmlToPdf = {
//  pdfExport() {
//              var mainRight = document.getElementById('mainRight');
//              html2canvas(mainRight, {
//                allowTaint: true,
//                scale: 2, // 提升画面质量,但是会增加文件大小
//              }).then(function(canvas) {
    
//    var contentWidth = canvas.width;
//    var contentHeight = canvas.height;
    
//    var pageData = canvas.toDataURL('image/jpeg', 0.4);
    
//    var pdfWidth = (contentWidth + 10) / 2 * 0.75;
//    var pdfHeight = (contentHeight + 200) / 2 * 0.75; // 500为底部留白
    
//    var imgWidth = pdfWidth;
//    var imgHeight = (contentHeight / 2 * 0.75); //内容图片这里不需要留白的距离
    
//    var pdf = new jsPDF('', 'pt', [pdfWidth, pdfHeight]);
//    pdf.addImage(pageData, 'jpeg', 0, 0, imgWidth, imgHeight);
//    pdf.save('report_pdf_' + new Date().getTime() + '.pdf');
//  });  }
    getPdf(title) {
        html2Canvas(document.querySelector('#pdfDom'), {
            allowTaint: true,
        }).then(canvas=>{
            //内容的宽度
            let contentWidth = canvas.width;
            //内容高度
            let contentHeight = canvas.height;
            //一页pdf显示html页面生成的canvas高度,a4纸的尺寸[595.28,841.89];
            let pageHeight = contentWidth / 592.28 * 841.89;
            //未生成pdf的html页面高度
            let leftHeight = contentHeight;
            //页面偏移
            let position = 0;
            //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
            let imgWidth = 595.28;
            let imgHeight = 841.89 / contentWidth * contentHeight;
            // let imgHeight = 592.28 / contentWidth * contentHeight;
            //canvas转图片数据
            let pageData = canvas.toDataURL('image/jpeg', 1.0);
            //新建JsPDF对象
            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')
            
             var _this=this
             //转成base64
             let pdf64 = PDF.output("datauristring");
             //base64转成blob文件
             let path = _this.createDownloadFile("报表", pdf64);
             //上传到服务器
             let formdata = new FormData();
             //第三个参数传一个不一定会用到的文件名,但是得有。注意后缀
             formdata.append("file", path, "报表.pdf");
            //调上传接口,这里因为我封装了axios增加了拦截器,所以是下面的写法,这里根据各位的上传方法不同,自行修改
             request({
                        url: _this.url + _this.curVersion + "/SysFile/uploadImg",
                        method: "post",
                        data: formdata,
                      }).then((res) => {
            //拼接文件线上地址
                        let path =
                          _this.url + res.data.data.filePath + res.data.data.fileName;
            //调用安卓或者ios提供的方法,打开浏览器
                        Android.openBrowser(path);
              });
              
        })
    }
};

export default htmlToPdf;

三,在main.js中使用我们定义的函数文件,定义全局。

import htmlToPdf from '@/components/utils/htmlToPdf'
Vue.use(htmlToPdf)

这里开始分两种方式进行,@click="pdfBtn"是点击pdf的事件,id="pdfDom"的div中就是打印的内容,所有内容要写在这个div里。

第一种:html2Canvas和JsPDF库

<template>
    <div id="PdfPage1">
        <button type="button" @click="pdfBtn">导出PDF</button>
        <div id="pdfDom" >
            
        </div>
    </div>
</template>

<script>
    import htmlToPdf from '@/utils/htmlToPdf'
    export default {
        name: "PdfPage",
        data(){
            return{
                htmlTitle:'页面导出PDF文件名',
            }
        },
        methods:{
            pdfBtn(){
                htmlToPdf.getPdf(this.htmlTitle);
            }
        }
    }
</script>

<style scoped>
</style>

第二种:window.print()

<template>
    <div id="PdfPage2">
        <button type="button" @click="pdfBtn">导出PDF</button>
        <div id="pdfDom">
          
        </div>
    </div>
</template>

<script>
    export default {
        name: "PdfPage2",
        methods:{
            pdfBtn(){
                window.print();
            }
        }
    }
</script>

<style scoped>

</style>

打印的css,在点击按钮生成pdf时,打印页面会生成这些样式

@media print{
打印页面样式
        .noprint{
            display: none;
        }
        .Front{
            background-color: white;
            background: url(../assets/beijng.jpg);
            background-size:100% 100%;
        }
        .buttonNoPrint{  
            display:none;  
        }  
        .Header{
            display:none; 
        }
        .Headers{
            display:none; 
        }
        body{
            -webkit-print-color-adjust:exact;
            -moz-print-color-adjust:exact;
            -ms-print-color-adjust:exact;
            print-color-adjust:exact;
        } 
        #pdfDom{
            /* width: 1078px;
            height: 1568px;
            height: 7200px;
             border: 1px #000 solid; */
            border-bottom: white;
            margin: 0 auto;
            /* margin-left: 1%;
            margin-top: 1%; */
        }

配置页眉页脚的边距,宽度
        @page{
             size: auto !important; 
             /* margin: 3mm !important; */
             margin: 1.5em 1.5em 1.5em
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容