使用Javascript从Div中的HTML生成pdf

2022-08-29 23:53:49

我有以下html代码:

<!DOCTYPE html>
<html>
    <body>
        <p>don't print this to pdf</p>
        <div id="pdf">
            <p><font size="3" color="red">print this to pdf</font></p>
        </div>
    </body>
</html>

我想做的就是打印成pdf,无论在div中找到的任何东西都是“pdf”的ID。这必须使用JavaScript完成。然后,应自动下载“pdf”文档,文件名为“foobar.pdf

我一直在使用jspdf来做到这一点,但它唯一的功能是“text”,它只接受字符串值。我想将HTML提交到jspdf,而不是文本。


答案 1

jsPDF能够使用插件。为了使它能够打印HTML,您必须包含某些插件,因此必须执行以下操作:

  1. 转到 https://github.com/MrRio/jsPDF 并下载最新版本。
  2. 在项目中包括以下脚本:
    • jspdf.js
    • jspdf.plugin.from_html.js
    • jspdf.plugin.split_text_to_size.js
    • jspdf.plugin.standard_fonts_metrics.js

如果要忽略某些元素,则必须使用ID标记它们,然后可以在jsPDF的特殊元素处理程序中忽略该ID。因此,您的 HTML 应如下所示:

<!DOCTYPE html>
<html>
  <body>
    <p id="ignorePDF">don't print this to pdf</p>
    <div>
      <p><font size="3" color="red">print this to pdf</font></p>
    </div>
  </body>
</html>

然后,您可以使用以下 JavaScript 代码在弹出窗口中打开创建的 PDF:

var doc = new jsPDF();          
var elementHandler = {
  '#ignorePDF': function (element, renderer) {
    return true;
  }
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
    source,
    15,
    15,
    {
      'width': 180,'elementHandlers': elementHandler
    });

doc.output("dataurlnewwindow");

对我来说,这创建了一个漂亮整洁的PDF,其中只包含“将此打印为pdf”行。

请注意,特殊元素处理程序仅处理当前版本中的 ID,GitHub 问题中也对此进行了说明。它指出:

由于匹配是针对节点树中的每个元素完成的,因此我的愿望是使其尽可能快。在这种情况下,它意味着“只有元素ID是匹配的”元素ID仍然以jQuery样式“#id”完成,但这并不意味着支持所有jQuery选择器。

因此,用像“.ignorePDF”这样的类选择器替换“#ignorePDF”对我来说不起作用。相反,您必须为每个元素添加相同的处理程序,您希望忽略这些处理程序,例如:

var elementHandler = {
  '#ignoreElement': function (element, renderer) {
    return true;
  },
  '#anotherIdToBeIgnored': function (element, renderer) {
    return true;
  }
};

示例中还指出,可以选择诸如“a”或“li”之类的标签。不过,对于大多数用例来说,这可能有点不受限制:

我们支持特殊的元素处理程序。使用 jQuery 样式的 ID 选择器注册它们以获取 ID 或节点名称。(“#iAmID”,“div”,“span”等)目前不支持任何其他类型的选择器(类,化合物)。

要添加的一件非常重要的事情是,您丢失了所有样式信息(CSS)。幸运的是,jsPDF能够很好地格式化h1,h2,h3等,这对于我的目的来说已经足够了。此外,它将仅打印文本节点中的文本,这意味着它不会打印文本区域等的值。例:

<body>
  <ul>
    <!-- This is printed as the element contains a textnode -->        
    <li>Print me!</li>
  </ul>
  <div>
    <!-- This is not printed because jsPDF doesn't deal with the value attribute -->
    <input type="textarea" value="Please print me, too!">
  </div>
</body>

答案 2

这是简单的解决方案。这对我有用。您可以使用javascript打印概念,并简单地将其另存为pdf。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type="text/javascript">
        $("#btnPrint").live("click", function () {
            var divContents = $("#dvContainer").html();
            var printWindow = window.open('', '', 'height=400,width=800');
            printWindow.document.write('<html><head><title>DIV Contents</title>');
            printWindow.document.write('</head><body >');
            printWindow.document.write(divContents);
            printWindow.document.write('</body></html>');
            printWindow.document.close();
            printWindow.print();
        });
    </script>
</head>
<body>
    <form id="form1">
    <div id="dvContainer">
        This content needs to be printed.
    </div>
    <input type="button" value="Print Div Contents" id="btnPrint" />
    </form>
</body>
</html>