/** * i-net software provides programming examples for illustration only, without warranty * either expressed or implied, including, but not limited to, the implied warranties * of merchantability and/or fitness for a particular purpose. This programming example * assumes that you are familiar with the programming language being demonstrated and * the tools used to create and debug procedures. i-net software support professionals * can help explain the functionality of a particular procedure, but they will not modify * these examples to provide added functionality or construct procedures to meet your * specific needs. * * Copyright © 1999-2025 i-net software GmbH, Berlin, Germany. **/ package rdc; import java.io.File; import java.io.FileOutputStream; import javax.swing.JTable; import com.inet.report.*; import com.inet.viewer.SwingReportViewer; /** * This sample demonstrates how to export a JTable to i-net Clear Reports */ public class ExportDataFromJTable { /** * The function gets the data form the JTable and saves it in a DatabaseTables table from where it can be exported. * To this function you have to assign the JTable and three boolean values: * @param table The JTable which you want to export * @param exportType Sets the export type of the engine (possible file formats: PDF, RTF, HTM, XLS, XML, CSV, PS, * Engine.NO_EXPORT to print) * @param marginOverrun If this value is true the table will be cut if its to wide for one page, otherwise it will * be press-formed to fit. * @param canGrow If this value is true the cells grow to multiple lines when they're to small for contained text. * @param showHeader If this value is true the table header will be shown * @return created engine */ public static Engine exportDataFromJTableToCrystalClear( JTable table, String exportType, boolean marginOverrun, boolean canGrow, boolean showHeader ) { //Set the name of the table final String TABLENAME = "ExportFromJTable"; final String TABLEALIAS; //The Object array tempData is for the data which the JTable contains //the array is two-dimensional and declares as many rows and columns as the JTable have. Object[][] tempData = new Object[table.getRowCount()][table.getColumnCount()]; //tempColumns are the column names String[] tempColumns = new String[table.getColumnCount()]; //tempDataTypes are the data types of the columns, they set the data types of the columns, //in this case the are not needed because we don`t use any databases. int[] tempDataTypes = new int[table.getColumnCount()]; //xPoint is the array which saves the X-coordinate of the columns int[] xPoint = new int[table.getColumnCount()]; //rowsWidth and rowsHeigth save the width and height of the table rows float[] rowsWidth = new float[table.getColumnCount()]; int[] rowsHeight = new int[table.getColumnCount()]; //columnsColor saves the back color of the single columns int[] columnsColor = new int[table.getColumnCount()]; //columnsFontName, columnsFontSize, columnsFontStyle and columnsFontColor //save the font name, -size, -style and -color of the single Columns String[] columnsFontName = new String[table.getColumnCount()]; int[] columnsFontSize = new int[table.getColumnCount()]; int[] columnsFontStyle = new int[table.getColumnCount()]; int[] columnsFontColor = new int[table.getColumnCount()]; //This variables save the font name, font size, font style, font color and the back color of the header String headerFontName; int headerColor; int headerFontSize; int headerFontStyle; int headerFontColor; int indexLastCol = 0; //gridColor saves the color of the JTable grid int gridColor = RDC.toCcColor( table.getGridColor() ); try { Engine eng = RDC.createEmptyEngine( exportType ); final DatabaseTables dbTables = eng.getDatabaseTables();//DatabaseTables stores the database informations final Fields fields = eng.getFields(); //Sets the left and right margin to 1134 twips (2 cm, 0.78 inch) eng.getReportProperties().setMarginLeft( 1134 ); eng.getReportProperties().setMarginRight( 1134 ); //Gets the Fields of the engine DatabaseField dbField = null; //Gets the "page header" and the "details" area, in this areas the table will be drawn Area headArea = eng.getArea( "PH" ); Area pageArea = eng.getArea( "D" ); Area endArea = eng.getArea( "RF" ); //Gets Sections of this areas, the Sections contains some tools to draw the table Section pageSec = pageArea.getSection( 0 ); Section headSec = headArea.getSection( 0 ); Section endSec = endArea.getSection( 0 ); //Sets the height of the pageSec and headSec, naturally you must multiply by 15 to convert from pixel //to twips but here we want to keep the sections a little smaller to anticipate free space between //the header and page section, the sections will grow automatically if they're to small pageSec.setHeight( (table.getRowHeight() * 14) ); headSec.setHeight( (table.getTableHeader().getHeight() * 14) ); //Gets the color and font properties of the table headerColor = RDC.toCcColor( table.getTableHeader().getBackground() ); headerFontName = table.getTableHeader().getFont().getName(); headerFontSize = table.getTableHeader().getFont().getSize(); headerFontStyle = table.getTableHeader().getFont().getStyle(); headerFontColor = RDC.toCcColor( table.getTableHeader().getForeground() ); //This double loop reads the JTable data out for( int columns = 0; columns < table.getColumnCount(); columns++ ) { //Gets the column names tempColumns[columns] = table.getColumn( table.getColumnName( columns ) ).getHeaderValue().toString(); //Gets the row width and height of every column rowsWidth[columns] = table.getColumn( table.getColumnName( columns ) ).getWidth() * 15; rowsHeight[columns] = table.getRowHeight() * 15; //Gets the color of the first cell in every column, in this example the hole column will be //exported in the color of the first JTable cell //the function RDC.toCcColor converts the color to a int value, which can be used by i-net Clear Reports columnsColor[columns] = RDC.toCcColor( table.prepareRenderer( table.getDefaultRenderer( table.getClass() ), 0, columns ).getBackground() ); //Gets the font properties columnsFontName[columns] = table.getCellRenderer( 0, columns ) .getTableCellRendererComponent( table, table.getValueAt( 0, columns ), false, false, 0, columns ).getFont().getName(); columnsFontSize[columns] = table.getCellRenderer( 0, columns ) .getTableCellRendererComponent( table, table.getValueAt( 0, columns ), false, false, 0, columns ).getFont().getSize(); columnsFontStyle[columns] = table.getCellRenderer( 0, columns ) .getTableCellRendererComponent( table, table.getValueAt( 0, columns ), false, false, 0, columns ).getFont().getStyle(); columnsFontColor[columns] = RDC.toCcColor( table.getCellRenderer( 0, columns ) .getTableCellRendererComponent( table, table.getValueAt( 0, columns ), false, false, 0, columns ) .getForeground() ); //Sets the DatabaseTable data types, this types are only important if you use databases tempDataTypes[columns] = Field.STRING; //The internal loop reads the JTable rows of every column out and save them to the two-dimensional array for( int rows = 0; rows < table.getRowCount(); rows++ ) { tempData[rows][columns] = table.getValueAt( rows, columns ); } } //Adding a new table definition to the data source Datasource ds = dbTables.getDatasource( 0 ); TableSource ts = ds.createTableSource( TABLENAME ); for( int colIdx = 0; colIdx < tempColumns.length; colIdx++ ) { ts.addColumn( tempColumns[colIdx], tempDataTypes[colIdx] ); } TABLEALIAS = ts.getAlias(); //This program branch will be performed if the attribute marginOverrun is false and the JTable is more narrow than the page //Creates a FieldElement, we need this to change font and color properties of the DatabaseTable FieldElement fieldEl; //Creates a Text, this Text is used to contain the table headers Text headers; //Creates a TextPart, this TextPart is used to change the font and color properties of the header, //because these may be differently than the table properties TextPart headPart; //Creates a vertical line Line lineVert; //This loop creates the DatabaseTable Columns for( int i = 0; i < table.getColumnCount(); i++ ) { float factorOverMargin; if( !marginOverrun && pageSec.getWidth() < (table.getWidth() * 15) ) { //calculates the factor with every column must be reduced to fit the page factorOverMargin = (float)headSec.getWidth() / (float)(table.getWidth() * 15); //multiply the width of every column width the factor rowsWidth[i] *= factorOverMargin; //calculates the x coordinate for the columns if( i != 0 ) { xPoint[i] = (xPoint[i - 1] + (int)rowsWidth[i - 1]); } else { xPoint[i] = 0; } } else { //Gets the x position of every column if( i != 0 ) { xPoint[i] = ((int)rowsWidth[i - 1] + xPoint[i - 1]); } else { xPoint[i] = 0; } //here the columns that cross the border of the page will cut if( (xPoint[i] + rowsWidth[i]) > pageSec.getWidth() ) { //indexLastCol contains the last drawn column, the horizontal lines possibly must be shorter when the table is cut if( i != 0 ) { indexLastCol = i - 1; } else { indexLastCol = 0; } break; } } if( showHeader ) { //Adds a Text Element to the head Section headers = headSec.addText( xPoint[i], 20, (int)rowsWidth[i], rowsHeight[i] ); //Set the canGrow property for the headers headers.setCanGrow( canGrow ); //Adds a TextPart to the Text Element and adds the column header name to the TextPart headPart = headers.addParagraph().addTextPart( tempColumns[i] ); //Sets the text align of the header headPart.setHorAlign( GeneralProperties.ALIGN_HORIZONTAL_CENTER ); //Set the table font and color properties setHeaderFont( headers, headPart, headerFontName, headerFontSize, headerFontStyle, headerFontColor, headerColor ); //Adds a vertical line to the headSec, the line goes down to the bottom of the pageSec //we subtract 20 twips to square the width of the lines lineVert = headSec.addVerticalLine( (xPoint[i] + (int)rowsWidth[i]) - 20, 20, 0, endSec ); } else { //if no header ought to be shown, the line only goes from top till bottom of the pageSec lineVert = headSec.addVerticalLine( (xPoint[i] + (int)rowsWidth[i]) - 20, headSec.getHeight(), 0, endSec ); } //Sets the fore color of the vertical line lineVert.setForeColor( gridColor ); //Adds a DatadaseField for every column dbField = fields.getDatabaseField( TABLEALIAS + "." + tempColumns[i] ); //Adds a FieldElement to the DatabaseField, the rows will later be set in this FieldElement fieldEl = pageSec.addFieldElement( dbField, xPoint[i], 0, (int)rowsWidth[i], rowsHeight[i] ); fieldEl.setCanGrow( canGrow ); //Set the table font and color properties setTableFont( fieldEl, columnsFontName[i], columnsFontSize[i], columnsFontStyle[i], columnsFontColor[i], columnsColor[i] ); } //Sets the index of the last column if the table is not cut if( !marginOverrun || pageSec.getWidth() >= (table.getWidth() * 15) ) { indexLastCol = table.getColumnCount() - 1; } //Creates a horizontal line at the top and bottom of the headSec and on end of the whole table Line horizontalLineTop = null, horizontalLineBottom, horizontalLineend; horizontalLineBottom = headSec.addHorizontalLine( 0, headSec.getHeight(), (xPoint[indexLastCol] + (int)rowsWidth[indexLastCol]) ); horizontalLineend = endSec.addHorizontalLine( 0, 0, (xPoint[indexLastCol] + (int)rowsWidth[indexLastCol]) ); if( showHeader ) { horizontalLineTop = headSec.addHorizontalLine( 0, 0, (xPoint[indexLastCol] + (int)rowsWidth[indexLastCol]) ); } horizontalLineend.setForeColor( gridColor ); horizontalLineBottom.setForeColor( gridColor ); if( showHeader ) { horizontalLineTop.setForeColor( gridColor ); } //setData sets the data of a two dimensional array or vector to the DatabaseTable eng.setData( tempColumns, tempData, false ); //Creates the first vertical line on the left side of the table Line firstVetLine; if( showHeader ) { firstVetLine = headSec.addVerticalLine( 0, 20, (pageSec.getY() + (table.getTableHeader().getHeight() * 15) - 30), pageSec ); firstVetLine.setForeColor( gridColor ); } else { firstVetLine = pageSec.addVerticalLine( 0, 0, pageSec.getHeight() ); firstVetLine.setForeColor( gridColor ); } //save the resulting report template RDC.saveEngine( new File( "c:/test.rpt" ), eng ); //In every case the engine must executed eng.execute(); //If the export type is NO_EXPORT we print if( exportType.equals( Engine.NO_EXPORT ) ) { print( eng ); } else { //else we export the table to a file, exportType defines the file format export( eng, exportType ); } return eng; } catch( Throwable e ) { e.printStackTrace(); System.exit( 1 ); return null; } } /** * Sets the table color and font properties. * @param fieldEl field whose properties are to be changed * @param tableFont font name * @param tableFontSize font size * @param tableFontStyle font style * @param tableFontColor font color * @param columnsColor color of the column * @throws Throwable if an error occurred */ private static void setTableFont( FieldElement fieldEl, String tableFont, int tableFontSize, int tableFontStyle, int tableFontColor, int columnsColor ) throws Throwable { fieldEl.setFontName( tableFont ); fieldEl.setFontSizeTwips( tableFontSize * 15 ); fieldEl.setFontStyle( tableFontStyle ); fieldEl.setFontColor( tableFontColor ); fieldEl.setBackColor( columnsColor ); } /** * Sets the header color and font properties. * @param text text whose back color are to be changed * @param textPart text part whose properties are to be changed * @param headerFontName font name * @param headerFontSize font size * @param headerFontStyle font style * @param headerFontColor font color * @param headerColor color of the table header * @throws Throwable if an error occurred */ private static void setHeaderFont( Text text, TextPart textPart, String headerFontName, int headerFontSize, int headerFontStyle, int headerFontColor, int headerColor ) throws Throwable { textPart.setFontName( headerFontName ); textPart.setFontSizeTwips( headerFontSize * 15 ); textPart.setFontStyle( headerFontStyle ); textPart.setFontColor( headerFontColor ); text.setBackColor( headerColor ); } /** * Exports the table to a file * @param eng engine that will be exported to a file * @param exportType file format * @throws Throwable if an error occurred */ private static void export( Engine eng, String exportType ) throws Throwable { //if the we want to export the table to an HTML file, we have to use another export algorithm if( exportType == Engine.EXPORT_HTML ) { for( int i = 1; i <= eng.getPageCount(); i++ ) { save( eng.getPageData( 1 ) ); } } else { File outputFile = new File( "C:/Sample." + exportType ); FileOutputStream fos = new FileOutputStream( outputFile ); for( int i = 1; i <= eng.getPageCount(); i++ ) { fos.write( eng.getPageData( i ) ); } fos.close(); } } /** * Prints the table * @param eng engine that will be printed */ private static void print( Engine eng ) { // to initialize we first create a top level ReportViewer: SwingReportViewer viewer = new SwingReportViewer(); // addNewReportView causes a new report view to be created using the given connection as its data source, and then // for this newly created report to be added to the viewer. com.inet.viewer.ReportView currentReportView = viewer.addNewReportView( new PrintEngineReportData( eng ) ); currentReportView.print( 1, -1, false ); } // These functions are used to export the table to an HTML file whith multiple pages /** * Reads a 4-byte number from the byte array * @param buffer byte array to read from * @param idx index to start reading * @return int read from byte array */ private static int readInt( byte[] buffer, int idx ) { int result = (buffer[idx + 0] & 0xFF) + ((buffer[idx + 1] & 0xFF) << 8) + ((buffer[idx + 2] & 0xFF) << 16) + (buffer[idx + 3] << 24); return result; } /** * Takes the byte array of the export data and writes it to the file(s) * @param fData exported data from server as byte array * @throws java.io.IOException if IO issues while writing */ private static void save( byte[] fData ) throws java.io.IOException { int idx = 0; while( idx < fData.length ) { int length = readInt( fData, idx ); if( length == -1 ) { break; } idx += 4; byte[] filename_bytes = new byte[length]; System.arraycopy( fData, idx, filename_bytes, 0, length ); // file name was encoded with UTF8, it need to be decoded here with UTF8 String name = new String( filename_bytes, "UTF8" ); FileOutputStream fos = new FileOutputStream( "C:/" + name ); idx += length; length = readInt( fData, idx ); idx += 4; fos.write( fData, idx, length ); idx += length; fos.close(); } } }