2016-05-30 23 views
0

WebアプリケーションからPDFレポートを生成したい。 PDFには、グラフ(円グラフ、棒グラフ)、表、さまざまなフォントと色が含まれている必要があります。Webアプリケーションから設計されたPDFレポートを生成する

アプリケーションのサーバー側はJavaで、クライアント側はAngularJS(もちろんCSS3とHTML)です。

つの主要なオプション:

  • クライアント側がサーバーにいくつかのパラメータを渡します、そして、サーバは、Javaパッケージを使用して、PDFレポートを生成します。その後、レポートはダウンロードされたファイルとしてクライアントに送り返されます。
  • クライアントは、HTMLとCSSをPDFに変換するJSパッケージを使用してレポートを生成します。

Javaの世界では、例えば、hereのようなiTextとJFreeChartが見つかりました。ここで問題となっているのは、この例ではチャートのデザインが悪く見えることです。私が持っているスタイルガイド(CSSで簡単に行うことができるデザイン)によってデザインが変更できるかどうかはわかりません。

JSの世界では、hereのようなhtml2canvasとpdfMakeが見つかりました。ここで問題となるのは、HTMLからキャンバスへの変換からPDFへの変換がAngularアプリケーションでうまくいくかどうかはわかりません。そして、私はそれがsvgやcanvas要素のチャートのような複雑なDOM要素を変換するのかどうかはわかりません。

これらのパッケージに関するご経験がありますか?このタスク、クライアント、またはサーバーに推奨される他のパッケージを知っていますか?

+0

多分、キャンバスではなくPDFへの直接SVGをサポートするhttp://www.cloudformatter.com/CSS2Pdfを見てください。 –

+0

ありがとう@KevinBrown。クラウドベースのソリューションなので、私はこのソリューションを使用できません。 POSTリクエストを送信し、PDFを返します。私たちのアプリケーションは、インターネット接続なしでも(大企業のセキュリティ問題のために)動作する必要があるため、PDFを個別に作成するソリューションが必要です。 – Guy

答えて

0

私のソリューションを共有したい...私はクライアント側のソリューションを選択しました。

私はjsPDFを使い始めましたが、いくつか問題がありました。たとえば、私が望むスタイルでテーブルを変換するのは難しいです。

Iは、(pdfMake文書に画像としてキャンバスに追加することができる)、PDF生成のための複雑な設計されたコンポーネントのスクリーンショットを取るためhtml2canvaspdfMakeを選択し、キャンバスにd3jsチャート(SVGチャート)の変換のためcanvg

PDFに変換したい部分のHTMLルートのCSSクラスを取得する関数を作成しました(1ページアプリケーションであることを覚えておいてください)。また、HTMLノードのメタデータを取得しますそれらのCSSクラス)をPDFに追加する必要があります(どのタイプがノード - テーブル/テキスト/イメージ/ svgです)。

DOMトラバースでは、PDFに追加したい要素を歩き、その種類ごとに処理しました。コードの一部(タイプによってトラバースおよびスイッチケース):

$(htmlRootSelector).contents().each(function processNodes(index, element) { 
    var classMeta = getMetaByClass(element.className); 

    if (!classMeta) { 
     $(element).contents().each(processNodes); 
     return; 
    } 

    var pdfObj = {}; 
    pdfObj.width = classMeta.width || angular.undefined; 
    pdfObj.height = classMeta.height || angular.undefined; 
    pdfObj.style = classMeta.style || angular.undefined; 
    pdfObj.pageBreak = classMeta.pageBreak || angular.undefined; 

    switch (classMeta.type) { 
    case 'text': 
     pdfObj.text = element.innerText; 
     pdfDefinition.content.push(pdfObj); 
     break; 
    case 'table': 
     var tableArray = []; 
     var headerArray = []; 
     var headers = $(element).find('th'); 
     var rows = $(element).find('tr'); 
     $.each(headers, function (i, header) { 
     headerArray.push({text: header.innerHTML, style: classMeta.style + '-header'}); 
     }); 
     tableArray.push(headerArray); 

     $.each(rows, function (i, row) { 
     var rowArray = []; 
     var cells = $(row).find('td'); 

     if (cells.length) { 
      $.each(cells, function (j, cell) { 
      rowArray.push(i % 2 === 1 ? {text: cell.innerText, style: classMeta.style + '-odd-row'} : cell.innerText); 
      }); 

      tableArray.push(rowArray); 
     } 
     }); 

     pdfObj.table = { 
     widths: $.map(headers, function (d, i) { 
      return i === 0 ? 80 : '*'; 
     }), 
     body: tableArray 
     }; 
     pdfDefinition.content.push(pdfObj); 
     break; 
    case 'image': 
     html2CanvasCount++; 
     htmlToCanvas(element, pdfObj); 
     pdfDefinition.content.push(pdfObj); 
     break; 
    case 'svg': 
     svgToCanvas(element, pdfObj); 
     pdfDefinition.content.push(pdfObj); 
     break; 
    default: 
     break; 
    } 

    $(element).contents().each(processNodes); 
    }); 

これは一般的な解決策です。 誰かを助けてくれることを願っています。

関連する問題