2014-09-02 4 views
11

Я использую Highcharts в моем приложении (без подключения к Интернету)Экспорт Highcharts в PDF (не используя JavaScript и локальный сервер - без подключения к Интернету)

У меня есть несколько диаграмм на HTML-страницу, и я хочу, чтобы генерировать PDF-отчет, содержащий все диаграммы с этой страницы.

Как это сделать, не отправляя данные на любой сервер в Интернете?

Буду благодарен за любую помощь или любой пример, который вы можете предоставить. Заранее спасибо :)

ответ

26

Да, это возможно, но включает несколько разных библиотек для работы. Первая библиотека - jsPDF, которая позволяет создавать PDF-файлы в браузере. Второй - canvg, который позволяет рендеринг и синтаксический анализ SVG, бит, который действительно крут, хотя он может отображать svg на элемент canvas. Наконец, Highcharts export module, который позволит нам отправить SVG в canvg, чтобы превратиться в URL-адрес данных, который затем можно передать jsPDF, чтобы он превратился в ваш pdf-файл.

Вот пример http://fiddle.jshell.net/leighking2/dct9tfvn/ вы также можете увидеть исходные файлы, которые вам необходимо включить в свой проект.

Итак, чтобы начать highcharts, вы можете использовать canvg с его экспортом, чтобы сохранить диаграмму в виде png. потому что вы хотите, чтобы все iamges в PDF это было немного изменено для нашей цели, чтобы просто вернуть 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(/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)); 

Тогда для примера я создал экспорт на кнопку мыши. Это будет искать все элементы определенного класса (поэтому выберите один для добавления ко всем элементам диаграммы), а затем вызовите их функцию 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

+0

Спасибо за вашу помощь, но в этом растворе данные отправляются на сервер экспорта Highcharts. И я не хочу, чтобы это произошло, как я сказал в вопросе :)) – Leon

+0

Нет Я использовал только модуль экспорта, чтобы получить данные SVG, я смотрел вкладку сети и не отправлял никаких данных. – Quince

+0

Преобразование происходит в браузером, поэтому я отключил кнопку экспорта на каждом графике. – Quince

1

Вам нужно настроить свой собственный сервер ехпортируя, локально, как в article

0

Возможно, эта ссылка может вам помочь.

http://bit.ly/1IYJIyF

Постарайтесь см экспортирующего свойства (fallbackToExportServer лжи) и нужный файл, который необходимо включать (в автономном режиме-exporting.js).

Принимая во внимание экспорт всех сразу, часть, в настоящее время я тоже все еще пытаюсь. Будет обновляться здесь, если таковые имеются.

0

Этот вопрос немного стар, но я недавно работал над собой и имел некоторые проблемы с ним.

Я использовал библиотеку 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> 
0

Ниже приведен пример использования библиотеки 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")); 
    } 
} 

полный рабочий код: https://jsfiddle.net/dimitrisscript/f6sbdsps/

Смежные вопросы