如何优雅使用 vue-html2pdf 插件生成pdf报表

news2024/11/20 2:29:40

使用 vue-html2pdf 插件

业务背景,老板想要一份能征服客户的pdf报表,传统的pdf要手撕,企业中确实有点耗费时间,于是github上面看到开源的这个插件就…废话不多说,直接上教程

1.使用下面命令安装 vue-html2pdf

npm i vue-html2pdf

2.在vue组件下使用

<template>
   <div>
       <!-- 具体说明看文档 -->
       <vue-html2pdf
   	      :show-layout="false"
   	      :float-layout="true"
   	      :enable-download="true"
   	      :preview-modal="true"
   	      :paginate-elements-by-height="1400"
   	      :filename="fileName"
   	      :pdf-quality="2"
   	      :manual-pagination="false"
   	      pdf-format="a4"
   	      pdf-orientation="portrait"
   	      pdf-content-width="800px"
   	      @progress="onProgress($event)"
   	      @hasStartedGeneration="hasStartedGeneration()"
   	      @rendered="hasGenerated($event)"
   	      ref="html2Pdf"
       >
           <section slot="pdf-content">
               <!-- 这里写要生成PDF的元素 -->
                           <section class="pdf-item">
                               <span>
                                   <div class="wrapper">
                                       <div class="header">
                                       <div class="main">
                                       <div class="footer">
                               </span>
                           </section>
                           <div class="html2pdf__page-break"/> //分页
                           ...有几页就再写一个pdf-item就好了
           </section>
       </vue-html2pdf>
   </div>
</template>
//引入vue-html2pdf
import VueHtml2pdf from "vue-html2pdf";
export default {
   components: {
       //注册组件
       VueHtml2pdf
   },
   methods: {
       //声明下载为PDF的方法
       generateReport () {
           this.$refs.html2Pdf.generatePdf()
       }
   },
}

另外我加了进度条,看到有这个加载的属性,就顺便封装了个进度条,看起来更优雅一点。默认值我设置的1,这个看自己调整。废话不说,直接上代码(Progress.vue),在项目中直接引用即可
在这里插入图片描述

<template>
  <div class="m-progress" :style="`width:${width}px;`">
    <div class="m-progress-outer">
      <div class="m-progress-inner">
        <div :class="['u-progress-bg', {'u-success-bg': progress >= 100}]" :style="`width: ${progress >= 100 ? 100:progress}%; height: ${strokeWidth}px;`"></div>
      </div>
    </div>
    <template v-if="showInfo"></template>
    <svg class="u-success" v-if="progress>=100" viewBox="64 64 896 896" data-icon="check-circle" aria-hidden="true" focusable="false">
      <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path></svg>
    <p class="u-progress-text" v-else>{{ progress>=100 ? 100:progress }}%</p>
  </div>
</template>
<script>
export default {
  name: 'Progress',
  props: {
    width: { // 进度条总宽度
      type: Number,
      default: 600
    },
    progress: { // 当前进度
      type: Number,
      default: 1
    },
    strokeWidth: { // 进度条线的宽度
      type: Number,
      default: 8
    },
    showInfo: { // 是否显示进度数值或状态图标
      type: Boolean,
      default: true
    }
  }
}
</script>
<style lang="scss" scoped="scoped">
.m-progress {
  height: 24px;
  margin: 0 auto;
  display: flex;
  .m-progress-outer {
    width: 100%;
    .m-progress-inner {
      display: inline-block;
      width: 100%;
      background: #f5f5f5;
      border-radius: 100px;
      .u-progress-bg {
        // background: #1890FF;
        background: linear-gradient(to right, rgb(16, 142, 233), rgb(135, 208, 104));
        border-radius: 100px;
        transition: all .3s cubic-bezier(.08,.82,.17,1);
      }
      .u-success-bg {
        background: #52C41A;
      }
    }
  }
  .u-success {
    width: 16px;
    height: 16px;
    fill: #52C41A;
    margin-left: 8px;
    margin-top: 4px;
  }
  .u-progress-text {
    font-size: 16px;
    line-height: 24px;
    margin-left: 8px;
    color: rgba(0,0,0,.45);
  }
}
</style>

3.属性整理一下

