将 Highcharts 导出为 PDF(使用 javascript 和本地服务器 - 没有互联网连接)
Posted
技术标签:
【中文标题】将 Highcharts 导出为 PDF(使用 javascript 和本地服务器 - 没有互联网连接)【英文标题】:Export Highcharts to PDF (using javascript and local server - no internet connection) 【发布时间】:2014-10-27 03:45:44 【问题描述】:我在我的应用程序中使用 Highcharts(没有任何互联网连接)
我在一个 html 页面上有多个图表,我想生成一个包含此页面中所有图表的 PDF 报告。
如何在不将数据发送到互联网上的任何服务器的情况下做到这一点?
我将感谢您提供的任何帮助或任何示例。 提前谢谢你:)
【问题讨论】:
【参考方案1】:是的,这是可能的,但需要几个不同的库才能开始工作。第一个库是jsPDF,它允许在浏览器中创建 PDF。第二个是canvg,它允许渲染和解析 SVG,虽然它可以将 svg 渲染到画布元素上,但它确实很酷。最后是Highcharts export module,它将允许我们将 svg 发送到 canvg 以转换为数据 URL,然后可以将其提供给 jsPDF 以转换为您的 pdf。
这是一个示例http://fiddle.jshell.net/leighking2/dct9tfvn/,您还可以在其中看到需要包含在项目中的源文件。
因此,highcharts 提供了一个使用 canvg 及其导出的示例,以将图表保存为 png。因为您想要 pdf 中的所有 iamges,所以为了我们的目的,我们对它进行了轻微更改,以仅返回数据 url
// create canvas function from highcharts example http://jsfiddle.net/highcharts/PDnmQ/
(function (H)
H.Chart.prototype.createCanvas = function (divId)
var svg = this.getSVG(),
width = parseInt(svg.match(//)[1]),
height = parseInt(svg.match(//)[1]),
canvas = document.createElement('canvas');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
if (canvas.getContext && canvas.getContext('2d'))
canvg(canvas, svg);
return canvas.toDataURL("image/jpeg");
else
alert("Your browser doesn't support this feature, please use a modern browser");
return false;
(Highcharts));
然后对于示例,我在按钮单击时设置了导出。这将查找某个类的所有元素(因此选择一个添加到所有图表元素中),然后调用它们的 highcharts.createCanvas 函数。
$('#export_all').click(function ()
var doc = new jsPDF();
// chart height defined here so each chart can be palced
// in a different position
var chartHeight = 80;
// All units are in the set measurement for the document
// This can be changed to "pt" (points), "mm" (Default), "cm", "in"
doc.setFontSize(40);
doc.text(35, 25, "My Exported Charts");
//loop through each chart
$('.myChart').each(function (index)
var imageData = $(this).highcharts().createCanvas();
// add image to doc, if you have lots of charts,
// you will need to check if you have gone bigger
// than a page and do doc.addPage() before adding
// another image.
/**
* addImage(imagedata, type, x, y, width, height)
*/
doc.addImage(imageData, 'JPEG', 45, (index * chartHeight) + 40, 120, chartHeight);
);
//save with name
doc.save('demo.pdf');
);
这里需要注意的是,如果您有很多图表,您需要处理将它们放置在新页面上的问题。 jsPDF 的文档看起来真的过时了(他们确实有一个很好的演示页面,虽然没有太多解释所有可能的选项),有一个 addPage() 函数,然后你可以玩宽度和高度,直到你找到一些东西有效。
最后一部分是使用一个额外的选项设置图表,以便在通常显示的每个图表上不显示导出按钮。
//charts
$('#chart1').highcharts(
navigation:
buttonOptions:
enabled: false
,
//this is just normal highcharts setup form here for two graphs see fiddle for full details
结果还不错,图表的质量给我留下了深刻的印象,因为我对此并没有期望太多,一些 pdf 位置和大小的播放看起来真的很好。
这是一个屏幕截图,显示了导出前后的网络请求,当导出时没有请求http://i.imgur.com/ppML6Gk.jpg
这里是 pdf 外观的示例http://i.imgur.com/6fQxLZf.png(查看实际 pdf 时看起来更好)
在本地https://github.com/leighquince/HighChartLocalExport 上试用的快速示例
【讨论】:
感谢您的帮助,但在此解决方案中,数据将发送到 Highcharts 导出服务器。正如我在问题中所说的那样,我不希望这种情况发生:)) 不,我只使用了导出模块来获取 SVG 数据,我在看网络选项卡,没有发送任何数据 转换都发生在浏览器中,这也是我关闭每个图表上的导出按钮的原因 @Leon 在问题中添加了网络请求的屏幕截图,以显示没有向高图表发送请求 你好 Quince,再次感谢,但我需要在本地服务器上完成。你能在本地服务器上运行这个例子,没有互联网连接吗?【参考方案2】:您需要在本地设置自己的导出服务器,例如 article
【讨论】:
【参考方案3】:这是一个使用库pdfmake的示例:
html:
<div id="chart_exchange" style="width: 450px; height: 400px; margin: 0 auto"></div>
<button id="export">export</button>
<canvas id="chart_exchange_canvas" style="display: none;"></canvas>
function drawInlineSVG(svgElement, canvas_id, callback)
var can = document.getElementById(canvas_id);
var ctx = can.getContext('2d');
var img = new Image();
img.setAttribute('src', 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgElement))));
img.onload = function()
ctx.drawImage(img, 0, 0);
callback(can.toDataURL("image/png"));
完整的工作代码: https://jsfiddle.net/dimitrisscript/f6sbdsps/
【讨论】:
它会在图表上导出文本呢? pdf里面有文字。 “你好世界”。 这是一个很好的解决方案。但是,我想知道,如果不使用 jQuery,这是否可能。【参考方案4】:也许这个链接可以帮助你。
http://bit.ly/1IYJIyF
尝试参考导出属性(fallbackToExportServer: false)和需要包含的必要文件(offline-exporting.js)。
而对于一次全部导出部分,目前我自己也在尝试。有的话会在这里更新。
【讨论】:
【参考方案5】:这个问题有点老了,但这是我最近自己研究的问题,遇到了一些麻烦。
我使用了 jsPDF 库:https://github.com/MrRio/jsPDF
我遇到的问题涉及 jsPDF 不支持高图表导出的 SVG 图像 + 图像模糊且质量低。
以下是我用来将两个图表合并到一个 pdf 文档中的解决方案:
function createPDF()
var doc = new jsPDF('p', 'pt', 'a4'); //Create pdf
if ($('#chart1').length > 0)
var chartSVG = $('#chart1').highcharts().getSVG();
var chartImg = new Image();
chartImg.onload = function ()
var w = 762;
var h = 600;
var chartCanvas = document.createElement('canvas');
chartCanvas.width = w * 2;
chartCanvas.height = h * 2;
chartCanvas.style.width = w + 'px';
chartCanvas.style.height = h + 'px';
var context = chartCanvas.getContext('2d');
chartCanvas.webkitImageSmoothingEnabled = true;
chartCanvas.mozImageSmoothingEnabled = true;
chartCanvas.imageSmoothingEnabled = true;
chartCanvas.imageSmoothingQuality = "high";
context.scale(2, 2);
chartCanvas.getContext('2d').drawImage(chartImg, 0, 0, 762, 600);
var chartImgData = chartCanvas.toDataURL("image/png");
doc.addImage(chartImgData, 'png', 40, 260, 250, 275);
if ($('#chart2').length > 0)
var chart2SVG = $('#chart2').highcharts().getSVG(),
chart2Img = new Image();
chart2Img.onload = function ()
var chart2Canvas = document.createElement('canvas');
chart2Canvas.width = w * 2;
chart2Canvas.height = h * 2;
chart2Canvas.style.width = w + 'px';
chart2Canvas.style.height = h + 'px';
var context = chart2Canvas.getContext('2d');
chart2Canvas.webkitImageSmoothingEnabled = true;
chart2Canvas.mozImageSmoothingEnabled = true;
chart2Canvas.imageSmoothingEnabled = true;
chart2Canvas.imageSmoothingQuality = "high";
context.scale(2, 2);
chart2Canvas.getContext('2d').drawImage(chart2Img, 0, 0, 762, 600);
var chart2ImgData = chart2Canvas.toDataURL("image/png");
doc.addImage(chart2ImgData, 'PNG', 300, 260, 250, 275);
doc.save('ChartReport.pdf');
chart2Img.src = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(chart2SVG)));
chartImg.src = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(chartSVG)));
要包含的脚本:
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js"></script>
【讨论】:
以上是关于将 Highcharts 导出为 PDF(使用 javascript 和本地服务器 - 没有互联网连接)的主要内容,如果未能解决你的问题,请参考以下文章
当highcharts导出png文件时,如何将moment.min.js的url设置为本地js文件