All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.discovery.jasperreports.jasper2word.J2WAbstractJRExporter Maven / Gradle / Ivy

The newest version!
package it.discovery.jasperreports.jasper2word;

import it.discovery.jasperreports.jasper2word.J2WGridPageLayout.ISimplifierGrid;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
import net.sf.jasperreports.export.ExporterInput;
import net.sf.jasperreports.export.ExporterInputItem;
import net.sf.jasperreports.export.ExporterOutput;

import java.util.Collection;
import java.util.Iterator;

/**
 * Base class for the exporter into docx. It's responsible for the initialization of the exporter and the execution of the entire process.
 * Derived classes must define the methods for build the document, using their own specific implementation (es. using poi-apache library
 * or docx4j, etc.).
 * @param  The class representing the docx output document
 * @param  The exporter output (es. stream, file, etc...)
 * @param  The exporter context that produce the output document
 * @param  The print element visitor context for the current exporter
 * @author discovery
 * @date 24/08/15
 */
public abstract class J2WAbstractJRExporter, PC extends J2WAbstractPrintElementVisitorContext>
        extends JRAbstractExporter {

    /**
     * Default constructor which requires one JasperReportsContext.
     * @param jasperReportsContext The exporter context, according Jasper Report Exporter API.
     */
    protected J2WAbstractJRExporter(JasperReportsContext jasperReportsContext) {
        super(jasperReportsContext);
    }

    /**
     * Export the report.
     * @throws JRException In case of errors.
     */
    public void exportReport() throws JRException {
        // Initialize exporter
        this.exporterContext = this.createNewExporterContext();
        ExporterInput input = this.getExporterInput();
        E exporterContext = this.getExporterContext();
        D document = exporterContext.getDocument();

        PC context = this.createVisitorContext();
        context.setDocument(document);
        PrintElementVisitor visitor = this.createPrintElementVisitor();

        // Export every ExporterInputItem
        boolean firstReport = true;
        for (Iterator iterator = input.getItems().iterator(); iterator.hasNext(); ) {
            ExporterInputItem item = iterator.next();
            this.exportReport(item, context, visitor, firstReport, !iterator.hasNext());
            firstReport = false;
        }

        // Write document to output
        exporterContext.writeReport(document, this.getExporterOutput());
    }

    /**
     * Export single item report (ExporterInputItem).
     * @param item The item to export.
     * @param context PrintElementVisitor exporter context (customized for subclasses).
     * @param visitor Element visitor to use for export.
     * @param firstReport Flag that indicates if {@code item} isthe first item to export.
     * @param lastReport Flag that indicates if {@code item} is the last item to export.
     */
    protected void exportReport(ExporterInputItem item, PC context, PrintElementVisitor visitor, boolean firstReport, boolean lastReport) {
        this.setCurrentExporterInputItem(item);
        JasperPrint report = item.getJasperPrint();
        J2WReportConfiguration configuration = (J2WReportConfiguration) item.getConfiguration();
        if (configuration == null)
            configuration = getCurrentItemConfiguration();

        Integer startPageIndex = configuration.getStartPageIndex();
        if (startPageIndex == null)
            startPageIndex = 0;
        Integer endPageIndex = configuration.getEndPageIndex();
        if (endPageIndex == null)
            endPageIndex = item.getJasperPrint().getPages().size() - 1;

        // Ask subclass to prepare for a new JasperPrint (report)
        this.prepareDocument(context, report, firstReport);

        JRExportProgressMonitor progressMonitor = configuration.getProgressMonitor();

        context.setLastPageInfo(null);
        // Export every page of the item
        for (int page = startPageIndex; page <= endPageIndex; page++) {
            JRPrintPage jrPage = report.getPages().get(page);
            // Calculate current page position inside the entire document
            PageOrder pageOrder = new PageOrder();
            if (firstReport && page == startPageIndex)
                pageOrder.firstestPage = true;
            if (page == startPageIndex)
                pageOrder.firstPageCurrentReport = true;
            if (lastReport && page == endPageIndex)
                pageOrder.lastestPage = true;
            if (page == endPageIndex)
                pageOrder.lastPageCurrentReport = true;

            // Export current page
            this.exportPage(jrPage, configuration, context, visitor, page, pageOrder);

            if (progressMonitor != null)
                progressMonitor.afterPageExport();
        }
    }

    /**
     * Export the page in input into the word document.
     * @param jrPage The page to export
     * @param configuration The exporter configuration
     * @param context The visitor exporter context
     * @param visitor The element visitor
     * @param pageNumber The current page number
     * @param pageOrder The current page position inside the entire document
     */
    protected void exportPage(JRPrintPage jrPage, J2WReportConfiguration configuration, PC context, PrintElementVisitor visitor,
                              int pageNumber, PageOrder pageOrder) {
        // Retrieve the simplifier algorithm for the page grid
        ISimplifierGrid semplifierGrid;
        if (configuration != null)
            semplifierGrid = configuration.getSimplifierGrid();
        else
            throw new JRRuntimeException("Missing configuration settings: simplifier not set");
        // Build the page grid
        J2WGridPageLayout grid = new J2WGridPageLayout(jrPage, configuration, semplifierGrid, context.getReport());

        // Read all the elements of the page outside from any element group
        Collection entries = grid.listJRPrintElements(null);

        // Reset the visito context
        context.setLastParagraphX(null);
        context.setLastParagraphWidth(null);
        context.resetLastY();
        context.setLastDocxElement(null);
        context.setLayout(grid);
        context.setConfiguration(configuration);

        // Ask subclass to prepare a new page
        this.prepareNewPage(context, jrPage, pageNumber, pageOrder);

        // Export every element in entries
        for (JRPrintElement element : entries) {
            this.exportJRPrintElement(element, context, visitor);
        }

        // Ask subclass to finalize the page
        this.finalizePage(context, jrPage, pageNumber, pageOrder);

        // Store in visitor context the current page information to allow the comparison with the next page
        context.setLastPageInfo(grid.getPageInfo());
    }

    protected void exportJRPrintElement(JRPrintElement element, PC pageContext, PrintElementVisitor visitor) {
        // Delete visitor to print the element
        element.accept(visitor, pageContext);
    }

    /**
     * Create a new context for the PrintElementVisitor.
     * The context store all the visitor request data.
     * @return A new context for the visitor.
     */
    protected abstract PC createVisitorContext();

    /**
     * Create new PrintElementVisitor according the current implementation.
     * The visitor can export every jasper report element in the output document.
     * @return A new visitor for the report.
     */
    protected abstract PrintElementVisitor createPrintElementVisitor();

    /**
     * Prepare this class to print a new report, appending its page in the current document (if any).
     * @param context The visitor context.
     * @param report The new report to export.
     * @param firstReport A flag that indicates if {@code report} is the first report to export.
     */
    protected abstract void prepareDocument(PC context, JasperPrint report, boolean firstReport);

    /**
     * Prepare this class to print a new page in the current document.
     * @param context The visitor context.
     * @param jrPage The page to export.
     * @param pageNumber The page number in the original report.
     * @param pageOrder The current page position inside the entire document.
     */
    protected abstract void prepareNewPage(PC context, JRPrintPage jrPage, int pageNumber, PageOrder pageOrder);

    /**
     * Finalize the exported page.
     * @param context The visitor context.
     * @param jrPage The page exported.
     * @param pageNumber The page number in the original report.
     * @param pageOrder The current page position inside the entire document.
     */
    protected abstract void finalizePage(PC context, JRPrintPage jrPage, int pageNumber, PageOrder pageOrder);

    /**
     * Create a new exporter context, according current implementation.
     * @return The global exporter context.
     */
    protected abstract E createNewExporterContext();

    /**
     * This class is a simple page cursor. It indicate the relative page position inside the entire document.
     */
    public static class PageOrder {
        /** {@code true} if this is the first page of the first report */
        private boolean firstestPage;
        /** {@code true} if this is the first page of the current report */
        private boolean firstPageCurrentReport;
        /** {@code true} if this is the last page of the current report */
        private boolean lastPageCurrentReport;
        /** {@code true} if this is the last page of the last report */
        private boolean lastestPage;

        /**
         * Constructor: all flags are false.
         */
        public PageOrder() {
        }

        /**
         * Return {@code true} if this page position is the first page of the first report to export.
         * @return {@code true} if this is the first page of the first report, {@code false} otherwise.
         */
        public boolean isFirstestPage() {
            return firstestPage;
        }

        /**
         * Return {@code true} if this page position is the first page of the current report to export.
         * @return {@code true} if this is the first page of the current report, {@code false} otherwise.
         */
        public boolean isFirstPageCurrentReport() {
            return firstPageCurrentReport;
        }

        /**
         * Return {@code true} if this page position is the last page of the current report to export.
         * @return {@code true} if this is the last page of the current report, {@code false} otherwise.
         */
        public boolean isLastPageCurrentReport() {
            return lastPageCurrentReport;
        }

        /**
         * Return {@code true} if this page position is the last page of the last report to export.
         * @return {@code true} if this is the last page of the last report, {@code false} otherwise.
         */
        public boolean isLastestPage() {
            return lastestPage;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy