Monday, April 25, 2011

Create PDF and RTF reports using Jasper API

Using Japer, you can create reports in various formats like CSV file, HTML file, PDF file, RTF file, Excel file, XML file etc. First of all, the report needs to be designed using a report designer. I was using the open source report designing tool called, iReport. You can produce a report using the data from a database, parameters, variable expressions etc. If you are generating the report from a custom class file (DAO), include it in the class path of iReport. Using the iReport designing tool, you’ll be able to create a report as a JRXML/XML file; compile the report creating a new file with extension, .jasper called as ‘Jasper file’. We will be using this Jasper file in our java code.
Download the Jasper API with all its dependent jar’s and invoke the report using the API. Here is a sample to generate PDF and RTF reports. Generating other formats are very similar to this. Here I am using a custom datasource inplemented from JRDataSource for generating the reports. Since I was writing a web service to generate reports, I wasn’t rendering the report but returning the report in byte array. The client progran would use the FileOutputStream to render the report from byte array or could directly feed the byte array to the OutputStream of the HttpServletResponse.

public byte[] buildRtfResume(final String ssnNumber) {
     ResumeEngineImpl.log.debug("Building RTF Resume for " + ssnNumber);
     byte[] rtfResume = null;
     try {
          final Applicant applicant = this.getApplicantBySsn(ssnNumber);
          final JasperPrint jasperPrint = this.renderCV(applicant);
          final JRRtfExporter rtfExporter = new JRRtfExporter();
          final ByteArrayOutputStream rtfStream = new ByteArrayOutputStream();
          rtfExporter.setParameter(JRExporterParameter.JASPER_PRINT,jasperPrint);
          rtfExporter.setParameter(JRExporterParameter.OUTPUT_STREAM,rtfStream);
          rtfExporter.exportReport();
          rtfResume = rtfStream.toByteArray();
     } catch (final JRException e) {
          ResumeEngineImpl.log.error(e.getMessage(), e);
     } catch (final RuntimeException e) {
          ResumeEngineImpl.log.error(e.getMessage(), e);
     }
     return rtfResume;
}

public byte[] buildPdfResume(final String ssnNumber) {
     ResumeEngineImpl.log.debug("Building PDF Resume for " + ssnNumber);
     byte[] pdfResume = null;
     try {
          final Applicant applicant = this.getApplicantBySsn(ssnNumber);
          final JasperPrint jasperPrint = this.renderCV(applicant);
          pdfResume = JasperExportManager.exportReportToPdf(jasperPrint);
     } catch (final JRException e) {
          ResumeEngineImpl.log.error(e.getMessage(), e);
     } catch (final RuntimeException e) {
          ResumeEngineImpl.log.error(e.getMessage(), e);
     }
     return pdfResume;
}

JasperPrint object represents the output, which can be viewed, printed or exported to many different formats.JasperFillManager class is used for report filling process. It takes three arguments to fill a report; Compiled report design, Parameters and Datasources.

public JasperPrint renderCV(Applicant applicant){
     ..........
     ..........
     final JasperReport jasperReport = (JasperReport) JRLoader.loadObject(this.getClass().getClassLoader().getResourceAsStream("jerry/jacob/reports/resume.jasper"));
     final JasperReport empHistSubReport = (JasperReport) JRLoader.loadObject(this.getClass().getClassLoader().getResourceAsStream("jerry/jacob/reports/EmploymentSubReport.jasper"));
     final JasperReport edHistSubReport = (JasperReport) JRLoader.loadObject(this.getClass().getClassLoader().getResourceAsStream("jerry/jacob/reports/EducationSubReport.jasper"));
     .........
     final EmpHistDataSource empHistDataSource = new EmpHistDataSource(empHists);
     final EducationHistDataSource edHistDataSource = new EducationHistDataSource(eduHists);
     .........
     final Map parameters = new HashMap();
     // add sub reports to map
     parameters.put("EmploymentSubReport", empHistSubReport);
     parameters.put("EducationSubReport", edHistSubReport);
     // add data sources to map
     parameters.put("EmploymentDataSource", empHistDataSource);
     parameters.put("EducationDataSource", edHistDataSource);
     return JasperFillManager.fillReport(jasperReport, parameters,applicantDataSource);
}

Getting the word document:
public byte[] buildDocResume(final String ssnNumber) {

        final String sourceMethod = "buildDocResume";
        ResumeEngineImpl.log.entering(ResumeEngineImpl.sourceClass,
                sourceMethod, ssnNumber);
        byte[] docResume = null;
        try {
            final Seeker seeker = this.getSeekerBySsn(ssnNumber);
            final JasperPrint jasperPrint = this.renderResume(seeker);

            final JRDocxExporter docExporter = new JRDocxExporter();
            final ByteArrayOutputStream docStream = new ByteArrayOutputStream();
            docExporter.setParameter(JRDocxExporterParameter.JASPER_PRINT,
                    jasperPrint);
            docExporter.setParameter(JRDocxExporterParameter.OUTPUT_STREAM,
                    docStream);
            docExporter.setParameter(JRDocxExporterParameter.FLEXIBLE_ROW_HEIGHT, Boolean.TRUE);
            docExporter.exportReport();
            docResume = docStream.toByteArray();
        } catch (final JRException e) {
            ResumeEngineImpl.log.logp(Level.WARNING,
                    ResumeEngineImpl.sourceClass, sourceMethod,
                    "Exception caught:", e);
        } catch (final RuntimeException e) {
            ResumeEngineImpl.log.logp(Level.WARNING,
                    ResumeEngineImpl.sourceClass, sourceMethod,
                    "Exception caught:", e);
        }

        return docResume;
    }

Tip: The generated word document will be formatted using several nested tables. If the property, JRDocxExporterParameter.FLEXIBLE_ROW_HEIGHT, is set to false, the table rows do not increase in height automatically and the user has to enlarge them manually in word.

No comments:

Post a Comment

Chitika