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 に同梱されているされているバージョンです。
処理の概要
- JFreeChartでグラフを定義し、org.jfree.chart.JFreeChart クラスのインスタンスを準備します。
- org.jfree.chart.JFreeChartのdrawメソッドで batikのSVGGraphics2Dに描画します。
- SVGGraphics2DをSVG形式に書き出します。
- 書き出した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にしました。