Vue页面生成PDF的方法

news2025/7/5 22:41:49

最近项目有个需求,将系统统计的数据生成分析报告,然后可以导出成PDF。

这种方法可以有两种,一种是直接调用打印,用户通过浏览器提供的打印页面手动选择导出PDF。当然这种方式兼容性差,且体验不好,显然不是我们想要的效果。

那么第二种方法的实现思路是什么呢?

首先生成报告页面,也就是常规页面;
然后将页面转换成图片( 用到的组件 html2canvas );
最后将图片导出成PDF( 用到的组件 jspdf )。

安装依赖

npm install --save html2canvas  // 页面转图片
npm install jspdf --save  // 图片转pdf

页面转图片

新建一个 index.vue 页面:

<template>
  <div ref="pdf">
    这是待转换的页面,点击 
    <button @click="handleExport">导出</button> 按钮,完成导出操作。
  </div>
</template>

<script>
import {downloadPDF} from "@/util/pdf.js"  //工具方法,导出操作
export default {
  name: "pdf",
  data() {
    return {};
  },
  methods: {
    handleExport(){
      downloadPDF(this.$refs.pdf)
    }
  }
};
</script>

页面很简单,一段话加上一个导出按钮。整个页面被设置别名 (ref=“pdf”),导出的时候通过别名导出整个页面。

按钮点击事件中调用了一个工具方法 downloadPDF(),来自于工具类 pdf.js:

import html2canvas from "html2canvas";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    page.appendChild(canvas);
  });
};

也很简单,首先引入了 html2canvas,定义downloadPDF方法,接受一个参数就是要导出的内容,可以使用id获取,也可以使用 ref 。

运行结果:
在这里插入图片描述

当我们点击导出按钮后,在现有的页面增加了一行相同的内容。通过元素检查器可以看到增加的这行内容实际是一个 canvas 图像,里面的按钮已经不可以操作了。

这样,页面转换图片的过程就完成了。

图片转PDF

首先给index.vue改造一下,为了让我们导出的pdf好看一点,使用el-table做个表格,其它的导出逻辑不变:

<template>
  <div ref="pdf">
    
    <el-table
      :data="tableData"
      style="width: 700px">
      <el-table-column
        prop="date"
        label="时间"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="对我说">
      </el-table-column>
    </el-table>

    <button @click="handleExport">导出</button>
  </div>
</template>
<script>
import {downloadPDF} from "@/util/pdf.js"  //工具方法,导出操作
export default {
  name: "pdf",
  data() {
    return {
      
          tableData: [{
            date: '昨天',
            name: '刘德华',
            address: '你好帅'
          }, {
            date: '今天',
            name: '郭富城',
            address: '你最帅'
          }, {
            date: '明天',
            name: '张学友',
            address: '你贼帅'
          }, {
            date: '每天',
            name: '黎明',
            address: '我没你帅'
          }]
    };
  },
  methods: {
    handleExport(){
      downloadPDF(this.$refs.pdf)
    }
  }
};
</script>

效果图:
在这里插入图片描述
然后改造一下pdf.js,增加上pdf转换逻辑

import html2canvas from "html2canvas";
import jsPDF from "jspdf";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    canvas2PDF(canvas);
  });
};

const canvas2PDF = canvas => {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;
  
  let imgHeight = contentHeight;
  let imgWidth = contentWidth;

  // 第一个参数: l:横向  p:纵向
  // 第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px")
  let pdf = new jsPDF("l", "pt");

  pdf.addImage(
    canvas.toDataURL("image/jpeg", 1.0),
    "JPEG",
    0,
    0,
    imgWidth,
    imgHeight
  );

  pdf.save("导出.pdf");
};

canvas2PDF 方法中创建了jsPDF的实例,然后添加上一步生成的图片,最后保存导出pdf文件。

导出的文件效果:
在这里插入图片描述

A4打印适配

因为部分需求有需要生成的页面使用A4纸打印,那么pdf生成时的宽高尺寸就不能像上面一样设定。需要按照A4纸的尺寸比例调整(其它打印需求同理,使用对应纸张比例即可)

