У меня есть страница html с несколькими iframe, некоторые из которых содержат графики старших диаграмм (svg), а некоторые содержат HTML таблицы. Мне нужно экспортировать эту страницу с графиками и таблицей html div. Я смог получить элементы svg изнутри iframes и экспортировать их в pdf, используя библиотеку svg2pdf. PDF идет очень хорошо. Но я не могу найти какой-либо способ извлечь таблицу и экспортировать ее в pdf вообще.
Я пытался преобразовать ее в base64, а затем добавить, но svg2pdf выдает мне эту ошибку:
svg2pdf. js: 3140 svg2pdf js: Изображения со ссылкой на внешний ресурс не поддерживаются! ("undefined")
Я также пытался преобразовать hmtl в svg, но обнаружил, что это бесполезно. .
Как мне к этому подойти?
<html>
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title></title>
<script data-require="jquery" data-semver="3.1.1"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-3d.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/offline-exporting.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/canvg/1.5/canvg.js"
integrity="sha256-gS9x7L+zPeuIJQi5Ozx6nkmnAKegHZGdx/Zy/jOs/Ao=" crossorigin="anonymous"></script>
</head>
<body>
<header class="header" id="canvas_div_pdf">
<div class="header-toolbar">
<form role="form" method="get" action="" style="width: 100%">
<div class="row">
<div style="padding-left: 2%; padding-top: 0.5%; padding-bottom: 0.5%; width: 98%; border-bottom: 1px solid #cccccc">
<div style="width:30%; float: left; font-size: 2.2rem; ">Test Board ( Global
)
</div>
<div style="width:45%; float: left">
<div style="float:left;border:solid 1pt black;">
<button id="export-pdf" onclick="return false">Export to PDF</button>
<input id="btn-Preview-Image" type="button" value="Preview"/>
<a id="btn-Convert-Html2Image" href="#">Download</a>
<br/>
<h3>Preview :</h3>
<div id="previewImage">
</div>
</div>
<a id="pdf-download">Creating PDF...</a>
<div style="float: right">
<label>Date Range</label>
<input type="text" class="form-control datepicker hasDatepicker" name="boardStartDate"
id="inputstartdate" placeholder="Start Date" value="20-12-2020">
<input type="text" class="form-control datepicker hasDatepicker" name="boardEndDate"
id="inputenddate" placeholder="End Date" value="20-12-2020">
<button type="submit" class="btn btn--small btn--icon btn--success"><span
class="icon icon-check"></span></button>
</div>
</div>
<div style="width:25%; float: right">
<div style="width:15%; min-width:32px; float: right">
<a class="btn btn--small btn--icon btn--primary" onclick="return showAddAnotherPopup(this);"
title="Dashboard Settings" target="popup" href="/admin/pivot_table/genericboard/1/">
<span class="icon-cog"></span>
</a>
</div>
<div style="width:15%; min-width:32px; float: right">
<a class="btn btn--small btn--icon btn--primary" onclick="updateBoardDefault()"
title="Set this dashboard as default" target="_blank">
<span class="icon-check-square-o"></span>
</a>
</div>
<div style="width:15%; min-width:32px; float: right">
<a class="btn btn--small btn--icon btn--primary" id="editBoard" title="Edit Panels on Board"
target="_blank">
<span class="icon-pencil"></span>
</a>
</div>
<div style="width:15%; min-width:32px; float: right">
<a class="btn btn--small btn--icon btn--primary" onclick="exportBoard()"
title="Export board to Excel">
<span class="icon-file-excel-o"></span>
</a>
</div>
<!-- <div style="width:15%; min-width:32px; float: right">-->
<!-- <button class="btn btn--small btn--icon btn--primary" id="export-pdf" onclick="return false" title="Export board to PDF">-->
<!-- <span class="icon-file-pdf-o"></span>-->
<!-- </button>-->
<!-- </div>-->
<div style="width:15%; min-width:32px; float: right;border: 1px solid black">
<button class="btn btn--small btn--icon btn--primary" id="export-div" onclick="return false"
title="Export board to PDF">
<span class="icon-file-pdf-o">download divs</span>
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</header>
<div>
<span>
<h4 id="graph1title">Graph one title</h4>
<iframe id="ifrm1" src="chart.html" width="250" height="250"></iframe>
</span>
<span>
<h4 id="graph2title">Graph two title</h4>
<iframe id="ifrm2" src="chart2.html" width="250" height="250"></iframe>
</span>
<span>
<h4>Table two title</h4>
<iframe id="ifrm3" src="table.html" width="500" height="300"></iframe>
</span>
</div>
<div id="buttonrow">
<button id="set-charts">Set Charts</button>
<button id="export-png">Export to PNG</button>
<button id="export-pdf">Export to PDF</button>
</div>
<script>
$(function() {
var element = $("#ifrm3"); // global variable
var getCanvas; // global variable
var imageData;
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
var imageData = getCanvas.toDataURL("image/png");
console.log("html div",imageData);
// Now browser starts downloading it instead of just showing it
var newData = imageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
}
});
});
$("#btn-Convert-Html2Image").on('click', function () {
var imageData = getCanvas.toDataURL("image/png");
console.log("html div",imageData);
// Now browser starts downloading it instead of just showing it
var newData = imageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
});
var ifrmChart = undefined;
var chartArray = [];
Highcharts.getSVG = function(charts) {
var svgArr = [],
top = 0,
line = false,
count = 0,
width = 0;
graphCount = charts.length;
// console.log(graphCount);
Highcharts.each(charts, function(chartArray,tableObject) {
console.log("@137",tableObject);
chart = chartArray.chart;
var tableSVG;
var xpos = chartArray.xPos;
var ypos = chartArray.yPos;
//console.log('typeof' + typeof(xpos));
//console.log(xpos,ypos);
var svg = chart.getSVG(),
// Get width/height of SVG for export
svgWidth = +svg.match(
/^<svg[^>]*\swidth\s*=\s*\"?(\d+)\"?[^>]*>/
)[1],
svgHeight = +svg.match(
/^<svg[^>]*height\s*=\s*\"?(\d+)\"?[^>]*>/
)[1];
svg = svg.replace('<svg', '<g><path style="padding: 20px"></path></g><g style="padding: 20px" transform="translate(' + ypos + ',' + xpos + ')" ');
svg = svg.replace('</svg>', '</g>');
var iframe = $('#ifrm3'); // or some other selector to get the iframe
var temp = $('#tableContainer', iframe.contents());
// html2canvas(tableObject).then(canvas => {
// tableSVG = canvas;
// console.log(tableSVG);
// });
svg = svg + '<text x="' + $(document).width()/2 + ' " text-anchor="middle" class="highcharts-title" style="color:#333333;font-size:24px;font-family:Arial;fill:#333333;;border:0px none rgb(51, 51, 51);border-block-end:0px none rgb(51, 51, 51);border-block-end-color:rgb(51, 51, 51);border-block-start:0px none rgb(51, 51, 51);border-block-start-color:rgb(51, 51, 51);border-bottom:0px none rgb(51, 51, 51);border-bottom-color:rgb(51, 51, 51);border-color:rgb(51, 51, 51);border-inline-end:0px none rgb(51, 51, 51);border-inline-end-color:rgb(51, 51, 51);border-inline-start:0px none rgb(51, 51, 51);border-inline-start-color:rgb(51, 51, 51);border-left:0px none rgb(51, 51, 51);border-left-color:rgb(51, 51, 51);border-right:0px none rgb(51, 51, 51);border-right-color:rgb(51, 51, 51);border-top:0px none rgb(51, 51, 51);border-top-color:rgb(51, 51, 51);caret-color:rgb(51, 51, 51);color:rgb(51, 51, 51);column-rule:0px none rgb(51, 51, 51);column-rule-color:rgb(51, 51, 51);font-family:Arial;outline:rgb(51, 51, 51) none 0px;outline-color:rgb(51, 51, 51);text-decoration:none solid rgb(51, 51, 51);text-decoration-color:rgb(51, 51, 51);webkit-border-after:0px none rgb(51, 51, 51);webkit-border-after-color:rgb(51, 51, 51);webkit-border-before:0px none rgb(51, 51, 51);webkit-border-before-color:rgb(51, 51, 51);webkit-border-end:0px none rgb(51, 51, 51);webkit-border-end-color:rgb(51, 51, 51);webkit-border-start:0px none rgb(51, 51, 51);webkit-border-start-color:rgb(51, 51, 51);webkit-column-rule:0px none rgb(51, 51, 51);webkit-column-rule-color:rgb(51, 51, 51);webkit-perspective-origin:113px 0px;webkit-text-emphasis-color:rgb(51, 51, 51);webkit-text-fill-color:rgb(51, 51, 51);webkit-text-stroke-color:rgb(51, 51, 51);" y="19" fill="rgb(51, 51, 51)"><tspan>Board Title Report</tspan></text>' + tableSVG;
svg = svg + '<image width="500" height="300" xlink:href="' + imageData + '">'
//replace 'Column charts' with chart title element text
svgArr.push(svg);
});
return "<svg height='" + $(document).height() + "' width='" + $(document).width() + "' version='1.1' xmlns='http://www.w3.org/2000/svg'>" +
svgArr.join('') + '</svg>';
};
Highcharts.exportCharts = function(charts, options) {
//Highcharts.setOptions({ });
// Merge the options
options = Highcharts.merge(Highcharts.getOptions().exporting, options);
svgContent = Highcharts.getSVG(charts);
console.log(svgContent);
console.log($(svgContent));
// Post to export server
// Highcharts.post(options.url, {
// filename: options.filename || 'chart',
// type: options.type,
// width: options.width,
// svg: Highcharts.getSVG(charts),
// });
var svgString = svgContent;
var htmlObject = document.createElement('div');
htmlObject.setAttribute("id", "svgexport");
htmlObject.innerHTML = svgString;
console.log(htmlObject);
// htmlObject.getElementById("myDiv").style.marginTop = something;
var svg = htmlObject.querySelector('svg'),
pdf = new jsPDF('p', 'pt', [$(document).height(), $(document).width()]);
setTimeout(function() {
svg2pdf(svg, pdf, {
removeInvalid: true,
scale: 72 / 96, // this is the ratio of px to pt units
});
var data = pdf.output('datauristring');
var dl = document.getElementById('pdf-download');
dl.innerHTML = 'Download PDF';
dl.href = data;
dl.download = 'mychart.pdf';
}, 1000);
};
$('#export-png').click(function() {
Highcharts.exportCharts(chartArray);
});
$('#export-pdf').click(function() {
chartArray = [];
tableArray = [];
$("iframe").each(function(index) {
console.log(index + ": " + $(this).attr('id'));
var iFrameId = "#" + $(this).attr('id');
if($(iFrameId)[0].contentWindow.getChart()){
var chartObj = $(iFrameId)[0].contentWindow.getChart();
var xPosition = $(iFrameId).parent().offset().top; // added some arbitrary padding
var yPosition = $(iFrameId).parent().offset().left;
//$("div #ifrm1div > iframe").offset()
//var xPosition = $("#ifrm"+index+"div > iframe").offset().top;
//var yPosition = $("#ifrm"+index+"div > iframe").offset().left;
console.log("x " + xPosition + "y " + yPosition);
//console.log(xPosition + "ypos "+ yPosition);
var divChartObj = {
xPos: xPosition,
yPos: yPosition,
chart: chartObj
};
console.log(divChartObj,"@328");
chartArray.push(divChartObj);
}
else
{
var tableObj = $('#tableContainer', $(iFrameId).contents()).html();
var xPosition = $(iFrameId).parent().offset().top; // added some arbitrary padding
var yPosition = $(iFrameId).parent().offset().left;
console.log("x " + xPosition + "y " + yPosition);
var divTableObj = {
xPos: xPosition,
yPos: yPosition,
chart: tableObj
};
tableArray.push(divTableObj);
var tableObject = $(divTableObj.chart);
console.log($(divTableObj.chart),"@272");
}
});
Highcharts.exportCharts(chartArray, {
type: 'application/pdf'
});
});
});
</script>
<script src="https://rawgit.com/yWorks/jsPDF/master/dist/jspdf.debug.js"></script>
<script src="https://rawgit.com/yWorks/svg2pdf.js/master/dist/svg2pdf.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://files.codepedia.info/files/uploads/iScripts/html2canvas.js"></script>
<script>
// $(document).ready(function(){
// var element = $("#ifrm3"); // global variable
// var getCanvas; // global variable
// $("#btn-Preview-Image").on('click', function () {
// html2canvas(element, {
// onrendered: function (canvas) {
// $("#previewImage").append(canvas);
// getCanvas = canvas;
// }
// });
// });
// $("#btn-Convert-Html2Image").on('click', function () {
// var imgageData = getCanvas.toDataURL("image/png");
// // Now browser starts downloading it instead of just showing it
// var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
// $("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
// });
// });
</script>
<!-- <script src="https://code.jquery.com/jquery-1.12.4.js"></script> -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script> -->
<!-- <script>
$(function() {
var ifrmChart = undefined;
var chartArray = [];
Highcharts.getSVG = function(charts) {
var svgArr = [],
top = 0,
line = false,
count = 0,
width = 0;
graphCount = charts.length;
// console.log(graphCount);
Highcharts.each(charts, function(chartArray) {
chart = chartArray.chart;
var xpos = chartArray.xPos;
var ypos = chartArray.yPos;
//console.log('typeof' + typeof(xpos));
//console.log(xpos,ypos);
var svg = chart.getSVG(),
// Get width/height of SVG for export
svgWidth = +svg.match(
/^<svg[^>]*\swidth\s*=\s*\"?(\d+)\"?[^>]*>/
)[1],
svgHeight = +svg.match(
/^<svg[^>]*height\s*=\s*\"?(\d+)\"?[^>]*>/
)[1];
svg = svg.replace('<svg', '<g><path style="padding: 20px"></path></g><g style="padding: 20px" transform="translate(' + ypos + ',' + xpos + ')" ');
svg = svg.replace('</svg>', '</g>');
svgArr.push(svg);
});
// return '<svg style="padding:20px; display:inline-block;" height="' + top + '" width="' + width +
// '" version="1.1" xmlns="http://www.w3.org/2000/svg">' +
// svgArr.join('') + '</svg>';
return "<svg height='" + $(document).height() + "' width='" + $(document).width() + "' version='1.1' xmlns='http://www.w3.org/2000/svg'>" +
svgArr.join('') + '</svg>';
};
Highcharts.exportCharts = function(charts, options) {
//Highcharts.setOptions({ });
// Merge the options
options = Highcharts.merge(Highcharts.getOptions().exporting, options);
svgContent = Highcharts.getSVG(charts);
console.log(svgContent);
console.log($(svgContent));
// Post to export server
// Highcharts.post(options.url, {
// filename: options.filename || 'chart',
// type: options.type,
// width: options.width,
// svg: Highcharts.getSVG(charts),
// });
var svgString = svgContent;
var htmlObject = document.createElement('div');
htmlObject.setAttribute("id", "svgexport");
htmlObject.innerHTML = svgString;
console.log(htmlObject);
// htmlObject.getElementById("myDiv").style.marginTop = something;
var svg = htmlObject.querySelector('svg'),
pdf = new jsPDF('p', 'pt', [$(document).height(), $(document).width()]);
setTimeout(function() {
svg2pdf(svg, pdf, {
removeInvalid: true,
scale: 72 / 96, // this is the ratio of px to pt units
});
var data = pdf.output('datauristring');
var dl = document.getElementById('pdf-download');
dl.innerHTML = 'Download PDF';
dl.href = data;
dl.download = 'mychart.pdf';
}, 1000);
};
$('#export-png').click(function() {
Highcharts.exportCharts(chartArray);
});
$('#export-pdf').click(function() {
chartArray = [];
<!-- console.log("Frame1 Chart: "); -->
<!-- console.log($('#ifrm1')[0].contentWindow.getChart()); -->
<!-- chartArray.push($('#ifrm1')[0].contentWindow.getChart()); -->
<!-- console.log("Frame2 Chart: "); -->
<!-- console.log($('#ifrm2')[0].contentWindow.getChart()); -->
<!-- chartArray.push($('#ifrm2')[0].contentWindow.getChart()); -->
<!-- console.log(chartArray.length); -->
<!-- console.log($('#ifrm3')[0].contentWindow.getChart()); -->
<!-- chartArray.push($('#ifrm3')[0].contentWindow.getChart()); -->
<!-- console.log($('#ifrm4')[0].contentWindow.getChart()); -->
<!-- chartArray.push($('#ifrm4')[0].contentWindow.getChart()); -->
<!-- console.log($('#ifrm5')[0].contentWindow.getChart()); -->
<!-- chartArray.push($('#ifrm5')[0].contentWindow.getChart()); -->
<!-- $("iframe").each(function(index) {
console.log(index + ": " + $(this).attr('id'));
var iFrameId = "#" + $(this).attr('id');
console.log(iFrameId);
var chartObj = $(iFrameId)[0].contentWindow.getChart();
var xPosition = $(iFrameId).parent().offset().top; // added some arbitrary padding
var yPosition = $(iFrameId).parent().offset().left;
//$("div #ifrm1div > iframe").offset()
//var xPosition = $("#ifrm"+index+"div > iframe").offset().top;
//var yPosition = $("#ifrm"+index+"div > iframe").offset().left;
console.log("x " + xPosition + "y " + yPosition);
//console.log(xPosition + "ypos "+ yPosition);
var divChartObj = {
xPos: xPosition,
yPos: yPosition,
chart: chartObj
};
console.log(divChartObj,"@328");
getPDF(divChartObj);
chartArray.push(divChartObj);
});
Highcharts.exportCharts(chartArray, {
type: 'application/pdf'
});
});
});
function getPDF(divChartObj) {
var HTML_Width = $(".canvas_div_pdf").width();
var HTML_Height = $(".canvas_div_pdf").height();
var top_left_margin = 15;
var PDF_Width = HTML_Width + (top_left_margin * 2);
var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
var canvas_image_width = HTML_Width;
var canvas_image_height = HTML_Height;
var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;
html2canvas($(".canvas_div_pdf")[0], {
allowTaint: true
}).then(function (canvas) {
canvas.getContext('2d');
console.log(canvas.height + " " + canvas.width);
var imgData = canvas.toDataURL("image/jpeg", 1.0);
// var graphimgData = new XMLSerializer().serializeToString(svgContent);
var encodedData = window.btoa(graphimgData);
console.log("@520 encodedData",encodedData);
var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
// pdf.addSVG(svgContent, 0,0, 1000, 1000);
// pdf.addImage(divChartObj, 'svgContent', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
console.log("svgContent is", svgContent);
// var img = canvas.toDataURL("image/png");
// var doc = new jsPDF('l', 'mm', [50, 120]);
// pdf.addImage(img, 'PNG', 0, 0, 120, 50);
var htmlObject = document.createElement('div');
htmlObject.setAttribute("id", "svgexport");
htmlObject.innerHTML = svgContent;
var canvas = document.createElement('canvas');
canvg(canvas, svgContent);
var graphimgData = canvas.toDataURL('image/png');
console.log("@533 graphimgData",graphimgData)
pdf.addImage(graphimgData, 'PNG', 10, 10, 25, 25);
<!-- var svgContentForExport = new XMLSerializer().serializeToString(htmlObject);-->
<!-- // pdf.addSVG(divChartObj, 140, 140, 1400, 1400);
console.log("svgContent is ", svgContent);
console.log("divChartObj is ", divChartObj);
console.log("pdf is",pdf);
<!-- addSvgAsImage(svgContentForExport, 0, 0, 1000, 1000, NONE, 0)-->
<!-- for (var i = 1; i <= totalPDFPages; i++) {
pdf.addPage(PDF_Width, PDF_Height);
pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height);
pdf.addSVG(svgContent, 140, 140, 1400, 1400);
}
pdf.save("HTML-Document.pdf");
}); -- -->
<!-- };
$('#export-div').click(function () {
getPDF();
}); -->
<!-- </script> -->
</body>
</html>
Как вы можете видеть, я использую функцию highcharts getsvg для получения кода svg изнутри фреймов. 'Tablearray' содержит код для таблицы, находящейся внутри iframe. Я также могу экспортировать PDF.