如何使用 jQuery 将 HTML 导出为 PDF(多页)? [英] How to Export HTML to PDF (multiple pages) using jQuery?

查看:68
本文介绍了如何使用 jQuery 将 HTML 导出为 PDF(多页)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 jQuery 将 HTML 导出为 PDF,它工作正常,但仅适用于 HTML 将在单页 PDF 中完成的情况.

但是当 html 中有大量数据并且 PDF 页面可能不止一个时,我面临将 html 导出为 PDF 的困难.

我的代码:

 $("body").on("click", "#downloadPDF", function () {html2canvas($('#downloadPDFData')[0], {onrendered:函数(画布){var data = canvas.toDataURL();var docDefinition = {内容: [{图像:数据,宽度:500}]};pdfMake.createPdf(docDefinition).download("report.pdf");}});});

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.22/pdfmake.min.js"></script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script><button id="downloadPDF">下载PDF</button><div id="下载PDFData"><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p><p>Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商使用了一个类型的厨房并争先恐后地制作了一本类型样本书.它不仅存活了五个世纪,而且还经历了电子排版的飞跃,基本保持不变.它在 1960 年代随着包含 Lorem Ipsum 段落的 Letraset 表的发布而流行,最近随着桌面出版软件 Aldus PageMaker 的发布,包括 Lorem Ipsum 的版本.</p>

我的代码有什么问题

回答将不胜感激!

解决方案

我发现了 2 个问题...

    1. 最好使用最新版本的 pdfMake.您使用的是 0.1.22...我使用了 0.1.68nofollow noreferrer">cdnjs.

    1. 似乎 pdfMake 无法拆分"一个图像并传播到几个页面......所以你必须提供一些已经分割的块.幸运的是,我找到了一个 SO 答案,特别是关于这个......我在这里稍微调整了一下.

您可以选择预定义的页面格式,例如 letter 或 A4 等作为 pdfMake 参数.请参阅可能的选项.

然后您将不得不通过尝试/失败来调整分割图像块的高度.在这里,我发现 775px 对于信件页面来说似乎不错...但只能使用您提供的 HTML 进行尝试.

SO 片段不允许下载.所以,把它变成一个片段没用,但你可以检查我的 CodePen.

一些文档:


//从这个 SO 答案稍微修改了函数:https://stackoverflow.com/a/21937796/2159528//它现在返回为 pdfMake 格式化的对象函数getClippedRegion(图像,x,y,宽度,高度){var canvas = document.createElement("canvas"),ctx = canvas.getContext(2d");canvas.width = 宽度;canvas.height = 高度;//源区域 dest.地区ctx.drawImage(image, x, y, width, height, 0, 0, width, height);返回 {//这些是一些 pdfMake 参数图像:canvas.toDataURL(),宽度:500};}$("body").on("click", "#downloadPDF", function () {html2canvas($("#downloadPDFData")[0], {onrendered:函数(画布){//根据所需的 PDF 页面高度,将 html2canvas 生成的画布拆分成几个让 splitAt = 775;//适合LETTER"的页面高度页面大小...让图像 = [];让 y = 0;而 (canvas.height > y) {images.push(getClippedRegion(canvas, 0, y, canvas.width, splitAt));y += splitAt;}//使用 pdfMake 创建 PDFvar docDefinition = {内容:图像,页面大小:字母"};pdfMake.createPdf(docDefinition).download(report.pdf");}});});

I want to Export HTML to PDF using jQuery that is working fine but only for when HTML will finish in single page PDF.

But I'm facing difficultly export html to PDF when there is lots of data in html and PDF pages may be more than one.

My code:

   $("body").on("click", "#downloadPDF", function () {
        html2canvas($('#downloadPDFData')[0], {
            onrendered: function (canvas) {
                var data = canvas.toDataURL();
                var docDefinition = {
                    content: [{
                        image: data,
                        width: 500
                    }]
                };
                pdfMake.createPdf(docDefinition).download("report.pdf");
            }
        });
    });

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.22/pdfmake.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
    
  <button id="downloadPDF">Download PDF</button>
  
    <div id="downloadPDFData">
    <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
       <p>
   Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
    </div>

What is wrong with my code

Answer will be appreciated!

解决方案

I found 2 issues...

    1. Better use the latest version of pdfMake. You were using 0.1.22... I used 0.1.68 found on cdnjs.

    1. Seems like pdfMake isn't able to "split" an image and spead to several pages... So you have to provide some already splitted chunks. Fortunately, I found a SO answer about this specifically... Which I very slightly adapted here.

You can choose a predefined page format, like letter or A4, etc as a pdfMake param. See possible options.

Then you will have to adjust the height of the splitted image chunks by try/fail. Here, I found that 775px seemed good for a letter page... But only tried it with the HTML you provided.

SO snippets are disallowing downloads. So, useless to make it a snippet but you can check my CodePen.

Some documentation:


// Slightly adapted function from this SO answer: https://stackoverflow.com/a/21937796/2159528
// It now returns the objects formatted for pdfMake
function getClippedRegion(image, x, y, width, height) {
  var canvas = document.createElement("canvas"),
      ctx = canvas.getContext("2d");

  canvas.width = width;
  canvas.height = height;

  //                   source region         dest. region
  ctx.drawImage(image, x, y, width, height, 0, 0, width, height);

  return {
    // Those are some pdfMake params
    image: canvas.toDataURL(),
    width: 500
  };
}

$("body").on("click", "#downloadPDF", function () {

  html2canvas($("#downloadPDFData")[0], {
    onrendered: function (canvas) {

      // split the canvas produced by html2canvas into several, based on desired PDF page height
      let splitAt = 775; // A page height which fits for "LETTER" pageSize...

      let images = [];
      let y = 0;
      while (canvas.height > y) {
        images.push(getClippedRegion(canvas, 0, y, canvas.width, splitAt));
        y += splitAt;
      }

      // PDF creation using pdfMake
      var docDefinition = {
        content: images,
        pageSize: "LETTER"
      };
      pdfMake.createPdf(docDefinition).download("report.pdf");
    }
  });
});

这篇关于如何使用 jQuery 将 HTML 导出为 PDF(多页)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