那么改造一下 pdf.js

import html2canvas from "html2canvas";
import jsPDF from "jspdf";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    canvas2PDF(canvas);
  });
};

const canvas2PDF = canvas => {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;

  //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
  let imgWidth = 595.28;
  let imgHeight = 592.28/contentWidth * contentHeight;

  // 第一个参数: l:横向  p:纵向
  // 第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px")
  let pdf = new jsPDF("p", "pt");

  pdf.addImage(
    canvas.toDataURL("image/jpeg", 1.0),
    "JPEG",
    0,
    0,
    imgWidth,
    imgHeight
  );

  pdf.save("导出.pdf");
};

这里面将 imgWidth 和 imgHeight 按照A4纸比例调整后,导出的pdf就可以正常比例打印了。

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

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

相关文章

net::ERR_CONNECTION_REFUSED 解决大全

sockjs-node/info报错 GET http://localhost/sockjs-node/info?t1641268443660 net::ERR_CONNECTION_REFUSED sockjs-node作用 SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascr…

前端页面出现 Failed to load response data

工作上前端 搭建了一套新的环境 同一个接口 新的前端环境 调用接口时 偶尔会出现一个情况 这时候 我们 在服务器 、 Postman 、本地环境调用都没问题 唯独在新的前端页面上会出现这样的问题 鉴于这样的问题 在网上查询了很多方法 进行修正都无济于事 最终在我们将问题指向了…

Android基础入门

第1章 Android基础入门 目录第1章 Android基础入门1.1 Android简介1.1.1 通信技术1.1.2 Android发展史1.1.3 Android体系结构1.1.4 Dalvik虚拟机1.2 Android开发环境搭建1.2.1 Android Studio安装1.2.2 模拟器创建1.2.3 SDK下载1.3 Android程序结构1.4 资源的管理与使用1.4.1 图…

前端第二章:9.HTML如何在网页中添加图片(img标签使用方法,以及img标签属性:alt、height、width);图片格式选择

一、img 标签简介 1.是自结束标签 2.用于向当前页面引入一个 外部图片 3.可以引入 gif 动图 4.img 是 替换元素&#xff0c;具有块元素和行内元素的某些特点 二、img标签基础 0.使用img标签将 图片 引入 网页&#xff01; 1.代码&#xff1a; <img src"图片的相对路…

【前端项目问题】Vue 中 v-html 的使用

Vue 中 v-html 的使用一、 v-html是什么&#xff1f;二、使用方式一、 v-html是什么&#xff1f; v-html 用来更新元素的 innerHTML&#xff0c;但是存在一定的安全性。 注意&#xff1a; 1、内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。 2、在网站上动态渲染任意 HTM…

前端技术发展历程

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 随着互联网的不断发展…

了解SVG-icon的使用流程

一.了解SVG是什么 SVG&#xff08;Scalable Vector Graphics&#xff09;可缩放矢量图形&#xff0c;是一种用于描述基于二维的矢量图形的 XML 标记语言&#xff0c;其基本矢量显示对象包括矩形、圆、椭圆、多边形、直线、任意曲线等&#xff0c;还能显示文字对象和嵌入式外部…

使用elementUI组件实现表格的分页以及搜索功能

主要的UI组件&#xff1a;el-input、el-table、el-pagination 效果展示&#xff1a; 主要功能&#xff1a; ① 完成列表与分页组件的联动&#xff0c;可以通过分页来实现列表数据翻页。 ② 通过在搜索栏输入关键词&#xff0c;在列表中展示出与关键词有关数据。 基础设置&a…

微信小程序实现滑动/点击切换Tab

背景 &#x1f44f; swiperscroll-view实现滑动/点击切换Tab&#xff0c;以及scroll-left的使用~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 2.1 scroll-view实现tab列表 scroll-view&#xff1a; 可滚动视图区域。使用竖向滚动时…

jsPDF + html2canvas A4分页截断 完美解决方案(含代码 + 案例)

