huruyosi’s blog

プログラミングとかインフラとかのメモです。

JFreeChartで作成したグラフをSVGにしてJasperReportsに反映する

目的

JasperReportsが提供するグラフの機能では、データ構造の関係で目的のグラフを作成できないと判断した。JFreeChartを直接利用してグラフを作成し、JasperReportsの Image expression に反映する方法です。

JasperReportsの出力物はpdfファイルです。

環境

  • JasperReports 5.1
  • JFreeChart 1.0.12
  • batik 1.7

JasperReports 5.1が基準です。JFreeChart とbatik は JasperReports に同梱されているされているバージョンです。

処理の概要

  1. JFreeChartでグラフを定義し、org.jfree.chart.JFreeChart クラスのインスタンスを準備します。
  2. org.jfree.chart.JFreeChartのdrawメソッドbatikのSVGGraphics2Dに描画します。
  3. SVGGraphics2DをSVG形式に書き出します。
  4. 書き出したSVG形式のデータを JasperReports にパラメータとして渡して、pdfファイルを生成します。

処理1. org.jfree.chart.JFreeChart を準備する

~ 色々省略 ~

JFreeChart chart = ChartFactory.createXYLineChart("", "時", "人数", data, PlotOrientation.VERTICAL, true, true, false);

  ここで取得したchart を使ってグラフを出力します。

処理2. SVGGraphics2Dに描画する

JasperReports のnet.sf.jasperreports.charts.util.SvgChartRendererFactory クラスのgetRenderableメソッドのほぼコピーです。

Rectangle2D rectangle = new Rectangle(width, height);
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
Document document = domImpl.createDocument(null, "svg", null);
SVGGraphics2D grx = new SVGGraphics2D(document);

grx.setSVGCanvasSize(rectangle.getBounds().getSize());
chart.draw(grx, rectangle);

処理3. SVG形式に書き出す

StringWriter swriter = new StringWriter();
grx.stream(swriter);

String svgGraph = swriter.getBuffer().toString();

 svgGraphに書き出した結果が入っています


処理4.  pdf を出力する

 SVGを出力するために image を設けます。処理3でSVGが書き出された値は パラメータ svgGraph に入れておきます。

<image>
<reportElement mode="Transparent" x="70" y="0" width="690" height="180" forecolor="#000000" uuid="XXXXXXXXXXXXX"/>
<imageExpression><![CDATA[net.sf.jasperreports.renderers.BatikRenderer.getInstanceFromText($P{svgGraph})]]></imageExpression>
</image>

あとは、 JRPdfExporter で pdfを書き出せば完了です。

JFreeSVGは使いません。


JfreeChart + svg で検索すると、 JFreeSVGが出てきます。 batikとJFreeSVGを比較すると、軽くて依存するjar が少ないから楽だよ。(意訳)の記事もありますが、 JaspreReport 5.1では batikを利用しているので、jarが増えるのを避けるためにも、 batikにしました。