html转PDF

项目场景:

提示:这里简述项目相关背景:

在项目中会有一些需要页面转成PDF的情况,这里需要配合一些插件可以完成

使用html2canvas将使用canvas将页面转为base64图片流,并插入jspdf插件中,保存并下载pdf。


安装依赖

提示:这里描述项目中遇到的问题:

javascript 复制代码
npm i html2canvas
npm i jspdf

解决方案1:

提示:这里填写该问题的具体解决方案:

1:创建htmlToPdf.ts文件

javascript 复制代码
// 页面导出为pdf格式
import html2Canvas from 'html2canvas';
import jsPDF from 'jspdf';

const htmlToPdf = {
  getPdf(title) {
    html2Canvas(document.querySelector('#pdfStyle'), {
      allowTaint: false,
      taintTest: false,
      logging: false,
      useCORS: true,
      dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
      scale: 2, //按比例增加分辨率
    }).then((canvas) => {
      const pdf = new jsPDF('p', 'mm', 'a4'); //A4纸,纵向
      const ctx = canvas.getContext('2d')
      const a4w = 190
      const a4h = 272 //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
      //按A4显示比例换算一页图像的像素高度
      const imgHeight = Math.floor((a4h * canvas.width) / a4w) 
      let  renderedHeight = 0;
      while (renderedHeight < canvas.height) {
        const page = document.createElement('canvas');
        page.width = canvas.width;
        //可能内容不足一页
        page.height = Math.min(imgHeight, canvas.height - renderedHeight); 
        //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
        page.getContext('2d')
          .putImageData(
            ctx.getImageData(
              0,
              renderedHeight,
              canvas.width,
              Math.min(imgHeight, canvas.height - renderedHeight),
            ),
            0,
            0,
          );
        pdf.addImage(
          page.toDataURL('image/jpeg', 1.0),
          'JPEG',
          10,
          10,
          a4w,
          Math.min(a4h, (a4w * page.height) / page.width),
        ); //添加图像到页面,保留10mm边距
        renderedHeight += imgHeight;
        if (renderedHeight < canvas.height) {
          pdf.addPage(); //如果后面还有内容,添加一个空页
        }
        // delete page;
      }
      //保存文件
      pdf.save(title + '.pdf');
      // loading = false;
      // console.log(loading);
    });
  },
};

export default htmlToPdf;

2:在页面中使用

javascript 复制代码
...
<!-- 按钮 -->
<el-button size="mini" type="primary" @click="pdfFunc" :loading="loading">
  转成pdf
</el-button>
...
<div id="pdfDom">
	<!-- 此处是希望转成pdf的部分的内容,用一个大div盒子包起来 -->
</div>
<script setup>
// 导入htmlToPdf.js
import htmlToPdf from '@/utils/htmlToPdf';
const pdfFunc = () => {
	 loading.value = true;
	 // 调用htmlToPdf工具函数
     htmlToPdf.getPdf('文档名称');
     // 定时器模拟按钮loading动画的时间
      setTimeout(() => {
        loading.value = false;
        ElMessage.success('打印成功!');
      }, 1000);
}
</script>

解决方案2:

1:创建htmlToPdf.ts文件

javascript 复制代码
// utils/htmlToPdf.js:导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

export default {
  install(Vue, options) {
    // id-导出pdf的div容器;title-导出文件标题
    Vue.prototype.htmlToPdf = (id, title) => {
      const element = document.getElementById(`${id}`)
      const opts = {
        scale: 12, // 缩放比例,提高生成图片清晰度
        useCORS: true, // 允许加载跨域的图片
        allowTaint: false, // 允许图片跨域,和 useCORS 二者不可共同使用
        tainttest: true, // 检测每张图片已经加载完成
        logging: true // 日志开关,发布的时候记得改成 false
      }

      html2Canvas(element, opts)
        .then((canvas) => {
          console.log(canvas)
          const contentWidth = canvas.width
          const contentHeight = canvas.height
          // 一页pdf显示html页面生成的canvas高度;
          const pageHeight = (contentWidth / 592.28) * 841.89
          // 未生成pdf的html页面高度
          let leftHeight = contentHeight
          // 页面偏移
          let position = 0
          // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          const imgWidth = 595.28
          const imgHeight = (592.28 / contentWidth) * contentHeight
          const pageData = canvas.toDataURL('image/jpeg', 1.0)
          console.log(pageData)
          // a4纸纵向,一般默认使用;new JsPDF('landscape'); 横向页面
          const PDF = new JsPDF('', 'pt', 'a4')

          // 当内容未超过pdf一页显示的范围,无需分页
          if (leftHeight < pageHeight) {
            // addImage(pageData, 'JPEG', 左,上,宽度,高度)设置
            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
          } else {
            // 超过一页时,分页打印(每页高度841.89)
            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')
        })
        .catch((error) => {
          console.log('打印失败', error)
        })
    }
  }
}

2:在页面中使用

html 复制代码
<template>
  <div>
      <div
       id="pdfDom"
      >
        测试数据
      </div>
      <el-button 
        type="primary" round 
        style="background: #4849FF" 
        @click="btnClick">导出PDF</el-button>
    </div>
 </template>
 <script>
 import JsPDF from 'jspdf'
 import html2Canvas from 'html2canvas'
 mounted() {
    // 导出pdf
    btnClick() {
     this.$nextTick(() => {
         this.htmlToPdf('pdfDom', '个人报告')
     })
    },
  },
 </script>
相关推荐
Cloud_Shy6183 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第六章 Item 40 - 43)
android·开发语言·人工智能·笔记·python·学习方法
AFinalStone4 小时前
Android12 U盘插拔链路源码全解析(五):Framework层(下) StorageManagerService
android·frameworks
杨浦老苏5 小时前
PDF文档管理平台PDFManager
docker·pdf·工具·群晖
rickys20805 小时前
腾讯会议截图自动去除黑边转PDF
pdf·腾讯会议
林九生5 小时前
【实用技巧】MySQL 绿色版一键路径更新脚本详解 —— update_path.bat 深度解析
android·数据库·mysql
2601_961875246 小时前
法考资料电子版|pdf|资料已整理
elasticsearch·搜索引擎·pdf·全文检索·solr·lucene·sphinx
故渊at7 小时前
第十三板块:Android 综合架构与未来演进 | 第三十一篇:Android 架构演进与 Fuchsia OS 的挑战
android·架构·宏内核·微内核·fuchsia·ipc 性能博弈
aqi007 小时前
一文速览 HarmonyOS 6.1.1 推出的十个新特性
android·华为·harmonyos·鸿蒙·harmony
matrixmind17 小时前
aiomysql:异步场景下的 MySQL 驱动
android·数据库·mysql·其他
随遇丿而安7 小时前
第8周:弹窗 / 提示组件全功能与弹窗优化
android