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>
相关推荐
2501_915909067 分钟前
iOS如何查看电池容量?理解系统限制与开发者级能耗调试方法
android·ios·小程序·https·uni-app·iphone·webview
NCHUtianlin20 分钟前
JAVA生成PDF(itextpdf)
java·开发语言·pdf
奔跑吧 android3 小时前
【android bluetooth 协议分析 07】【SDP详解 2】【SDP 初始化】
android·bluetooth·aosp15·bt·gd·sdp_init
梦否6 小时前
Android 代码热度统计(概述)
android
xchenhao9 小时前
基于 Flutter 的开源文本 TTS 朗读器(支持 Windows/macOS/Android)
android·windows·flutter·macos·openai·tts·朗读器
coder_pig10 小时前
跟🤡杰哥一起学Flutter (三十五、玩转Flutter滑动机制📱)
android·flutter·harmonyos
消失的旧时光-194311 小时前
OkHttp SSE 完整总结(最终版)
android·okhttp·okhttp sse
ansondroider12 小时前
OpenCV 4.10.0 移植 - Android
android·人工智能·opencv
hsx66614 小时前
Kotlin return@label到底怎么用
android
itgather15 小时前
安卓设备信息查看器 - 源码编译
android