Visualizar Reportes Jasper en JavaFX

Jasper Report es una librería utilizada para la construcción de reportes en Java, la misma cuenta con un visor de reportes construido con Swing, por lo que crearemos un visor en JavaFX que nos permita visualizar nuestros reportes sin inconvenientes de interoperabilidad.

El visor que crearemos nos permitirá visualizar un objeto JasperPrint por lo que podremos utilizar el mismo para visualizar reportes provenientes de Jasper Report directamente o de librerías como DynamicReports ó DynamicJasper que utilizan Jasper como núcleo.

Visor de reporte JasperFX
Convertiremos las representación 2D del reporte generado por Jasper a gráficos compatibles con JavaFX, hablando en términos de clases convertiremos un objeto de la clase BufferedImage a WritableImage.

Primero obtenemos el área visible del reporte:

private BufferedImage getImage(JasperPrint jasperPrint, int pageIndex, float zoom) throws JRException {
    int canvas_width = (int) canvas.getWidth();
    int canvas_height = (int) canvas.getHeight();

    BufferedImage pageImage = new BufferedImage(canvas_width, canvas_height, BufferedImage.TYPE_INT_ARGB);
    if (exporter == null) {
        exporter = new JRGraphics2DExporter(jasperReportsContext);
        exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
    }

    int offsetx = (int) sbHorizontal.getValue();
    int offsety = (int) sbVertical.getValue();

    SimpleGraphics2DExporterOutput output = new SimpleGraphics2DExporterOutput();
    output.setGraphics2D((Graphics2D) pageImage.getGraphics());
    output.getGraphics2D().translate(-offsetx, -offsety);

    exporter.setExporterOutput(output);

    SimpleGraphics2DReportConfiguration configuration = new SimpleGraphics2DReportConfiguration();
    configuration.setPageIndex(pageIndex);
    configuration.setZoomRatio(zoom);

    exporter.setConfiguration(configuration);
    exporter.exportReport();

    return pageImage;
}

La imagen obtenida representa solamente el área que se encuentra visible actualmente, al cambiar el desplazamiento o tamaño de la ventana se calcula nuevamente la imagen.

Ahora convertimos la imagen para que se pueda dibujar sobre JavaFX:

private void renderPage(int actual) {
    try {
        float zoomRatio = getZoom();
        PrintPageFormat pageFormat = print.getPageFormat(actual);

        int image_width = (int) (pageFormat.getPageWidth() * zoomRatio);
        int image_height = (int) (pageFormat.getPageHeight() * zoomRatio);
        int ch = (int) canvas.getHeight(), cw = (int) canvas.getWidth();
        int xpos = cw > image_width ? (cw / 2) - (image_width / 2) : 0;
        int ypos = ch > image_height ? (ch / 2) - (image_height / 2) : 0;

        BufferedImage bimage = getImage(print, actual, zoomRatio);
        WritableImage wimage = SwingFXUtils.toFXImage(bimage, null);

        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.clearRect(0, 0, cw, ch);
        gc.drawImage(wimage, xpos, ypos);
    } catch (JRException e) {
        e.printStackTrace();
}

Esta función también dibuja la imagen en la posición adecuada a los desplazamientos actuales.

Otra función a la que debemos hacer referencia es la siguiente, que permite exportar el reporte visualizado a los formatos: .pdf, .html, .docx, .xlsx

private void saveReport() {
    FileChooser fileChooser = new FileChooser();
    fileChooser.setInitialFileName("Reporte.pdf");
    fileChooser.setTitle("Guardar Reporte");

    fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("PDF Document", Arrays.asList("*.pdf", "*.PDF")));
    fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("DOCX Document", Arrays.asList("*.docx", "*.DOCX")));
    fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XLSX Document", Arrays.asList("*.xlsx", "*.XLSX")));
    fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("HTML Document", Arrays.asList("*.html", "*.HTML")));

    File file = fileChooser.showSaveDialog(stage);
    if (fileChooser.getSelectedExtensionFilter() != null && fileChooser.getSelectedExtensionFilter().getExtensions() != null) {
        java.util.List<String> selectedExtension = fileChooser.getSelectedExtensionFilter().getExtensions();
        try {
            if (selectedExtension.contains("*.pdf")) {
                JasperExportManager.exportReportToPdfFile(print, file.getAbsolutePath());
            } else if (selectedExtension.contains("*.html")) {
                JasperExportManager.exportReportToHtmlFile(print, file.getAbsolutePath());
            } else if (selectedExtension.contains("*.docx")) {
                ReportExporter.docx(print, file.getAbsolutePath());
            } else if (selectedExtension.contains("*.xlsx")) {
                ReportExporter.xlsx(print, file.getAbsolutePath());
            }
        } catch (JRException e) {
            e.printStackTrace();
        }}}

Este visor permite guardar, imprimir, navegar entre las distintas páginas del reporte, cambiar el zoom.

GitHub: Visor de reportes JavaFX

Comentarios

Publicar un comentario

Entradas populares de este blog

Conectar SQL Server con Java

Detección de rostros

Instalar OpenCV para Python en Windows