Как программно установить источник данных для отчета BIRT? - PullRequest
12 голосов
/ 14 июля 2010

У меня есть отчет BIRT, который подключается к нашей тестовой базе данных. В продуктивной среде я хотел бы предоставить источник данных, который предоставляется контейнером через jndi.

Как бы я программно установил источник данных для данного отчета?

    ...
    IReportRunnable design = birtEngine.openReportDesign ( new File ( properties.getProperty ( "reportPath" ), report + ".rptdesign" ).getAbsolutePath () );
    IRunAndRenderTask task = birtEngine.createRunAndRenderTask ( design );

    PDFRenderOption options = new PDFRenderOption ();
    options.setOutputFormat ( PDFRenderOption.OUTPUT_FORMAT_PDF );
    options.setOutputStream ( out );
    task.setRenderOption ( options );
    for ( Entry<String, Object> entry : parameters.entrySet () )
    {
        task.setParameterValue ( entry.getKey (), entry.getValue () );
    }

    task.run ();
    task.close ();
    ...

Полагаю, мне бы пришлось изменить design, но с другой стороны, task имеет метод setDataSource, но это немного похоже на то, что мне нужно было бы предоставить некоторые элементы xml dom.

Ответы [ 5 ]

6 голосов
/ 11 февраля 2011

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

Для моих требований это работает нормально.

Я получил это с какого-то сайта, не помню.

import java.io.IOException;
import java.util.ArrayList; 

import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.model.api.CellHandle;
import org.eclipse.birt.report.model.api.DataItemHandle;
import org.eclipse.birt.report.model.api.DesignConfig; 
import org.eclipse.birt.report.model.api.ElementFactory;
import org.eclipse.birt.report.model.api.IDesignEngine;
import org.eclipse.birt.report.model.api.IDesignEngineFactory;
import org.eclipse.birt.report.model.api.LabelHandle;
import org.eclipse.birt.report.model.api.OdaDataSetHandle;
import org.eclipse.birt.report.model.api.OdaDataSourceHandle;
import org.eclipse.birt.report.model.api.PropertyHandle;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.RowHandle;
import org.eclipse.birt.report.model.api.SessionHandle;
import org.eclipse.birt.report.model.api.StructureFactory;
import org.eclipse.birt.report.model.api.TableHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import org.eclipse.birt.report.model.api.elements.structures.ComputedColumn;

import com.ibm.icu.util.ULocale;

/**
 * Dynamic Table BIRT Design Engine API (DEAPI) demo.
 */

public class DECreateDynamicTable
{
    ReportDesignHandle designHandle = null;
    ElementFactory designFactory = null;
    StructureFactory structFactory = null;  