属性描述本人建议
show-layouttrue/false是否显示要转为 PDF 的元素调式要转出的元素的布局时 true,平时 false
float-layouttrue/false如果道具设置为 false 道具 show-layout 将被覆盖。布局不会浮动,并且布局将始终显示。我一直使用的 true,因为做的时候做了两份,一个是在后台显示的,一个是导出为 PDF 的,布局不一样
enable-downloadtrue/false是否弹出转 PDF 后的预览模板,为 true 时调用上面的下载方法默认弹出预览模板调试时开启,完工后关闭
preview-modaltrue/false是否弹出转 PDF 后的预览模板,为 true 时调用上面的下载方法默认弹出预览模板调试时开启,完工后关闭
paginate-elements-by-height任何数字输入的数字将用于对元素进行分页,数字仅以 px 为单位。官方默认 1400,没动过
filename任何字符串导出后的默认 PDF 文件名自定义
pdf-quality0 - 2(可以有小数)2 是最高质量,0.1 是最低质量,0 将使 PDF 消失。官方虽然说是 0~2,但是我调 5 也是更高清了
manual-paginationtrue/false为 true 时不会自动对元素进行分页。为 false 时分页将依赖于具有“html2pdf__page-break”类的元素来知道在哪里分页,也就是下面所写的我一直使用的 false,看需求
pdf-formata0, a1, a2, a3, a4, letter, legal, a5, a6, a7, a8, a9, a10这是 PDF 格式(纸张尺寸)一般都用的a4,所以 a4
pdf-orientationportrait, landscapePDF 方向,landscape 是横向,portrait 是纵向看需求
pdf-content-width任何 css 尺寸(例如“800px”、“65vw”、“70%”)PDF 内容宽度800px 应该是 a4 最大的尺寸,具体边距我使用的 padding

4.说到分页这个,组件中有自动分页,但是会影响你的页眉页脚,如果不想自动分页的话,直接在元素后面加上下面代码即可分页

<div class="html2pdf__page-break"></div>

5.个人使用感想:使用这个插件后,渲染的话还可以的直接和vue能搭配,更能和E-Charts搭配使用,确实方便,优点:节约开发成本,提高开发效率,拿来即用。缺点:不支持超链接功能,有时候业务场景需要在pdf中超链接,如果有这个功能的话,那就很全了。当然,也不是说这个组件不好,使用起来还是比较丝滑的。主要是看业务场景吧。
6. 项目中遇到比较棘手的问题,就是动态排版展示,因为本人是后端,所以跟专业前端大佬不能比,就想记录一下
在这里插入图片描述
本身是想写死多少个平台,然后使用v-if或者v-show来展示,但是代码量有点冗余不说,还没有排版好,就想到了v-for。

					<div class="b1" style="width: 100%; display: flex; flex-wrap: wrap;">
                      <div v-for="(platform, index) in platforms"
                           :key="index" v-if="platform.count > 0"
                           class="bordered3"
                           style="flex-basis: calc(50% - 10px); margin-right: 10px; margin-bottom: 10px;">
                        <div class="r3">
                          <p class="p1">{{ platform.instituteType }}处理违规数量</p>
                          <span class="p2">{{ platform.count }}</span>
                        </div>
                        <div class="r4">
                          <img class="tb"
                               :src="getPlatformImage(platform.instituteType)"
                               alt="Sample Image">
                        </div>
                      </div>
                    </div>

v-for主要没啥,主要是动态样式调整起来确实费事,终于能体会到前端大佬的不易!觉得好玩的可以去试试!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1302286.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

牛客算法心得——买卖股票的最好时机三(dp)

大家好&#xff0c;我是晴天学长&#xff0c; 一个找状态的经典题&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .买卖股票的最好时机&#xff08;三&#xff09; 假设你有一个数组prices&#xff0c;…

【深度学习】AlexNet网络实现猫狗分类

【深度学习】AlexNet网络实现猫狗分类 AlexNet简介 AlexNet是一种卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;模型&#xff0c;它在2012年的ImageNet图像分类挑战赛中取得了重大突破&#xff0c;引发了深度学习在计算机视觉领域的热潮…

【C知道】帮我答疑解惑:java的entity字段是map,如何映射到数据库

目录 一、问题场景描述 二、跟【C知道】第一次沟通 &#xff08;1&#xff09;我问 &#xff08;2&#xff09;他答 &#xff08;3&#xff09;我说 三、跟【C知道】第二次沟通 &#xff08;1&#xff09;我问 &#xff08;2&#xff09;他答 &#xff08;3&#xff0…

iptables 命令说明

摘要 iptables是一个用于Linux系统的网络包过滤工具。它是一个基于内核的防火墙系统&#xff0c;用于配置和管理网络规则以控制网络流量。iptables可以对数据包进行过滤、转发、修改目的地、屏蔽IP等操作&#xff0c;可通过定义不同的规则和策略来确保网络的安全性和可靠性。 …

猫咪口味大考验:最受欢迎的猫罐头品牌揭晓!

养猫的这几年德罐也买了不少了&#xff0c;很早以前德罐给我的感觉就是&#xff0c;物美价廉&#xff0c;而且质量保障也不错&#xff0c;很美丽。但最近的德罐恕在下高攀不起了。 作为一个已经离职的宠物医生&#xff0c;我也发现不少人有这样的困扰吧&#xff01;其实&#x…

Linux 高级管理,基于域名的虚拟Web主机

实验环境 某公司的网站服务器使用的公网IP地址为192.168.184.50并使用该IP地址注册了两个域名 www.bdqn1.com和www.jbit.com。服务器中已经安装好了 CentOS 7操作系统.并通过源码编译的 方式安装了Web服务器软件httpd-2.4.25.现需要对httpd服务进行配置.以支持同时运行这两个 W…