业务需求 网页html生成A4大小分页的pdf&#xff0c;翻遍了整个互联网发现没有很系统的整理与分析&#xff0c;甚至对jsPDF的解析也没有几篇。遇到过几次&#xff0c;用的比较多&#xff0c;完成代码编写后特此整理分析&#xff0c;自我记录。 业务难点 1.存在图片/组件/文字…

vue弹窗如何嵌入其它vue页面

文章目录说明子组件&#xff0c;将要引入到弹框内的页面父页面思考组件 v-if 和 v-show 切换时生命周期钩子的执行说明 【1】实现方式&#xff0c;将其他页面作为组件传入 【2】在父页面&#xff0c;将该组件引入到弹框内&#xff0c;并通过动态渲染进行切换 子组件&#xff0…

使用宝塔面板快速搭建web网站,并内网穿透实现公网远程访问

目录 1. 环境安装 2. 安装cpolar内网穿透 3. 内网穿透 4. 固定http地址 5. 配置二级子域名 6. 创建一个测试页面 宝塔面板简单几步搭建本地web站点&#xff0c;并做内网穿透&#xff0c;实现公网用户也可以正常远程访问&#xff0c;无需公网IP&#xff0c;无需设置路由器…

echarts入门基础教程

目录 效果图 1.下载资源 新建项目 2.引入echarts 3.准备一个呈现图表的盒子 4.初始化echarts实例对象 5.准备配置项 6.将配置项设置给echarts实例对象 7.完整代码 效果图 1.下载资源 新建项目 去官网下载echarts压缩包&#xff0c;在包里的dist文件里找到echarts.min.j…

使用vite构建Vue3组件库,发布npm包

使用vite构建Vue3组件库&#xff0c;发布npm包 在国内用vue框架开发的是非常之多的&#xff0c;使用vue开发组件封装是一个很普片的事情了&#xff0c;封装好一个组件可以在项目的任意地方去使用&#xff0c;我们还可以从npm仓库下载别人封装的组件进行使用&#xff0c;比如ele…

基于Java+Springboot+vue高校资源共享交流平台设计和实现

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【完整代码】用HTML/CSS制作一个美观的个人简介网页

【完整代码】用HTML/CSS制作一个美观的个人简介网页整体结构完整代码用HTML/CSS制作一个美观的个人简介网页——学习周记1HELLO&#xff01;大家好&#xff0c;由于《用HTML/CSS制作一个美观的个人简介网页》这篇笔记有幸被很多伙伴关注&#xff0c;于是特意去找了之前写的完整…

web前端框架——Vue的特性

目录 前言&#xff1a; 一.vue 二.特性 1.轻量级 2.数据绑定 3.指令 4.插件 三.比较Angular 、React 、Vue 框架之间的比较 1. Angular Angular的优点&#xff1a; 2. React React 的优点&#xff1a; 3.vue 3.Vue的优点&#xff1a; 前言&#xff1a; 本篇文章…

【Vue】初识Vue,Vue简介及Vue Devtools配置

目录1. Vue是什么2. Vue的特点3. Vue的引入方式4. 安装Vue Devtools5. 第一个Vue案例1. Vue是什么 关于这个问题官方给了我们答案&#xff1a; 一套用于构建用户界面的渐进式JavaScript框架 渐进式框架是指我们可以在项目中一点点来引入和使用Vue&#xff0c;而不一定需要全部…

【vue2】使用vue常见的业务流程与实现思路

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;vue的业务处理思路。前台数据渲染与后台的增删改查操作 【前言】当大家会点开这一篇文章…

手把手教你基于HTML、CSS搭建我的相册(下)

The sand accumulates to form a pagoda⭐ 写在前面⭐ 相册中心部分⭐ 添加照片⭐ 图片展示样式⭐ 搭建底部版权模块⭐ 写在最后⭐ 写在前面 经常有一些粉丝咨询前端该从什么开始学&#xff0c;那当然是我们的前端基础三件套开始学起&#xff0c;HTML、CSS、javaScript&#x…