Skip to main content

Export DIV contents to PNG

Comments

2 comments

  • Johnny Stevens

    I'll provide an update and ask a new, more refined questions.

    I'm using the html2canvas js library to grab a PNG of the chart and I'm hoping to pass that canvas.toBlob result to another report for the PDF export. I'll place my SharedElement containing the code and the note that the SharedElement requires 2 Shared Parameters (html2CanvasElement into which the element to rendered as PNG is entered, and mainChartId which is required for the waitForElement I placed in the function... as in, wait until this Chart is rendered to take the snapshot).

    <Report
        ID="sharedExport"
        >
        <SharedElement
            ID="sharedHtmlCanvas"
            >
            <Note
                Note="Add this Shared Element to render HTML output as an image for Export"
            />
            <Note
                Note="The Action.ExportPDF and Action.ExportNativeExcel need to be edited to export divCanvas instead of divResults"
            />
            <Note
                Note="Add &quot;clickExport=1&quot; as a Link Parameter to the PDF/Excel Export action to trigger this code"
            />
            <Division
                Condition="0@Request.clickExport~=0"
                HtmlDiv="True"
                ID="divCanvas"
                >
                <Note
                    Note="The Condition on divCanvas for Production is clickExport=1"
                />
                <HtmlTag
                    Class="ThemeHidden"
                    HtmlTagName="canvas"
                    >
                    <HtmlAttributeParams
                        height="600"
                        id="canvasExport"
                        width="1200"
                    />
                </HtmlTag>
                <IncludeScript
                    ID="html2canvas"
                    IncludedScript="function waitForElement(elementId, callBack){
      window.setTimeout(function(){
        var element = document.getElementById(elementId);
        if(element){
          callBack(elementId, element);
        }else{
          waitForElement(elementId, callBack);
        }
      },5000)
    };

    function saveScreenshot(canvas) {
        const fileName = &quot;image&quot;;
        const link = document.createElement(&quot;a&quot;);
        link.download = fileName + &quot;.png&quot;;
        console.log(canvas);
        canvas.toBlob(function (blob) {
            console.log(blob);
            document.getElementById(&apos;hdnBlob&apos;).value = blob;
        });
    };

    waitForElement(&quot;@Shared.mainChartId~&quot;,function(){
        html2canvas(document.getElementById(&quot;@Shared.html2CanvasElement~&quot;), {canvas: canvasExport, scale: 0.85}).then(function(canvas) {
        //document.body.appendChild(canvas);
        html2canvas(document.body, {
        allowTaint: true,
        useCORS: true
    }).then(saveScreenshot);
    });
    });"
                />
                <IncludeScriptFile
                    IncludedScriptFile="html2canvas.min.js"
                />
            </Division>
            <InputHidden
                ID="hdnBlob"
            />
        </SharedElement>
        <ideTestParams
            clickExport=""
        />
    </Report>

    With the SharedElement placed in my report definition, I'm able to grab a snapshot of divResults (my html2ChartElement) once Chart1 (my mainChartId) is loaded. It is still a little wonky as it doesn't truly take action once the Chart loads, it just adds 5 seconds once the page loads which I'm hoping will cover the time for the chart to finish rendering, so any assist on that point would be wonderful!! The other thing I've noticed is that if I give too much time here, the user could be hovering and get tooltip/hover-text in the PNG.

    Now that I have the divResults element as a PNG/blob, I need to find a way to pass the blob to a new report which will run when the user clicks export as PDF. Basically, the parent report has JS that I need to run to render including the client-side JS and the child report that I need to house the PNG/blob will be referenced in the parent's Target.Report element for Action.ExportPDF.

    1. How do I get the PNG/blob over to the child report?
    2. How do I get my waitForElement to actually run once Chart1 is fully rendered?

    0
  • Johnny Stevens

    Just to update everyone, I'm going to use Highcharts' getSVG API call to pull the SVG info into a new report. This should allow me to export the new report into PDF with the pre-configured SVG rendering of the chart intact within the export. I'll try to set up a sample of my reports once I have this work completed in case anyone else wants to export PDFs of charts with modifications (like exporting with some of the legend items inactivated).

    0

Please sign in to leave a comment.