Eclipse BIRTを使ってみる (6) - IReportEventHandler -

2013-04-26T00:00:00+00:00 Eclipse BIRT Java

org.eclipse.birt.report.engine.api.script.eventhandler.IReportEventHandlerっていうのを使うと、ラベルを動的に変えちゃったり出来る模様

import java.util.Map;
import java.util.logging.Logger;

import org.eclipse.birt.report.engine.api.script.IReportContext;
import org.eclipse.birt.report.engine.api.script.ScriptException;
import org.eclipse.birt.report.engine.api.script.element.IReportDesign;
import org.eclipse.birt.report.engine.api.script.eventhandler.IReportEventHandler;
import org.eclipse.birt.report.engine.api.script.instance.IPageInstance;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;


public class SampleLabelEventAdapter implements IReportEventHandler {

    private static final Logger logger = Logger.getLogger(SampleLabelEventAdapter.class.getName());
    private static final String CONTEXT_KEY = "test";

    @Override
    @SuppressWarnings("unchecked")
    public void initialize(IReportContext context) throws ScriptException {
        logger.info("initialize");

        // 実行クライアント側から設定したAppContextなMapを取得してパラメータを取る
        Map<String, Object> appContext = context.getAppContext();

        if (appContext.containsKey(CONTEXT_KEY)) {
            logger.info("initialize: " + appContext.get(CONTEXT_KEY));
        }
    }

    @Override
    public void onPrepare(IReportContext context) throws ScriptException {
        logger.info("onPrepare");

        DesignElementHandle label = context.getDesignHandle().findElement("label1");

        try {
            label.setProperty("text", "hoge");
        } catch (SemanticException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void beforeFactory(IReportDesign design, IReportContext context) throws ScriptException {
        logger.info("beforeFactory");
    }

    @Override
    public void beforeRender(IReportContext context) throws ScriptException {
        logger.info("beforeRender");
    }

    @Override
    public void onPageStart(IPageInstance page, IReportContext context) throws ScriptException {
        logger.info("onPageStart");
    }

    @Override
    public void onPageEnd(IPageInstance page, IReportContext context) throws ScriptException {
        logger.info("onPageEnd");
    }

    @Override
    public void afterFactory(IReportContext context) throws ScriptException {
        logger.info("afterFactory");
    }

    @Override
    public void afterRender(IReportContext context) throws ScriptException {
        logger.info("afterRender");
    }
}

でこれどうやって使うのっていうのを説明すると

ってな感じで設定するか、rptdesignファイルに

<?xml version="1.0" encoding="UTF-8"?>
<report>
    <property name="eventHandlerClass">SampleLabelEventAdapter</property>

な感じでレポートプロパティをして設定すれば良い模様(ソースでそうなってるのを見ただけなのでEclipse上で設定しなくても出来るかは不明)

でinitializeメソッド上でやってるAppContextな件に関しては実行クライアント上から

import java.util.Map;

import org.eclipse.birt.report.engine.api.EXCELRenderOption;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.engine.api.ReportEngine;

public class Client {
    @SuppressWarnings("unchecked")
    public static void main(String[] args){
        EngineConfig config = new EngineConfig();

        Map<String, Object> appContext = config.getAppContext();
        appContext.put("test", "hoge fuga foobar");

        ReportEngine engine = new ReportEngine(config);
        IRunAndRenderTask task = null;

        try {
            IReportRunnable design = engine.openReportDesign(
                ClassLoader.getSystemResourceAsStream("sample.rptdesign")
            );

            task = engine.createRunAndRenderTask(design);

            EXCELRenderOption options = new EXCELRenderOption();
            options.setOutputFormat("xls");
            options.setEmitterID("org.eclipse.birt.report.engine.emitter.nativexls");

            task.setRenderOption(options);
            task.run();
        } catch (EngineException e) {
            e.printStackTrace();
        } finally {
            if (task != null) {
                task.close();
            }
        }
    }
}

な感じでパラメーターなりぶち込んでおけば、IReportEventHandler上でもIReportContextを介して参照する事が出来る模様

んまぁテンプレを読み込みでレポート変数とか作らなくても動的に値を変えちゃうとかも出来るんじゃないかと

ちなみに上記でHandlerと書くべきがAdapterってなってるのはこっちのミスなので...orz

追記

レポートにイベントハンドラーを設定せずに実行側のJavaでそれを制御するには

import java.util.Map;

import org.eclipse.birt.report.engine.api.EXCELRenderOption;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.engine.api.ReportEngine;
import org.eclipse.birt.report.model.api.activity.SemanticException;

public class Client2 {
    @SuppressWarnings("unchecked")
    public static void main(String[] args){
        EngineConfig config = new EngineConfig();

        Map<String, Object> appContext = config.getAppContext();
        appContext.put("test", "hoge fuga foobar");

        ReportEngine engine = new ReportEngine(config);

        IRunAndRenderTask task = null;

        try {
            IReportRunnable design = engine.openReportDesign(
                ClassLoader.getSystemResourceAsStream("sample.rptdesign")
            );

           // 追加
           design.getDesignHandle().setProperty("eventHandlerClass", "SampleLabelEventAdapter");

            task = engine.createRunAndRenderTask(design);

            EXCELRenderOption options = new EXCELRenderOption();
            options.setOutputFormat("xls");
            options.setEmitterID("org.eclipse.birt.report.engine.emitter.nativexls");

            task.setRenderOption(options);
            task.run();
        } catch (EngineException e) {
            e.printStackTrace();
        } catch (SemanticException e) {
            e.printStackTrace();
        } finally {
            if (task != null) {
                task.close();
            }
        }
    }
}

てな感じ

gradleでローカルリポジトリ RubyOnRails演習 (3)