Export DIV contents to PNG
We have some client-side JavaScript that we want to include in a PDF Export, but Logi's ABCPDF has the option for client-side JS disabled. One alternative I'm pondering is that, when the user clicks the option to export the report to PDF, we grab a PNG of the chart and related labels/captions and generate a new Logi 'report' that just shows that PNG, downloading that report to the PDF. This would allow us to have the client-side JS run, captured, and presented in PDF.
We DO NOT want to enable Global Chart Export as this would not solve the problem of the related labels, no PDF header/footer/paging, etc.
Has anyone set up a Process Task and/or Report Definition to capture a screen or part of a screen as an image (PNG, JPG, etc.)? Are there some undocumented options or libraries that anyone has used to accomplish something like this?
-
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 "clickExport=1" 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 = "image";
const link = document.createElement("a");
link.download = fileName + ".png";
console.log(canvas);
canvas.toBlob(function (blob) {
console.log(blob);
document.getElementById('hdnBlob').value = blob;
});
};waitForElement("@Shared.mainChartId~",function(){
html2canvas(document.getElementById("@Shared.html2CanvasElement~"), {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 -
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.
Comments
2 comments