Exporter des graphiques en format PDF (en utilisant javascript et le serveur local - pas de connexion internet)

je suis en utilisant Highcharts dans mon application (sans connexion internet)

j'ai plusieurs graphiques sur une page html, et je veux générer un rapport PDF qui contient tous les graphiques de cette page.

Comment puis-je faire cela sans envoyer les données à n'importe quel serveur sur l'internet ?

je serai reconnaissant pour toute aide ou exemple, vous pouvez fournir. Merci d'avance :)

13
demandé sur Leon 2014-09-02 23:22:53

5 réponses

Oui c'est possible mais cela implique quelques bibliothèques différentes pour travailler. La première Bibliothèque est jsPDF qui permet la création de PDF dans le navigateur. La deuxième est canvg ce qui permet le rendu et l'analyse des SVG, le peu qui est vraiment cool c'est qu'il peut rendre un svg on à l'élément canvas. Enfin est Highcharts module d'exportation ce qui nous permettra d'envoyer le svg au canvg pour qu'il se transforme en une URL de données qui peut ensuite être donnée à jsPDF pour se transformer en votre pdf.

Voici un exemple http://fiddle.jshell.net/leighking2/dct9tfvn/ vous pouvez également voir dans il fichiers source, vous devez inclure dans votre projet.

donc pour démarrer highcharts fournit un exemple d'utilisation de canvg avec son exportation pour enregistrer un graphique en png. parce que vous voulez tous les iamges dans un pdf cela a été légèrement modifié pour notre but de simplement retourner l'url des données

// 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(/width="([0-9]+)"/)[1]),
            height = parseInt(svg.match(/height="([0-9]+)"/)[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));

puis pour l'exemple i ont mis en place l'exportation sur un clic de bouton. Cela va chercher tous les éléments d'une certaine classe (donc choisissez un à ajouter à tous vos éléments de carte) et ensuite appeler leurs highcharts.fonction 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');
});

important de noter ici que si vous avez beaucoup de graphiques, vous aurez besoin de gérer leur placement sur une nouvelle page. La documentation pour jsPDF semble vraiment périmée (ils ont une bonne page demos mais pas beaucoup pour expliquer toutes les options possibles), il y a une page Add() fonction et ensuite vous pouvez juste jouer avec les largeurs et les hauteurs jusqu'à ce que vous trouvez quelque chose qui fonctionne.

la dernière partie est juste de configuration des graphiques avec une option pour ne pas afficher le bouton exporter sur chaque graphique qui serait normalement l'affichage.

//charts
$('#chart1').highcharts({
    navigation: {
            buttonOptions: {
                enabled: false
            }
        },

//this is just normal highcharts setup form here for two graphs see fiddle for full details

le résultat n'est pas trop mauvais je suis impressionné par la qualité des graphiques car je n'attendais pas beaucoup de cela, avec un peu de jeu des positions et des tailles pdf pourrait sembler vraiment bon.

voici un écran plan montrant les requêtes réseau faites avant et après l'exportation, quand l'exportation est faite aucune requête est faite http://i.imgur.com/ppML6Gk.jpg

voici un exemple de ce que le pdf ressemble à http://i.imgur.com/6fQxLZf.png (regarde mieux lorsque la vue réelle pdf)

exemple rapide à essayer sur local https://github.com/leighquince/HighChartLocalExport

30
répondu Quince 2014-09-03 09:12:48

Vous devez configurer votre propre serveur d'exportation, localement comme à l' article

1
répondu Sebastian Bochan 2014-09-03 09:06:30

Voici un exemple d'utilisation de la bibliothèque 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" width="450" height="400" style="display: none;"></canvas>

javascript:

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"));
  }
}

code de travail complet: https://jsfiddle.net/dimitrisscript/f6sbdsps/

1
répondu Dimitris Siakavelis 2017-04-06 12:24:19

Peut-être que ce lien pourra vous aider.

http://bit.ly/1IYJIyF

essayez de faire référence aux propriétés d'exportation (fallbackToExportServer: false) et au fichier nécessaire qui doit être include (offline-exporting).js).

alors que pour l'export tout d'un coup partie, actuellement je suis moi-même toujours essayer. Sera mise à jour ici.

0
répondu William Kheng 2015-08-10 07:34:14

cette question est un peu vieille mais c'était quelque chose sur lequel je travaillais moi-même récemment et j'ai eu quelques problèmes avec elle.

https://github.com/MrRio/jsPDF

questions que j'ai rencontré impliqué jsPDF ne supportant pas L'image SVG exportée par le graphique haut + images étant flou et de faible qualité.

ci-dessous est la solution que j'ai utilisé pour obtenir deux graphiques dans un document 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)));
}
}

scripts pour inclure:

 <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>
0
répondu Ryan Gavin 2017-04-04 15:08:18