    public static void main( String[] args )
    {
        try
        {
            DECreateDynamicTable de = new DECreateDynamicTable();
            ArrayList al = new ArrayList();
            al.add("USERNAME");
            al.add("COUNTRY");
            de.buildReport(al, "From GTM_REPORT_APP_USER" );
        }
        catch ( IOException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch ( SemanticException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    void buildDataSource( ) throws SemanticException
    {

        OdaDataSourceHandle dsHandle = designFactory.newOdaDataSource(
                "Data Source", "org.eclipse.birt.report.data.oda.jdbc" );
        dsHandle.setProperty( "odaDriverClass",
                "oracle.jdbc.driver.OracleDriver" );
        dsHandle.setProperty( "odaURL", "jdbc:oracle:thin:@xeon:1521:ora9i" );
        dsHandle.setProperty( "odaUser", "AIMS_GTMNE" );
        dsHandle.setProperty( "odaPassword", "AIMS_GTMNE" );

        designHandle.getDataSources( ).add( dsHandle );

    }

    void buildDataSet(ArrayList cols, String fromClause ) throws SemanticException
    {

        OdaDataSetHandle dsHandle = designFactory.newOdaDataSet( "ds",
                "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" );
        dsHandle.setDataSource( "Data Source" );
        String qry = "Select ";
        for( int i=0; i < cols.size(); i++){
            qry += " " + cols.get(i);
            if( i != (cols.size() -1) ){
                qry += ",";
            }

        }
        qry += " " + fromClause;

        dsHandle.setQueryText( qry );

        designHandle.getDataSets( ).add( dsHandle );



    }
    void buildReport(ArrayList cols, String fromClause ) throws IOException, SemanticException
    {


        //Configure the Engine and start the Platform
        DesignConfig config = new DesignConfig( );

        config.setProperty("BIRT_HOME", "D:/Softwares/Frame Works - APIs-Tools/birt-runtime-2_6_1/birt-runtime-2_6_1/ReportEngine");

        IDesignEngine engine = null;
        try{


            Platform.startup( config );
            IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject( IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY );
            engine = factory.createDesignEngine( config );

        }catch( Exception ex){
            ex.printStackTrace();
        }       


        SessionHandle session = engine.newSessionHandle( ULocale.ENGLISH ) ;



        try{
            //open a design or a template

            designHandle = session.openDesign("D:/tempBirtReport/test.rptdesign");

            designFactory = designHandle.getElementFactory( );

            buildDataSource();
            buildDataSet(cols, fromClause);

            TableHandle table = designFactory.newTableItem( "table", cols.size() );
            table.setWidth( "100%" );
            table.setDataSet( designHandle.findDataSet( "ds" ) );


            PropertyHandle computedSet = table.getColumnBindings( ); 
            ComputedColumn  cs1 = null;

            for( int i=0; i < cols.size(); i++){
                cs1 = StructureFactory.createComputedColumn();
                cs1.setName((String)cols.get(i));
                cs1.setExpression("dataSetRow[\"" + (String)cols.get(i) + "\"]");
                computedSet.addItem(cs1);
            }


            // table header
            RowHandle tableheader = (RowHandle) table.getHeader( ).get( 0 );


            for( int i=0; i < cols.size(); i++){
                LabelHandle label1 = designFactory.newLabel( (String)cols.get(i) ); 
                label1.setText((String)cols.get(i));
                CellHandle cell = (CellHandle) tableheader.getCells( ).get( i );
                cell.getContent( ).add( label1 );
            }                           

            // table detail
            RowHandle tabledetail = (RowHandle) table.getDetail( ).get( 0 );
            for( int i=0; i < cols.size(); i++){
                CellHandle cell = (CellHandle) tabledetail.getCells( ).get( i );
                DataItemHandle data = designFactory.newDataItem( "data_"+(String)cols.get(i) );
                data.setResultSetColumn( (String)cols.get(i));
                cell.getContent( ).add( data );
            }

            designHandle.getBody( ).add( table );

            // Save the design and close it. 

            designHandle.saveAs( "D:/tempBirtReport/test.rptdesign" ); //$NON-NLS-1$
            designHandle.close( );
            System.out.println("Finished");
        }catch (Exception e){
            e.printStackTrace();
        }       

    }
 }
3 голосов
/ 19 августа 2010

Вы можете создать параметр отчета для строки подключения к базе данных.

Затем установите URL-адрес JNDI в разделе «Источник данных» -> «Привязка свойства» -> «URL-адрес JNDI» в виде: params ["База данных"]. Значение
(Где «База данных» - это имя параметра отчета)

2 голосов
/ 23 июля 2010

Установка только источника данных во время выполнения будет проблематичной, поскольку набор данных привязан к одному источнику данных, а ваши элементы управления в отчете затем привязываются к конкретному набору данных.Эту иерархию было бы довольно сложно создавать каждый раз при запуске отчета.

Вы можете параметризовать все аспекты определения источника данных, делая ваш проект переносимым во все среды.При редактировании источника данных посмотрите на группу привязки свойств с левой стороны.Это должно дать вам достаточно гибкости, чтобы сделать ваш источник данных более портативным.Можно указать параметры времени выполнения для элементов URL JDBC или профиля JNDI времени выполнения.

Надеюсь, это поможет.

1 голос
/ 16 декабря 2016

Это сработало для меня. Я получил контекст и из контекста получил источник данных и передал соединение с отчетом Birt, как показано ниже

  Context initialContext = new InitialContext();
     if ( initialContext == null){
     System.out.println("JNDI problem. Cannot get InitialContext.");
        }
        DataSource datasource = (DataSource)initialContext.lookup("java:/datasources/SAMPLE");
     task.getAppContext().put("OdaJDBCDriverPassInConnection", datasource.getConnection());
1 голос
/ 04 февраля 2014

Мне нравится подход Адамса.Вот как мы это делаем:

    /*
 * Change the data sources in the .rptdesign
 */
void changeDataSource(ElementFactory designFactory,
        ReportDesignHandle designHandle, String userConnect)
        throws SemanticException {

    SlotHandle datasources = designHandle.getDataSources();
    SlotIterator iter = (SlotIterator) datasources.iterator();
    while (iter.hasNext()) {
        DesignElementHandle dsHandle = (DesignElementHandle) iter.next();
        if (dsHandle instanceof OdaDataSourceHandle && dsHandle.getName().equals("lisa")) {
            log.debug("changeDataSource: Changing datasource "
                    + dsHandle.getName() + " new url=" + getLisaDbUrl());
            dsHandle.setProperty("odaDriverClass",
                    "oracle.jdbc.driver.OracleDriver");
            dsHandle.setProperty("odaURL", getLisaDbUrl());
            dsHandle.setProperty("odaUser", getLisaUser());
            dsHandle.setProperty("odaPassword", getLisaPassword());
        } else {
            log.debug("changeDataSource: Ignoring DS " + dsHandle.getName());
        }
    }
}

Здесь "lisa" - это имя источника данных, который мы хотели бы изменить во время выполнения.Функция get ... возвращает значения, необходимые во время «производства».

...