mybatis多表映射-分步查询

1、建库建表 create database mybatis-example; use mybatis-example; create table t_book (bid varchar(20) primary key,bname varchar(20),stuid varchar(20) ); insert into t_book values(b001,Java,s001); insert into t_book values(b002,Python,s002); insert into …

LinuxC中进程通信

LinuxC中进程通信 信号&#xff08;Signals&#xff09;&#xff1a;Linux 提供了信号机制&#xff0c;允许一个进程向另一个进程发送信号以通知特定事件的发生。这是一种轻量级的通信机制&#xff0c;通常用于处理异步事件。您可以使用 kill 命令或 kill 函数来发送信号&…

小米路由器4A千兆版如何刷OpenWRT并使用固定地址远程访问

文章目录 前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 前言 OpenWRT是一个高度模块化、高度自…

基于微服务架构的餐饮系统的设计与实现-计算机毕设 附源码 86393

基于微服务架构的餐饮系统的设计与实现 摘 要 近年来,我国经济和社会发展迅速,人们物质生活水平日渐提高,餐饮行业更是发展迅速,人们对于餐饮行业的认识和要求也越来越高。传统形式的餐饮行业都是以人为本,管理起来需要很多人力、物力、财力,既不方便管理者的管理,也不方便顾…

大创项目推荐 卷积神经网络手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…

GaussDB数据库语法及gsql入门

一、GaussDB数据库语法入门 之前我们讲了如何连接数据库实例&#xff0c;那连接数据库后如何使用数据库呢&#xff1f;那么我们今天就带大家了解一下GaussDB&#xff0c;以下简称GaussDB的基本语法。 关于如何连接数据库&#xff0c;请戳这里。 学习本节课程之后&#xff0c…

C语言——输出菱形

法一&#xff1a; #include<stdio.h> #define N 7 //假设输出7层菱形 int main(){int i;//i控制第几行 int j;//j控制每一行空格的循环个数 int k;//k控制每一行*的循环次数 for(i1;i<4;i){//将图形分为两部分,前四行(第一部分) for(j1;j<4-i;j){//输出第i行的…

【带头学C++】----- 九、类和对象 ---- 9.11 面向对象模型

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️麻烦您点个关注&#xff0c;不迷路❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目 录 9.11 面向对象的框架模型 9.11.1 成员变量与函数的存储架构 代码举例说明&#xff1a; 9.11.2 this指针 9.11.4 this指针的应用…

线程互斥与同步

用户级线程 内核的LWP Linux线程 OS概念中经常说的 用户级线程 和 内核级线程 也就是线程实现真的是在OS内部实现&#xff0c;还是应用层或用户层实现 很明显Linux是属于用户级线程 用户级执行流&#xff08;用户级线程&#xff09; &#xff1a;内核lwp 1 : 1 也有1&…

Anaconda+Pytorch(GPU版)深度学习环境配置笔记

主要参考以下文章进行配置&#xff1a; https://blog.csdn.net/qq_43757976/article/details/131173301 配置版本略有更新&#xff0c;最新版本时间为2023.12.11 一、准备工作 个人电脑配置&#xff1a;laptop RTX4060 win11 个人配置版本&#xff1a;cuda&#xff08;12.1&…

虹科Pico汽车示波器 | 汽车免拆检修 | 2019款别克GL8豪华商务车前照灯水平调节故障

一、故障现象 一辆2019款别克GL8豪华商务车&#xff0c;搭载LTG发动机&#xff0c;累计行驶里程约为10.7万km。车主反映&#xff0c;车辆行驶过程中组合仪表提示前照灯水平调节故障。 二、故障诊断 接车后试车&#xff0c;起动发动机&#xff0c;组合仪表上提示“前照灯水平调节…

OWASP ESAPI 预防XSS跨站脚本攻击

跨站脚本攻击XSS案例&#xff1a;跨站脚本攻击XSS案例及其解决方案_xss攻击案例-CSDN博客 Java集成&#xff1a; 1、引入maven <!--OWASP ESAPI&#xff0c;防御 XSS跨站攻击--><dependency><groupId>org.owasp.esapi</groupId><artifactId>esa…

90%的人都值得学习微信商城的准备工作,7个关键步骤

如何做一个小程序卖东西&#xff1f;90%的人都不知道微信商城的准备工作 近几年&#xff0c;随着疫情的影响和电商的崛起&#xff0c;实体生意大家都变得越来越难做&#xff0c;越来越多的企业老板开始把矛头转向成本费用比实体门店更加低的微商城小程序&#xff0c;通过小程序…

微信小程序 bindtap 事件多参数传递

在微信小程序中&#xff0c;我们无法直接通过 bindtap"handleClick(1,2,3)" 的方式传递参数&#xff0c;而是需要通过自定义属性 data- 的方式进行传递&#xff0c;并在事件回调函数中通过 event.currentTarget.dataset 来获取这些参数。然而&#xff0c;这种传参方式…