带有wkhtmltopdf的SVG内容无法正确呈现

时间:2019-01-24 06:48:43

标签: svg wkhtmltopdf

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

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

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

在屏幕上,呈现SVG like this,而不是像素化。

但是在生成的PDF文件中,它得到like this,有些行被像素化,其渲染使您想到的是栅格图像而不是矢量图像。

使用Windows放大镜放大屏幕图像,而在查看器中放大pdf。

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

无需任何其他参数即可完成转换,

titleList.stream()
        .forEach(titleMap ->
            combineList.addAll(
                codeList.stream()
                    .filter(codeMap -> titleMap.get("ID").equals(codeMap.get("ID")))
                    .map(codeMap -> {
                      Map<String, Object> tempMap = new HashMap<>();
                      tempMap.put("ID", titleMap.get("ID"));
                      tempMap.put("NAME", titleMap.get("NAME"));
                      tempMap.put("ID", codeMap.get("ID"));
                      tempMap.put("AGE", codeMap.get("AGE"));
                      return tempMap;
                    })
                    .collect(Collectors.toList())
            )
        );

测试文件在这里:

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的建议或想法。

1 个答案:

答案 0 :(得分:2)

这并不是真正的解决方案,但更多的是一种解决方法。老实说,我不记得我是怎么找到它的(太长了,可能是通过修改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

希望这会有所帮助。