带有 wkhtmltopdf 的 SVG 内容未正确呈现

SVG content with wkhtmltopdf not rendered properly

在使用带有嵌入式 SVG 图表的文件使用 wkhtmltopdf 渲染 PDF 文件时,我遇到了一个奇怪的渲染问题。

为了这个问题的目的,我试图简化 SVG 和 HTML 内容,同时保持问题的可重现性。但是,在生产中,我不能(或者更确切地说我非常不想)更改 SVG 内容,因为它是从 canvas2svg 生成的。

SVG是一个简单的折线图,至少有2个数据集(示例有4个)。

在屏幕上,呈现 SVG like this,未像素化。

但在生成的 PDF 文件中,它变得 like this,一些线条被像素化,渲染让你想到光栅图像而不是矢量图像。

使用 windows 放大镜放大屏幕图像,同时使用查看器放大 pdf。

通过改变图表中数据集的数量,我的结论是只有最后一个可以正确呈现。

转换是在没有任何附加参数的情况下完成的,如下所示:

wkhtmltopdf.exe test.html test.pdf

测试文件在这里:

test.svg : https://drive.google.com/file/d/1y3onOnBhMPrlUgrRYQXlIckTOgvzuW2L/view?usp=sharing

test.html : https://drive.google.com/file/d/1SkspS3IfggSz9RCf17LL4w9qo8dN0WWH/view?usp=sharing

test.pdf : https://drive.google.com/file/d/1q7HXTqJASRDIzaFLn9w4XCVfHF5z2n5M/view?usp=sharing

任何能为我指出修复或解决方法的解释,或任何关于如何正确获取 PDF 的建议或想法,我们都将不胜感激。

这并不是真正的解决方案,但更像是一种解决方法。老实说,我不记得我是怎么找到它的(太久了,可能是通过修改 SVG 内容),但它就在这里。

SVG里面有一些clip-path属性;诀窍是将其删除。我不是 SVG 专家,所以我无法解释为什么会这样。

原始 SVG 看起来像这样:

...
<defs>
    <clipPath id="vOWrkDAZwIkA">
        <path fill="none" stroke="none" d="..."/>
    </clipPath>
</defs>
...
<g clip-path="url(#vOWrkDAZwIkA)">
...
</g>

我的应用程序的流程是这样的:

  • 网络应用显示带有嵌入式图表的报告
  • 图表内容被发送回服务器以重新组合报告
  • wkhtmltopdf 应用程序
  • 将报告从 html 转换为 PDF

所以在重新组合 SVG 内容之前,我使用了这个:

String svgData = /* just get the chart data here or possibly the whole HTML content */;
String regex = "(\sclip-path=\\"url\(#)[a-zA-Z]*(\)\\")";
Matcher m = Pattern.compile(regex).matcher(svgData);

while (m.find()) {
    svgData = svgData.replace(m.group(0), "");
}   
// use the modified SVG data

希望这对您有所帮助。