2014-09-02 7 views

risposta

26

Sì, questo è possibile ma richiede alcune librerie diverse per funzionare. La prima libreria è jsPDF che consente la creazione di PDF nel browser. Il secondo è canvg che consente il rendering e l'analisi di SVG, il bit che è davvero interessante anche se è in grado di eseguire il rendering di un elemento di svg sull'elemento canvas. Infine, è Highcharts export module che ci permetterà di inviare lo svg al canvg per trasformarlo in un URL di dati che può essere poi dato a jsPDF per trasformarlo nel tuo pdf.

Ecco un esempio http://fiddle.jshell.net/leighking2/dct9tfvn/ è anche possibile vedere in là i file di origine che è necessario includere nel progetto.

Quindi, per avviare highcharts viene fornito un esempio di utilizzo di canvg con la sua esportazione per salvare un grafico come png. perché si desidera che tutti i iamges in un PDF Questo è stato leggermente alterato per il nostro scopo di restituire solo l'url dati

// 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)); 

Quindi per l'esempio che ho creato l'esportazione su un pulsante di scatto. Questo cercherà tutti gli elementi di una determinata classe (quindi sceglierne uno da aggiungere a tutti gli elementi del grafico) e quindi chiama la funzione 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'); 
}); 

importante da notare qui che se hai un sacco di grafici è necessario gestirli immissione in una nuova pagina. La documentazione di jsPDF sembra davvero superata (hanno una buona pagina di demo anche se non molto per spiegare tutte le opzioni possibili), c'è una funzione addPage() e quindi puoi giocare con larghezze e altezze fino a trovare qualcosa che lavori.

l'ultima parte consiste semplicemente nell'impostare i grafici con un'opzione aggiuntiva per non visualizzare il pulsante di esportazione su ciascun grafico che normalmente verrà visualizzato.

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

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

Il risultato non è male io sono impressionato con la qualità dei grafici, come non mi aspettavo molto da questo, con un po 'di gioco delle posizioni pdf e le dimensioni potrebbe apparire davvero buono.

Ecco uno screenshot che mostra le richieste di rete fatte prima e dopo l'esportazione, quando è fatta nessuna richiesta sono realizzati http://i.imgur.com/ppML6Gk.jpg

qui l'esportazione è un esempio di quello che sembra la pdf come http://i.imgur.com/6fQxLZf.png (guarda meglio quando vista in formato pdf effettivo)

esempio veloce per essere giudicato sulla locale https://github.com/leighquince/HighChartLocalExport

+0

Grazie per il vostro aiuto, ma in questa soluzione i dati vengono inviati al server di esportazione Highcharts. E non voglio che ciò accada come ho detto nella domanda :)) – Leon

+0

No Ho solo usato il modulo di esportazione per ottenere i dati SVG, stavo guardando la scheda di rete e non sono stati inviati dati – Quince

+0

La conversione avviene tutto in il browser, questo è anche il motivo per cui ho disattivato il pulsante di esportazione su ciascun grafico – Quince

1

È necessario configurare il proprio server di esportazione, a livello locale come nel article

0

Forse questo link può aiutarti.

http://bit.ly/1IYJIyF

Prova si riferiscono alle proprietà esportatori (fallbackToExportServer: false) e il file necessari che devono essere includere (offline-exporting.js).

Considerando che per l'esportazione tutto in una volta parte, attualmente anch'io sto ancora provando. Si aggiornerà qui se presente.

0

Questa domanda è un po 'vecchia ma era qualcosa che stavo lavorando su di me di recente e ha avuto qualche problema con esso.

ho usato la biblioteca jsPDF: https://github.com/MrRio/jsPDF

problemi che ho incontrato jsPDF coinvolti non sostenere l'immagine SVG esportato dalla elevata grafico + immagini essendo qualità sfocate e basso.

Di seguito è la soluzione che ho usato per ottenere due grafici in un unico documento 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 per includere:

<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

Ecco un esempio utilizzando la libreria 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")); 
    } 
} 

codice di lavoro completo: https://jsfiddle.net/dimitrisscript/f6sbdsps/

Problemi correlati