The CSV report rendering extension package
The implementation package for the CSV report rendering extension example, org.eclipse.birt.report.engine.emitter.csv, contains the following classes:
*CSVPlugin
Defines the methods for starting, managing, and stopping a plug-in instance.
*CSVRenderOption
Integrates the plug-in with BIRT Report Engine, specifying configuration information. CSVRenderOption extends RenderOption, specifying the output format as CSV.
*CSVReportEmitter
Extends org.eclipse.birt.report.engine.emitter.ContentEmitterAdapter. CSVReportEmitter handles the start and end processing that renders the report container.
*CSVTags.java
Defines the comma and new line String settings used when writing to the CSV file.
*CSVWriter
CSVWriter writes the data and label contents of the report to the CSV file, using a call to java.io.PrintWriter.print( ). CSVWriter also uses org.eclipse
.birt.report.engine.emitter.XMLWriter with java.util.logging.Logger to write log messages at specified levels.
The following sections contain specific information about implementation details for the classes in the CSV report rendering extension package.
CSVReportEmitter class
CSVReportEmitter is the class that extends ContentEmitterAdapter to output the text content of the report items to a CSV file. CSVReportEmitter instantiates the writer and emitter objects.
Core CSVReportEmitter methods
CSVReportEmitter implements the following methods:
*CSVReportEmitter( ) instantiates the CSV report emitter class as an org.eclipse.birt.report.engine.presentation.ContentEmitterVisitor object, to perform emitter operations, as shown in Listing 24‑1.
Listing 24‑1 The CSVReportEmitter( ) constructor
public CSVReportEmitter( )
{
contentVisitor = new ContentEmitterVisitor( this );
}
*initialize( ) performs the following operations required to create an output stream that writes the text contents of the report to the CSV file:
*Obtains a reference to the IEmitterServices interface. Instantiates the file and output stream objects, using the specified settings
*Instantiates the CSV writer object
Listing 24‑2 shows the initialize( ) method.
Listing 24‑2 The initialize( ) method
public void initialize( IEmitterServices services )
{
this.services = services;
Object fd = services.getOption
( RenderOptionBase.OUTPUT_FILE_NAME );
File file = null;
try {
if ( fd != null )
{
file = new File( fd.toString( ) );
File parent = file.getParentFile( );
if ( parent != null && !parent.exists( ) )
{
parent.mkdirs( );
}
out = new BufferedOutputStream( new
FileOutputStream( file ) );
}
}
catch ( FileNotFoundException e ) {
logger.log( Level.WARNING, e.getMessage( ), e );
}
if ( out == null )
{
Object value = services.getOption
( RenderOptionBase.OUTPUT_STREAM );
if ( value != null && value instanceof OutputStream )
{
out = (OutputStream) value;
} else
{
try {
file = new File( REPORT_FILE );
out = new BufferedOutputStream( new
FileOutputStream( file ) );
}
catch ( FileNotFoundException e ) {
logger.log( Level.SEVERE, e.getMessage( ), e );
}
}
}
writer = new CSVWriter( );
}
*start( ) performs the following operations:
*Obtains a reference to the IReportContent interface
*Sets the start emitter logging level and writes to the log file
*Opens the output file and specifies the encoding scheme as UTF-8
*Starts the CSV writer
Listing 24‑3 shows the start( ) method.
Listing 24‑3 The start( ) method
public void start( IReportContent report )
{
logger.log( Level.FINE,
"[CSVReportEmitter] Start emitter." );
this.report = report;
 
writer.open( out, "UTF-8" );
writer.startWriter( );
}
*end( ) performs the following operations:
*Sets the end report logging level and writes to the log file
*Ends the write process and closes the CSV writer
*Closes the output file
Listing 24‑4 shows the end( ) method.
Listing 24‑4 The end( ) method
public void end( IReportContent report )
{
logger.log( Level.FINE,
"[CSVReportEmitter] End report." );
writer.endWriter( );
writer.close( );
if( out != null )
{
try {
out.close( );
}
catch ( IOException e ) {
logger.log( Level.WARNING, e.getMessage( ), e );
}
}
}
Other CSVReportEmitter methods
The CSVReportEmitter class defines the following additional methods, called
at different phases of the report generation process, that provide access to emitters, render options, and style information to facilitate BIRT report engine processing:
*startTable( )
When writing to the CSV file, the CSV rendering extension must consider the cell position in the row because a comma appears as the last character in all the cells except the last cell in the row.
The startTable( ) method uses ITableContent.getColumnCount( ) to get information about table column numbers and to initialize the protected columnNumbers variable, as shown in Listing 24‑5.
Listing 24‑5 The startTable( ) method
public void startTable( ITableContent table )
{
assert table != null;
tableDepth++;
columnNumbers = table.getColumnCount( );
...
}
*startRow( )
At the start of each row, startRow( ) performs the following operations:
*Calls isRowInFooterBand( ) to determine if the row is in the header or footer band of a table or group.
*Sets exportElement to false if the current table element belongs to a table header, footer, or is an image, since this extension exports only label and data elements to the CSV file.
*Sets the currentColumn indicator to 0.
Listing 24‑6 shows the startRow( ) code.
Listing 24‑6 The startRow( ) method
public void startRow( IRowContent row )
{
assert row != null;
if ( tableDepth > 1)
{
logger.log( Level.FINE,
"[CSVTableEmitter] Nested tables are not supported." );
return;
}
if ( isRowInFooterBand( row ) )
{
exportElement = false;
}
currentColumn = 0;
}
*isRowInFooterBand( )
If the row is an instance of band content, isRowInFooterBand( ) checks the band type. If the band type is a footer, the method returns true, as shown in Listing 24‑7.
Listing 24‑7 The isRowInFooterBand( ) method
boolean isRowInFooterBand( IRowContent row )
{
IElement parent = row.getParent( );
if ( !( parent instanceof IBandContent ) )
{
return false;
}
IBandContent band = ( IBandContent )parent;
if ( band.getBandType( ) == IBandContent.BAND_FOOTER )
{
return true;
}
return false;
}
*startText( )
If the element is exportable, startText( ) writes the text value to the CSV output file, as shown in Listing 24‑8.
Listing 24‑8 The startText( ) method
public void startText( ITextContent text )
{
if ( tableDepth > 1)
{
logger.log( Level.FINE,
"[CSVTableEmitter] Nested tables are not supported." );
return;
}
String textValue = text.getText( );
if (exportElement)
{
writer.text( textValue );
}
}
*endCell( )
If the current cell is not the last column in the row and the element is exportable, endCell( ) writes a comma to the CSV output file, as shown in Listing 24‑9.
Listing 24‑9 The endCell( ) method
public void endCell( ICellContent cell )
{
if ( ( currentColumn < columnNumbers ) && exportElement )
{
writer.closeTag( CSVTags.TAG_COMMA );
}
}
*endRow( )
At the end of each row, if the element is exportable, endRow( ) writes a new line or carriage return to the CSV output file, as shown in Listing 24‑10.
Listing 24‑10 The endRow( ) method
public void endRow( IRowContent row )
{
if ( exportTableElement )
{
writer.closeTag( CSVTags.TAG_CR );
exportElement = true;
}
}
CSVTags class
The CSVTags class defines the contents of the comma and new line tags, as shown in Listing 24‑11.
Listing 24‑11 The CSVTags class
public class CSVTags
{
public static final String TAG_COMMA = "," ;
public static final String TAG_CR = "\n" ;
}
CSVWriter class
The CSVWriter class writes the closing tags defined in CSVTags, as shown in Listing 24‑12.
Listing 24‑12 The closeTag( ) method
public void closeTag( String tagName )
{
printWriter.print( tagName );
}
CSVRenderOption class
The org.eclipse.birt.report.engine.emitter.csv.CSVRenderOption class extends org.eclipse.birt.report.engine.api.RenderOption to add the CSV rendering option to the BIRT report engine run time, as shown in Listing 24‑13.
Listing 24‑13 The CSVRenderOption class
public class CSVRenderOption extends RenderOption
{
public static final String CSV = "CSV";
public CSVRenderOption( ) { }
}