当前位置: 首页 > article >正文

jsPDF+html2canvas实现html转pdf下载+打印

 原理:将页面的dom元素通过html2canvas转成canvas,通过canvas.toDataURL('image/jpeg', 1.0);返回一个包含图片展示的 数据URL,通过JsPDF将调用 addImage用法插入图片数据,JsPDF通过addPage添加页面,pdf.autoPrint()自动打印, pdf.save(`${title}.pdf`)生成pdf文件。

缺陷:通过html2canvas转化后有缩放,无论怎么调整,感觉都不够高清,大多数场景都能满足,但是和手动创建word文档打印,还是有差距,若用在重要文档上,业务审核肯定不通过,这个时候就要求无缩放打印,下一章写如何用JsPDF无缩放打印


pdf.addimage()是一个可用于在PDF文件上插入图片的函数,它提供了控制图片大小、压缩质量、图片旋转度数等属性。

pdf.addImage(image, format, x, y, width, height, alias, compression, rotation)
参数
1、image:表示要插入的图片资源,可以是图片文件的路径或者base64编码字符串。

2、format:表示要插入的图片格式,包括:‘JPEG’, ‘PNG’, ‘GIF’, ‘BMP’, ‘TIFF’, ‘RAW’, ‘JPEG2000’。

3、x:图片在PDF中的x轴坐标,单位为pt(点)。

4、y:图片在PDF中的y轴坐标,单位为pt(点)。

5、width:图片在PDF中的宽度,单位为pt(点)。

6、height:图片在PDF中的高度,单位为pt(点)。

7、alias(可选):指定图片资源的别名。

8、compression(可选):指定图片的压缩质量,取值为0-1之间的浮点数。

9、rotation(可选):指定图片的旋转角度,取值范围为0-360之间的整数

核心代码如下:

/**
 * 生成pdf、pdf打印
 * @param {*} ele  页面解析后的dom
 * @param {*} printParams 打印配置,内部配置参数如下
 * @param {*} title  文件名称
 * @param {*} type 打印类型
 * @param {*} offset  边距
 */
export const printPreviewPDF = (ele, printParams) => {
  const { title, type, offset = 15, iframDom, scale} = printParams;
  const newDom = ele.cloneNode(true);
  newDom.style.position = 'fixed';
  newDom.style.top = 999999;
  document.body.appendChild(newDom);
  html2canvas(newDom, { dpi: 300, scale: scale || 2 }).then((canvas) => {
    const contentWidth = canvas.width;
    const contentHeight = canvas.height;

    const w = 595.28 - offset * 2;
    const h = 841.89 - offset * 2;
    // 一页pdf显示html页面生成的canvas高度;
    const pageHeight = (contentWidth / w) * h;
    // 未生成pdf的html页面高度
    let remainHeight = contentHeight;
    // pdf页面偏移
    let position = 0;
    // html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])
    const imgWidth = w;
    const imgHeight = (w / contentWidth) * contentHeight;

    const pageData = canvas.toDataURL('image/jpeg', 1.0);
    const pdf = new JsPDF('', 'pt', 'a4');

    // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
    // 当内容未超过pdf一页显示的范围,无需分页
    if (remainHeight < pageHeight) {
      pdf.addImage(pageData, 'JPEG', offset, offset, imgWidth, imgHeight);
    } else {
      while (remainHeight > 0) {
        pdf.addImage(pageData, 'JPEG', offset, position, imgWidth, imgHeight);
        remainHeight -= pageHeight;
        position -= 841.89;
        // 避免添加空白页
        if (remainHeight > 0) {
          pdf.addPage();
        }
      }
    }
    if (type === PRINT_TYPE.CURRENT_PRINT) {
      pdf.autoPrint();
      iframDom.src = pdf.output('datauristring'); // 在iframe中显示,实现当前页面打印
      // 打印
    } else if (type === PRINT_TYPE.DOWNLOAD) {
      // 下载
      pdf.save(`${title}.pdf`);
    } else {
      // pdf.autoPrint();
      // pdf.output('dataurlnewwindow'); --- 这个方法,导致 超过 3页,第4页的时候 页面空白。弃用。
      const link = window.URL.createObjectURL(toBlob(pdf.output('datauristring')));
      const myWindow = window.open(link);
      myWindow.print();
    }
    newDom.remove();
  });
};


http://www.kler.cn/a/231333.html

相关文章:

  • MySQL超详细安装配置教程(亲测有效)
  • 【微软:多模态基础模型】(5)多模态大模型:通过LLM训练
  • 【leetcode 02】27. 移除元素
  • BERT模型中的多头注意力机制详解
  • Android Activity Manager Service (AMS) 深入详解及源码分析
  • 【模块一】kubernetes容器编排进阶实战资源对象之Configmap与Secret简介
  • npm_config_xxx
  • 信息隐藏研究新动向
  • 使用easyExcel 定义表头 字体 格式 颜色等,定义表内容,合计
  • 标注工具体积3D数据集
  • 力扣题目训练(7)
  • 2024.2.7
  • kafka 文件存储机制
  • ComfyUI 学习笔记
  • 如何部署基于 Pyramid 的 Python WSGI Web 应用程序
  • C++ std::map 取值方式
  • 网站被攻击有什么办法呢?
  • IP数据云识别真实IP与虚假流量案例
  • 计网——运输层、端口号
  • Elasticsearch中Document Routing特性
  • Vue3.0(四):Composition API的使用
  • vue3的pinia基本用法
  • dynamic_cast运行阶段类型识别
  • vscode代码快捷键
  • React+Antd+tree实现树多选功能(选中项受控+支持模糊检索)
  • 学习总结14