JS Web页面指定元素保存为pdf文件

技术栈: html2canvas + jspdf

简介

在实际业务开发中,经常需要实现将页面中的echarts图表和统计数据一键保存为pdf文件。
这涉及到两个阶段功能:

  1. 将页面某部分内容截取出来,成为图片格式(类似于截图)
  2. 将图片保存为pdf文件
    于是,此处需要html2canvas.jsjspdf.js 两个插件。

jspdf官网: https://raw.githack.com/MrRio/jsPDF/master/docs/index.html
html2canvas官网: https://html2canvas.hertzen.com/

实现

安装

首次,需要安装此两个js插件

# npm
npm install html2canvas --save
npm install jspdf --save

# yarn
yarn add html2canvas
yarn add jspdf

js逻辑

插件安装好后,进行引入。
明确需要打印的元素、操作事件,接下来就是插件调用与逻辑处理了。

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

toBePdf(eleId) {
    const theEle = document.getElementById(eleId); // 获取指定元素
    // 将element绘制为canvas
    html2Canvas(theEle).then(async (canvas) => {
      let imgurl = canvas.toDataURL('image/png') // 将canvas转换为图片
      let contentWidth = canvas.width
      let contentHeight = canvas.height
      // 将图片转为pdf格式(宽 > 高,则横向)
      let pdf = new JsPDF(contentWidth > contentHeight ? 'l' : 'p', 'pt', [contentWidth, contentHeight])
      pdf.addImage(imgurl, 'PNG', 0, 0, contentWidth, contentHeight)
	  pdf.save('document.pdf'); // 保存为pdf
    }).error((err) => {
        console.log(err)
    })
}

应用

此处应用采用 Vue 的写法。

调用

<template>
	<div>
		<div id="toBeEle"> 3123123</div>
		<button @click="toBePdf('toBeEle')">保存为pdf</button>
	</div>
</template>
<style>
#toBeEle {
	width: 100vw;
	height: 20vh;
	color: red;
}
</style>

效果

页面表现

页面表现

pdf内表现

pdf文件内容

扩展

因个人实际工作业务中,还需要将报表内容以图片、pdf文件的形式通过邮件发送给指定客户,此处扩展发送邮件相关内容。实际是将邮件的内容发送给后端,由后端处理从而发送到邮箱。如需要纯前端实现,需要使用 email.js 插件并注册该系统的邮箱(发送包含附件的邮件需开通付费会员)。

sendEmail() {
    const theEle = document.getElementById('toBePdf')
    html2Canvas(theEle).then( async (canvas) => {
      let imgurl = canvas.toDataURL('image/png')
      let contentWidth = canvas.width
      let contentHeight = canvas.height
      let pdf = new JsPDF(contentWidth > contentHeight ? 'l' : 'p', 'pt', [contentWidth, contentHeight])
      pdf.addImage(imgurl, 'PNG', 0, 0, contentWidth, contentHeight)

		/**
		* 邮件发送相关
		*/
      const formData = new FormData();
      const title = '2023/09/20-2023/12/20 营收报表'
      const imgTag = document.createElement('img');
      imgTag.src = imgurl;
      
      formData.append('to', this.model.email); // 收件人的电子邮件地址
      formData.append('subject', title);   // 邮件主题
      formData.append('file', pdf.output('blob'), 'document.pdf'); // 添加PDF文件并转Blob格式(二进制数据对象)
      formData.append('text', imgTag.outerHTML);   // 邮件正文(这里是个图片) 
      // const text = '这是邮箱正文';
      // formData.append('text', text);
      await StatisticsAPI.sendEmail(formData); // 后端发送邮件的接口
    })
  }
// 接口请求配置
sendEmail: function sendEmail(param) {
    return axios({
      url: '/send-email',
      method: 'post',
      data: param,
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  },

邮件效果

发送邮件效果

其他

关于html2canvas.jsjspdf.js 插件的具体描述,可以参考其他博客:
司徒小北 - jspdf用法
pingan8787 - 深度使用html2canvas的经验总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值