繁体   English   中英

使用CDN库和外部样式表将HTML转换为PDF

[英]Convert HTML with CDN Libraries and External stylesheets to PDF

在此处输入图片说明 我用bootstrap和material design lite设计了我的简历,现在我想将html页面转换为pdf文件。

我尝试了一些库(jsPdf)和一些工具(html2pdf,princexml),它会生成pdf文件,但问题是pdf不是它在html页面中显示的样子。

没有样式,我得到的输出类似于在浏览器中按ctrl + p`。

我的问题是, 有没有解决我问题的工具或库? 还是我可以使用上述工具中的任何选项?

pdf输出 在此处输入图片说明

在后端尝试使用此转换器WKHTMLTOPDF 它输出的正是您在浏览器中看到的内容。 它支持html,css甚至js。 基于Webkit的Wkhtmltopdf。

使用运行时可以这样使用

wkhtmltopdf http://google.com google.pdf

在您的情况下,似乎wkhtmltopdf无法加载CSS。 检查正确的CSS包含路径。 不要使用相对路径。

您的问题是Bootstrap库,而不是您使用的任何插件或PDF工具。 当您“打印”网页时,它会删除大多数样式,包括打印为PDF。 我的公司DocRaptor HTML to PDF服务,在一篇很棒的博客文章中 ,列出了建议的修复程序列表,以使Bootstrap样式能够正确打印,但可以将它们概括为:

  • 使用屏幕CSS模式/规则打印,而不打印。 否则,您必须对Bootstrap进行大量替代才能使其正常工作。 使渲染器使用屏幕模式要容易得多。
  • Bootstrap会认为大多数PDF是像手机一样的超小型设备,因此您必须调整断点或代码内列定义。
  • 如果最后一列移至新行,这是因为Bootstrap将许多列的宽度定义为XX.66666667%。 PDF引擎将所有这些加在一起,并且由于末尾有7个,因此从技术上讲它大于100%。 由于行宽超过100%,因此会将最后一列碰撞到新行。 解决方法是覆盖Bootstrap的列宽( 用于该类的方便的Gist文件 )。

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 Issue中也有说明。 它指出:

因为匹配是针对节点树中的每个元素完成的,所以我希望使其尽可能快。 在那种情况下,这意味着“仅元素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等,足以满足我的目的。 另外,它将仅打印文本节点内的文本,这意味着它将不打印textareas等的值。 例:

<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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM