Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf)

2023-12-11 06:04

本文主要是介绍Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf)

文章目录

    • Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf)
      • 一、背景介绍
      • 二、疑问
      • 三、所使用技术
        • html2canvas+jspdf
      • 四、展示开始
        • 1、效果展示
        • 2、代码部分
        • 3、参数说明
          • 3.1、html2canvas常用参数
          • 3.2、jsPDF常用参数
      • 五、常见问题

一、背景介绍

​ 当我们在不想改变后端代码的同时想是纯html页面导出PDF,那么(html2canvas+jspdf)就是无疑最好的选择,导出时它不占用我们服务器的资源,而是由用户本地自行执行js文件下载PDF,不占用我们系统的带宽,所以这无非是最好的选择方式。

二、疑问

1、为什么要使用html2canvas,单jspdf也能实现pdf下载?

​ HTML2Canvas 和 jsPDF 是 JavaScript 库,用于在浏览器中生成 PDF 文件。

​ HTML2Canvas 用于将 HTML 元素渲染成图像,可以将整个页面或特定区域以图像形式进行捕获。这对于将复杂的 HTML 结构转换为 PDF 格式非常有用,因为它可以捕获 HTML 中的样式、布局和图像等细节。 jsPDF 是一个 PDF 生成库,它允许你通过 JavaScript 代码创建和编辑 PDF 文档。与 HTML2Canvas 结合使用,你可以将 HTML 元素渲染成图像,然后将图像插入到 jsPDF 创建的 PDF 文档中。 虽然单独使用 jsPDF 也可以实现 PDF 下载,但是在某些情况下,使用 HTML2Canvas 可能更方便。例如,当你需要将整个页面转换为 PDF 或以图像形式捕获特定区域时,HTML2Canvas 提供了更灵活的选项。然后,你可以将 HTML2Canvas 生成的图像插入到 jsPDF 中,进一步编辑和操作 PDF。 综上所述,使用 HTML2Canvas 结合 jsPDF 可以更容易地将 HTML 转换为 PDF,并提供更多灵活性和控制力。

三、所使用技术

html2canvas+jspdf

js引入:引入线上js直接使用

<!--pdf下载 -->
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<!--jquery 方便后续使用jquery原生函数,可不引入-->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

四、展示开始

1、效果展示

html页面

在这里插入图片描述

下载成PDF

在这里插入图片描述

2、代码部分

js引入:

<!--pdf下载 -->
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<!--jquery 方便后续使用jquery原生函数,可不引入-->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

整体流程:

  1. 先将页面通过html2canvas转换成图片
  2. (jsPDF)将转换成的图片导出成PDF的形式
<!--pdf下载 -->
<script src="assets/js/jspdf/html2canvas.js"></script>
<script src="assets/js/jspdf/jspdf.umd.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>$('#downloadPDF').click(function() {console.log('开始下载PDF');htmlToPdf();});function htmlToPdf() {// 获取HTML元素const element = document.getElementById("layout-wrapper");const options = {dpi: 192,  //dpi属性的值为192,表示图像的分辨率scale: 2, //scale属性的值为2,表示图像的缩放比例。backgroundColor: "#F1F6FE"  //backgroundColor属性的值为"#F1F6FE",表示图像的背景颜色。};// 将元素转换为canvas对象html2canvas(element, options).then((canvas) => {var contentWidth = canvas.width;   //获取Canvas(上面元素id 'layout-wrapper')对象的宽度var contentHeight = canvas.height; //获取Canvas(上面元素id 'layout-wrapper')对象的高度// 创建jsPDF对象	jsPDF = jspdf.jsPDF;  //导入jsPDF库,用于创建PDF文件const pdf = new jsPDF('1', 'pt', [contentWidth, contentHeight]); //创建一个新的PDF对象,参数包括页面格式('1'表示A4纸张)、单位('pt')和页面尺寸([contentWidth, contentHeight])var pageData = canvas.toDataURL('image/jpeg', 1.0);  //将Canvas对象转换为JPEG格式的数据,并将其存储在pageData变量中。1.0表示图片质量pdf.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight);  //将JPEG格式的图片添加到PDF文件中,图片的左上角坐标为(0, 0),宽度为contentWidth,高度为contentHeightpdf.save("test.pdf");});}
</script>

在这里插入图片描述

3、参数说明
3.1、html2canvas常用参数

html2canvas 函数接受一些常用的参数,用于配置转换后的 canvas 元素的行为和样式。以下是一些常用的参数:

  • element: 必需参数,表示需要转换为 canvas 的 HTML 元素。
  • widthheight: 可选参数,分别表示转换后的 canvas 元素的宽度和高度。如果不设置这些参数,则 canvas 元素会自动调整大小以适应所包含的 HTML 元素。
  • scale: 可选参数,表示 canvas 元素的比例。默认值为 1,表示 canvas 元素会保持原始大小。
  • border: 可选参数,表示 canvas 元素的边框宽度。默认值为 0,表示没有边框。
  • backgroundColor: 可选参数,表示 canvas 元素的背景颜色。默认值为 “#ffffff”,表示白色。
  • foregroundColor: 可选参数,表示 canvas 元素的前景色颜色。默认值为 “#000000”,表示黑色。
  • imageQuality: 可选参数,表示转换后的图像的质量。默认值为 1,表示高质量。
  • jsPDF: 可选参数,表示需要使用的 jsPDF 对象。如果不设置这个参数,则不会将 canvas 转换为 PDF 文件。

