LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

前端 HTML 转 PDF

zhenglin
2025年12月2日 17:4 本文热度 330

前端 HTML 转 PDF 的工具函数,核心作用是:把网页中指定 ID 的 DOM 元素(比如表格、报表、表单等),通过 html2canvas 和 jspdf 两个库转换成 PDF 文件并下载到本地。

简单说:它能让用户 “一键下载” 网页上的某个区域为 PDF(比如报表、数据统计页、合同预览页等),还预留了 “水印功能” 的注释代码(可按需启用)。


核心依赖说明

函数依赖两个关键库,必须先安装才能使用:


库名作用
html2canvas把指定的 HTML 元素 “截图” 成 Canvas 画布(相当于把网页内容转成图片)
jspdf生成 PDF 文件,再把 Canvas 图片嵌入 PDF 中,最终触发浏览器下载


函数核心逻辑(分步拆解)

函数名 htmlToPdf,接收两个参数:

  • title:下载的 PDF 文件名(比如 “2024 年报表”);


  • htmlId:需要转换的 HTML 元素的 ID(比如 #report-container)。


整体流程:定位 HTML 元素 → 滚动置顶避免截图不全 → (可选加水印)→ HTML 转 Canvas → Canvas 转 PDF → 下载 PDF

1. 准备工作:定位元素 + 滚动置顶

const element = document.querySelector(htmlId); // 找到要转PDF的HTML元素

// 滚动置顶:避免元素被滚动条遮挡,导致截图不全

window.pageYOffset = 0;

document.documentElement.scrollTop = 0;

document.body.scrollTop = 0;

2. 可选:添加水印(已注释,需启用可取消注释)

注释部分的逻辑是:创建一个带文字水印(比如 “我是水印”)的 Canvas,作为背景图添加到目标元素上,转 PDF 时水印会一起被截取(适合需要版权保护的场景)。


3. HTML 转 Canvas(核心步骤)


html2Canvas(element, {

  allowTaint: true, // 允许跨域图片(如果元素内有跨域图片需开启)

  useCORS: true, // 启用CORS跨域支持

  scale: 2, // 缩放2倍:提升PDF清晰度(代价是文件变大)

  height: element.scrollHeight, // 用元素实际滚动高度:避免只截取可视区域(关键!)

  windowHeight: element.scrollHeight

}).then(canvas => {

  // Canvas生成成功后,进入PDF生成步骤

});

4. Canvas 转 PDF 并下载


const contentWidth = canvas.width; // Canvas宽度

const contentHeight = canvas.height; // Canvas高度

const pageHeight = (contentWidth * 841.89) / 592.28; // A4纸的高度(按比例计算)

let leftHeight = contentHeight; // 未生成PDF的剩余高度

let position = 0; // PDF页面偏移量


// 创建A4尺寸的PDF(纵向:"p" = portrait)

const pdf = new JsPDF("p", "pt", "a4");

// Canvas转成图片数据(jpeg格式,质量1.0)

const pageData = canvas.toDataURL("image/jpeg", 1.0);


// 处理分页:如果内容高度超过1页A4纸,自动分页

if (leftHeight < pageHeight) {

  // 单页:直接嵌入图片(20是左右边距,避免内容贴边)

  pdf.addImage(pageData, "JPEG", 20, 20, imgWidth, imgHeight);

} else {

  // 多页:循环截取内容,每满1页添加新页面

  while (leftHeight > 0) {

    pdf.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight);

    leftHeight -= pageHeight;

    position -= 841.89; // 向下偏移A4纸高度

    if (leftHeight > 0) pdf.addPage(); // 剩余内容不为空时,新增一页

  }

}


// 触发下载:文件名=title+".pdf"

pdf.save(title + ".pdf");

如何使用

1. 安装依赖



# npm 安装

npm install html2canvas jspdf --save


# pnpm 安装

pnpm add html2canvas jspdf

2.创建一个htmlToPdf.js文件


import html2Canvas from "html2canvas";

import JsPDF from "jspdf";

// title:下载文件的名称  htmlId:包裹的标签的id

