Friday, December 13, 2013

NextReports: Creating the report programmatically

NextReports can be used to create a report programmatically. In our company, there was a need to have a report automatically created starting from a sql query and then run it using the engine api. Just think you have a set of data and a simple template which informs about layout properties (fonts, colors, padding and so on) and you want to bypass the process of creating a report using the designer.

To achieve this you have to create a Report object.
  Report report = new Report();
  report.setName("Report File Name"); 
  report.setSql("select ..."); 
  report.setLayout(createLayout(columnNames, "Title"));
The only thing you have to do is to create the ReportLayout:
 public static ReportLayout createLayout(List<String> columnNames, String title) {

        ReportLayout reportLayout = new ReportLayout();
        reportLayout.setReportType(ResultExporter.DEFAULT_TYPE);
        int size = columnNames.size();

        // create a row in header band with a title cell spanned on the entire row
        Band headerBand = reportLayout.getHeaderBand();
        List<BandElement> titleRow = new ArrayList<BandElement>();
        BandElement titleElement = new BandElement(title);
        titleElement.setColSpan(size);
        titleElement.setHorizontalAlign(BandElement.CENTER);
        titleElement.setVerticalAlign(BandElement.MIDDLE);
        titleElement.setPadding(new Padding(1,1,1,1));
        titleRow.add(titleElement);
        for (int i = 0; i < size - 1; i++) {
            titleRow.add(null);
        }
        List<List<BandElement>> headerElements = new ArrayList<List<BandElement>>();
        headerElements.add(titleRow);

        // create two rows in detail band: 
        // first with column names and second with ColumnBandElement cells
        Band detailBand = reportLayout.getDetailBand();
        List<BandElement> headerNamesRow = new ArrayList<BandElement>(size);
        List<bandelement> headerFieldsRow = new ArrayList<BandElement>(size);
        for (String column : columnNames) {
         BandElement he = new BandElement(column);
         he.setPadding(new Padding(1,1,1,1));
            headerNamesRow.add(he);
            BandElement ce = new ColumnBandElement(column);
            ce.setPadding(new Padding(1,1,1,1));
            headerFieldsRow.add(ce);
        }
        List<List<BandElement>> detailElements = new ArrayList<List<BandElement=>>();
        headerElements.add(headerNamesRow);
        detailElements.add(headerFieldsRow);
        
        // create an empty footer row
        Band footerBand = reportLayout.getFooterBand();
        List<List<BandElement>> footerElements = new ArrayList<List<BandElement>>();
        List<BandElement> footerRow = new ArrayList<BandElement>();
        for (int i = 0; i < size; i++) {
         footerRow.add(new BandElement(""));
        }
        footerElements.add(footerRow);

        headerBand.setElements(headerElements);
        detailBand.setElements(detailElements);
        footerBand.setElements(footerElements);               

        return reportLayout;
    }
  
This is the method used by "New Report" action from designer. You can choose any template properties to add on your BandElement cells.

After creating the report you can run it using the engine api or you can save it using  any ro.nextreports.engine.util.ReportUtil save methods.

No comments: