【问题标题】:wkhtmltopdf missing SVG paths (Rendering)wkhtmltopdf 缺少 SVG 路径(渲染)
【发布时间】:2018-10-03 20:18:19
【问题描述】:

我在 HMTL 代码中使用了一个图像,如下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
  </head>
  <body>
    <svg height="291pt" version="1.1" viewBox="0 0 291 291" width="291pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs>  <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}  </style> </defs> <g id="figure_1">  <g id="patch_1">   <path d="M 0 291.4 L 291.4 291.4 L 291.4 0 L 0 0 z" style="fill:none;"></path>  </g>  <g id="axes_1">   <g id="line2d_1">    <path clip-path="url(#p6e64365aaf)" d="M 268.427273 145.7 L 207.063636 251.984936 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_2">    <path clip-path="url(#p6e64365aaf)" d="M 248.397453 148.307103 L 199.306544 233.335052 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_3">    <path clip-path="url(#p6e64365aaf)" d="M 207.063636 251.984936 L 84.336364 251.984936 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_4">    <path clip-path="url(#p6e64365aaf)" d="M 84.336364 251.984936 L 22.972727 145.7 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_5">    <path clip-path="url(#p6e64365aaf)" d="M 92.093456 233.335052 L 43.002547 148.307103 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_6">    <path clip-path="url(#p6e64365aaf)" d="M 22.972727 145.7 L 84.336364 39.415064 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_7">    <path clip-path="url(#p6e64365aaf)" d="M 84.336364 39.415064 L 207.063636 39.415064 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_8">    <path clip-path="url(#p6e64365aaf)" d="M 96.609091 55.457845 L 194.790909 55.457845 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>   <g id="line2d_9">    <path clip-path="url(#p6e64365aaf)" d="M 207.063636 39.415064 L 268.427273 145.7 " style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.2;"></path>   </g>  </g> </g> <defs>  <clipPath id="p6e64365aaf">   <rect height="270" width="270" x="10.7" y="10.7"></rect>  </clipPath> </defs></svg>
  </body>
</html>

当我使用 wkhtmltopdf 将其转换为 PDF 时,缺少一些 SVG 路径。有没有人有同样的问题?这个问题的一些解决方法?

我尝试在代码中单独使用相对路径、完整路径、base64 源和 SVG(如示例中所示)。

wkhtmltopdf 版本:0.12.4

【问题讨论】:

  • 我不确定它是否有帮助,但看起来 wkhtmltopdf (bitbucket) 的新版本已经解决了这个问题。

标签: html svg rendering wkhtmltopdf


【解决方案1】:

所以不是一个精确的解决方案,但现在更好的选择是在无头模式下使用chrome

$ chrome --headless --disable-gpu --print-to-pdf test.html
[0427/011400.636954:WARNING:dns_config_service_posix.cc(174)] dns_config has unhandled options!
[0427/011400.638406:ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context.
[0427/011400.801881:INFO:headless_shell.cc(586)] Written to file output.pdf. 

另外,如果您想更好地控制流程,您可以使用 NodeJS 和 puppeteer

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'hn.pdf', format: 'A4'});

  await browser.close();
})();

【讨论】:

  • 非常感谢,但我确实需要使用 Wkhtmltopdf,因为这只是在 Python (jinja2/pdfkit) 中从 html 转换为 pdf 的大文档的一部分。
  • 那么我建议你在那个 repo 上打开一个 bug,如果我没记错的话,chrome puppeteer 也有 python 绑定
  • 我做到了,但仍然没有答案。我去找谷歌木偶师。
  • @IurySousa,如果您确实觉得这个答案会有所帮助,请不要忘记在赏金到期之前分配赏金。
【解决方案2】:

一种解决方法是在转换为 .PDF 之前将 .SVG 文件转换为 .PNG 文件。 .SVG 代码可以通过AgilityPack 提取或将文件作为字符串读取。然后使用Svg library转换成.PNG如下:

var svg = SvgDocument.FromSvg<SvgDocument>(svgXmlAsString);
var bitmap = svg.Draw();
var codec = "image/png".ParseImageCodecInfo();
// intermediaryStream required due to image.Save attempting read access
using (var intermediaryStream = new MemoryStream())
{
    bitmap.Save(intermediaryStream, codec);
    intermediaryStream.Position = 0;
    await intermediaryStream.CopyToAsync(responseStream);
    await intermediaryStream.FlushAsync();
    await responseStream.FlushAsync();
}

【讨论】:

  • 谢谢@Joshcodes。原来我已经不在这个项目中了,但是你的解决方案和我们所做的非常相似。出于打印质量的原因,我们一直在寻找一种保持 SVG 格式的方法。此外,我们将图像放在具有不同行颜色的剥离表上。这意味着我们需要为 PNG 背景颜色使用 alpha。但无论如何,它是这样工作的。
  • 感谢您的回复。在打印质量和 alpha 背景方面,我们的情况非常相似。
猜你喜欢
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
相关资源
最近更新 更多