const htmlToPdf = (title, htmlId) => {

  const element = document.querySelector(htmlId);

  window.pageYOffset = 0;

  document.documentElement.scrollTop = 0;

  document.body.scrollTop = 0;

  setTimeout(() => {

    // // 以下注释的是增加导出的pdf水印 !!!!!!!!!!!!!

    // const value = '我是水印'

    // //创建一个画布

    // let can = document.createElement('canvas')

    // //设置画布的长宽

    // can.width = 400

    // can.height = 500

    // let cans = can.getContext('2d') as any

    // //旋转角度

    // cans.rotate((-15 * Math.PI) / 180)

    // cans.font = '18px Vedana'

    // //设置填充绘画的颜色、渐变或者模式

    // cans.fillStyle = 'rgba(200, 200, 200, 0.40)'

    // //设置文本内容的当前对齐方式

    // cans.textAlign = 'left'

    // //设置在绘制文本时使用的当前文本基线

    // cans.textBaseline = 'Middle'

    // //在画布上绘制填色的文本(输出的文本,开始绘制文本的X坐标位置,开始绘制文本的Y坐标位置)

    // cans.fillText(value, can.width / 8, can.height / 2)

    // let div = document.createElement('div')

    // div.style.pointerEvents = 'none'

    // div.style.top = '20px'

    // div.style.left = '-20px'

    // div.style.position = 'fixed'

    // div.style.zIndex = '100000'

    // div.style.width = element.scrollHeight + 'px'

    // div.style.height = element.scrollHeight + 'px'

    // div.style.background =

    //   'url(' + can.toDataURL('image/png') + ') left top repeat'

    // element.appendChild(div) // 到页面中

    html2Canvas(element, {

      allowTaint: true,

      useCORS: true,

      scale: 2, // 提升画面质量,但是会增加文件大小

      height: element.scrollHeight, // 需要注意,element的 高度 宽度一定要在这里定义一下,不然会存在只下载了当前你能看到的页面   避雷避雷!!!

      windowHeight: element.scrollHeight

    }).then(function (canvas) {

      const contentWidth = canvas.width;

      const contentHeight = canvas.height;

      // 一页pdf显示html页面生成的canvas高度;

      const pageHeight = (contentWidth * 841.89) / 592.28;

      // 未生成pdf的html页面高度

      let leftHeight = contentHeight;

      // 页面偏移

      let position = 0;

      // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高  //40是左右页边距

      const imgWidth = 595.28 - 40;

      const imgHeight = (592.28 / contentWidth) * contentHeight;

      const pageData = canvas.toDataURL("image/jpeg", 1.0);

      const pdf = new JsPDF("p", "pt", "a4");

      // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)

      // 当内容未超过pdf一页显示的范围,无需分页

      if (leftHeight < pageHeight) {

        pdf.addImage(pageData, "JPEG", 20, 20, imgWidth, imgHeight);

      } else {

        while (leftHeight > 0) {

          pdf.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight);

          leftHeight -= pageHeight;

          position -= 841.89;

          // 避免添加空白页

          if (leftHeight > 0) {

            pdf.addPage();

          }

        }

      }

      pdf.save(title + ".pdf");

    });

  }, 1000);

};

export default htmlToPdf;

3. 在 Vue/React 中使用示例

代码高亮:

<!-- Vue 示例:页面中有一个要转PDF的区域 -->

<template>

  <div>

    <!-- 要转PDF的元素:必须有唯一ID -->

    <div id="report-container">

      <h1>2024年销售报表</h1>

      <table>...</table> <!-- 报表内容 -->

    </div>

    <!-- 下载按钮 -->

    <button @click="downloadPdf">下载PDF</button>

  </div>

</template>


<script>

import htmlToPdf from '@/utils/htmlToPdf'; // 导入函数


export default {

  methods: {

    downloadPdf() {

      // 调用函数:参数1=PDF文件名,参数2=目标元素ID(注意加#)

      htmlToPdf('2024年销售报表', '#report-container');

    }

  }

}

</script>

 

常见问题与优化

1. 截图不全 / 内容缺失?

  • 确保目标元素的 height/scrollHeight 正确(函数已处理,但如果元素是动态渲染的,可能需要调整 setTimeout 延迟时间,比如从 1000ms 改为 2000ms);

  • 避免元素内有 position: fixed 的内容(会被重复截取)。

2. 图片跨域导致截图空白?

  • 确保 html2Canvas 配置中 allowTaint: true 和 useCORS: true 已开启;

  • 图片服务器需配置 CORS 允许当前域名访问。

3. PDF 清晰度太低?

  • 增大 scale 参数(比如改为 3),但会导致文件变大;

  • 把 toDataURL 的质量参数从 1.0 保留(已最优)。

4. 想要启用水印?

  • 取消代码中水印相关的注释,修改 value 为你的水印文字(比如 “内部资料”);

  • 调整 rotate 旋转角度、font 字体大小、fillStyle 透明度(0.4 为半透明)。


总结

这个函数是前端开发中非常实用的 “HTML 转 PDF 工具”,适用于报表下载、合同导出、数据归档等场景。

核心是通过 html2canvas 转图片、jspdf 生成文件,逻辑完整且预留了水印扩展,稍作调整就能适配大部分项目需求


参考文章:原文链接



该文章在 2025/12/2 17:04:16 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved