如何使用 PrimeFaces Diagram 导出图像文件

How to export image file using PrimeFaces Diagram

我正在使用 The Diagram component 的 PrimeFaces。 我想从该组件获取图像(如 png)。

我该怎么做?

我试过 html2canvas and canvg,但我无法获得相同的图像。 我也试过https://github.com/jsplumb/jsPlumb/issues/35#issuecomment-82196174,但不好。

我的代码如下。

DiagramShowView.java

package //omitted;

import // omitted
import org.primefaces.model.diagram.DiagramModel;

@Named
@ViewScoped
public class DiagramShowView implements Serializable {

    @Getter
    private DiagramModel flow;

    public void init(){
        this.flow = createDiagramModel(); // omitted createDiagramModel() impementation.
    }
}

Diagram.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<f:metadata><f:viewAction action="#{diagramShowView.init()}"/></f:metadata>
<h:body>
    <h:form id="mainForm">
        <style type="text/css">
            .ui-diagram-element {
                border: 0.1em dotted #d4e06b;
                width: 14em;
                height: 4em;
                line-height: 4em;
                text-align: center;
            }
        </style>
        <div class="ui-g">
            <div class="ui-g-6">
                <p:diagram value="#{diagramShowView.flow}" style="width:100%;height:500px;" id="flow"
                           styleClass="ui-widget-content" var="el">
                    <f:facet name="element">
                        <h:outputText value="#{el}"
                                      style="display:block;margin-top:0.5em;"/>
                    </f:facet>
                </p:diagram>
            </div>
            <div class="ui-g-6">
                <p id="copy"/>
            </div>
        </div>
        <script type="text/javascript" src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
        <script type="text/javascript" src="https://canvg.github.io/canvg/demo/v2/canvg.js"/>
        <script type="text/javascript">
            let el = document.getElementById("mainForm:flow");
            html2canvas(document.getElementById("mainForm:flow"), {
                width: el.scrollWidth,
                height: el.scrollHeight
            }).then(function (canvas) {
                // this code copy from github issue
                ctx = canvas.getContext('2d');
                $flows = $('> svg', el);
                $flows.each(function () {
                    $svg = $(this)
                    offset = $svg.position();
                    svgStr = this.outerHTML;
                    ctx.drawSvg(svgStr, offset.left, offset.top);
                });
                $endpoints = $('._jsPlumb_endpoint > svg', el);
                $endpoints.each(function () {
                    $svg = $(this)
                    offset = $svg.parent().position();
                    svgStr = this.outerHTML;
                    ctx.drawSvg(svgStr, offset.left, offset.top);
                });
                // end of copy code.

                document.getElementById("copy").appendChild(canvas);
            });
        </script>
    </h:form>
</h:body>
</html>

浏览器输出如下。 左边的组件是 jsf 的 darwn。 html2canvas 和 canvg.js.

使用了正确的组件

我自己解决了一部分。 原因是图像需要更大 area.The 答案在下面 post.

HTML2Canvas does not render full div, only what is visible on screen?