以下是一个使用 html2canvas 函数的示例,其中包含了上述参数:

html2canvas(document.getElementById("my-element"), {width: 800,height: 600,scale: 2,border: 1,backgroundColor: "#cccccc",foregroundColor: "#000000",imageQuality: 0.9,jsPDF: pdf
}).then(function(canvas) {// 处理转换后的 canvas 元素
});
3.2、jsPDF常用参数

jsPDF 是一个用于创建 PDF 文件的 JavaScript 库。以下是 jsPDF 常用的参数:

  1. jsPDF('1', 'pt', [width, height]): 创建一个新的 PDF 对象,其中 '1' 表示 A4 纸张(l:竖向,p:横向),'pt' 表示单位为 point,widthheight 分别表示页面宽度和高度。
  2. pdf.setFont(font, size): 设置 PDF 文件的字体和大小。其中 font 表示字体名称,如 'Helvetica''Times'size 表示字体大小。
  3. pdf.setLineWidth(width): 设置 PDF 文件的线宽。其中 width 表示线宽的像素值。
  4. pdf.drawLine(x1, y1, x2, y2): 在 PDF 文件中绘制一条直线。其中 x1y1x2y2 分别表示直线的起点和终点坐标。
  5. pdf.drawRect(x, y, width, height): 在 PDF 文件中绘制一个矩形。其中 xy 分别表示矩形左上角的坐标,widthheight 分别表示矩形的宽度和高度。
  6. pdf.drawText(text, x, y): 在 PDF 文件中绘制一段文本。其中 text 表示要绘制的文本,xy 分别表示文本的左上角坐标。
  7. pdf.save('filename.pdf'): 将 PDF 文件保存为指定的文件名。其中 'filename.pdf' 表示要保存的 PDF 文件的文件名。
  8. pdf.addImage(imageData, type, x, y, width, height): 在 PDF 文件中添加一个图像。其中 imageData 表示图像的数据,type 表示图像的类型,如 'JPEG''PNG'xy 分别表示图像左上角的坐标,widthheight 分别表示图像的宽度和高度。
  9. pdf.rotate(angle, x, y): 旋转 PDF 文件中的图像或文本。其中 angle 表示旋转的角度,xy 分别表示旋转中心的位置。
  10. pdf.translate(x, y): 将 PDF 文件中的文本或图像移动到指定位置。其中 xy 分别表示要移动的坐标。

五、常见问题

1、图片跨域

解决方案:

  • 设置配置项 allowTaint: false

    canvas 的 CanvasRenderingContext2D 属于浏览器的对象,如果渲染过跨域资源,浏览器就认定 canvas 已经被污染了 Taint:污点

  • 设置配置项 useCORS: false

    表示允许跨域资源共享,注意不能与 allowTaint 同时配置为 true

  • img 标签中添加 crossOrigin = "anonymous"

    anonymous:如果使用这个值的话就会在请求 header 中带上 Origin 属性,但请求不会带上 cookie 和客户端 ssl 证书等其他的一些认证信息

  • 图片服务器配置 Access-Control-Allow-Origin: *

    重要的配置项,是跨域问题的根本源泉,需要后端配合

2、截图锯齿

解决方案:根据设备像素比进行缩放

// 设置放大倍数
const scale = window.devicePixelRatio;

4、对 css3 支持不好

html2canvas 暂不支持的 CSS 样式属性:

background-blend-mode、background-clip: text、box-decoration-break、repeating-linear-gradient()、font-variant-ligatures、mix-blend-mode、writing-mode、writing-mode、border-image、box-shadow、filter、zoom、transform

解决方案:

对于一些必要的样式,可以选择使用图片做兜底实现

box-shadow 可以参考 这个pr,修改源码解决,但是,实际效果也不是太理想……

5、svg 标签

问题原因:vue-lottie 动画库渲染的标签是 svg(也可能是你自己写的 svg 标签)

html2canvas 对于 svg 标签的支持也不尽人意,解决办法同样是用图片做兜底

在项目中,我们是用 svg 做动画,截图的时候把动画换成一张静态图,这样只要设置要静态图的样式,截图效果还是可以接受的

想……

5、svg 标签

问题原因:vue-lottie 动画库渲染的标签是 svg(也可能是你自己写的 svg 标签)

html2canvas 对于 svg 标签的支持也不尽人意,解决办法同样是用图片做兜底

在项目中,我们是用 svg 做动画,截图的时候把动画换成一张静态图,这样只要设置要静态图的样式,截图效果还是可以接受的

这篇关于Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/479673

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca