Saltar al contenido

Visualización de pdf en JavaFX

Nuestro grupo de trabajo ha estado horas buscando respuestas a tus dudas, te compartimos la resolución de modo que nuestro deseo es resultarte de mucha ayuda.

Solución:

Código de muestra y uso de JPedalFX

El código de muestra sobre el uso de JPedalFX se proporciona con la descarga de JPedalFX.

Un poco tonto de mi parte, pero pegaré fragmentos de código de muestra aquí que se han copiado del visor de muestra proporcionado con la biblioteca JPedalFX. El código se basa en el archivo jpedal_lgpl.jar incluido con la distribución JPedalFX que se encuentra en la ruta de clase (o la ruta de la biblioteca a la que se hace referencia en el manifiesto de su aplicación jar).

Si tiene más preguntas sobre el uso de JPedalFX, le sugiero que se comunique directamente con IDR Solutions (me han respondido en el pasado).

// get file path.
FileChooser fc = new FileChooser();
fc.setTitle("Open PDF file...");
fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PDF Files", "*.pdf"));     
File f = fc.showOpenDialog(stage.getOwner());
String filename = file.getAbsolutePath();

// open file.
PdfDecoder pdf = new PdfDecoder();
pdf.openPdfFile(filename);
showPage(1);
pdf.closePdfFile();

. . . 

/**
 * Update the GUI to show a specified page.
 * @param page 
 */
private void showPage(int page) 

    //Check in range
    if (page > pdf.getPageCount())
        return;
    if (page < 1)
        return;

    //Store
    pageNumber = page;


    //Show/hide buttons as neccessary
    if (page == pdf.getPageCount())
        next.setVisible(false);
    else
        next.setVisible(true);

    if (page == 1)
        back.setVisible(false);
    else
        back.setVisible(true);


    //Calculate scale
    int pW = pdf.getPdfPageData().getCropBoxWidth(page);
    int pH = pdf.getPdfPageData().getCropBoxHeight(page);

    Dimension s = Toolkit.getDefaultToolkit().getScreenSize();

    s.width -= 100;
    s.height -= 100;

    double xScale = (double)s.width / pW;
    double yScale = (double)s.height / pH;
    double scale = xScale < yScale ? xScale : yScale;

    //Work out target size
    pW *= scale;
    pH *= scale;

    //Get image and set
    Image i = getPageAsImage(page,pW,pH);
    imageView.setImage(i);

    //Set size of components
    imageView.setFitWidth(pW);
    imageView.setFitHeight(pH);
    stage.setWidth(imageView.getFitWidth()+2);
    stage.setHeight(imageView.getFitHeight()+2);
    stage.centerOnScreen();


/**
 * Wrapper for usual method since JFX has no BufferedImage support.
 * @param page
 * @param width
 * @param height
 * @return 
 */
private Image getPageAsImage(int page, int width, int height) 

    BufferedImage img;
    try 
        img = pdf.getPageAsImage(page);

        //Use deprecated method since there's no real alternative 
        //(for JavaFX 2.2+ can use SwingFXUtils instead).
        if (Image.impl_isExternalFormatSupported(BufferedImage.class))
            return javafx.scene.image.Image.impl_fromExternalImage(img);

     catch(Exception e) 
        e.printStackTrace();
    

    return null;


/**
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.jpedal.org
 * (C) Copyright 1997-2008, IDRsolutions and Contributors.
 *
 *  This file is part of JPedal
 *
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * JPedalFX.java
 * ---------------
 */

Procesador de PDF de SwingLabs

Además, en el pasado utilicé un antiguo renderizador de pdf basado en SwingLabs Swing con JavaFX para renderizar archivos PDF para mi navegador web JavaFX. Aunque la integración de Swing / JavaFX no era una característica compatible de JavaFX en el momento en que desarrollé el navegador, todavía me funcionó bien. El código para la integración está en PDFViewer.java y BrowserWindow.java.

Tenga en cuenta que la incrustación de JavaFX en una aplicación Swing es compatible con Java 2.2 y la incrustación de una aplicación Swing en JavaFX es compatible con Java 8.

Sugiero usar la biblioteca de JavaScript PDF JS.

Cree un WebView y cargue estáticamente el contenido html / javascript de este proyecto de ejemplo de visor de pdf en javascript. Crea una función en javascript a la que puedas enviar el byte pdf array para ser mostrado.

De esta manera toda la lógica del visor de pdf ya está ahí. Incluso puede modificar el html de los visores para eliminar algunas características allí.

También tenga cuidado con JPedalFX ya que no lo encontré confiable en los casos en que tuvo que representar imágenes que se agregaron al archivo pdf. En mi caso, JPedalFX no pudo representar una imagen de gráfico que se generó con jfreechart

Ok, aquí están mis 50 centavos. Además de @ALabrosik y @ReneEnriquez responde.

Descargue pdf.js dist y colóquelo debajo src/main/resources

├── pom.xml
├── src
│   └── main
│       ├── java
│       │   └── me
│       │       └── example
│       │           ├── JSLogListener.java
│       │           ├── Launcher.java
│       │           └── WebController.java
│       └── resources
│           ├── build
│           │   ├── pdf.js
│           │   └── pdf.worker.js
│           ├── main.fxml
│           ├── web
│           │   ├── cmaps
│           │   ├── compatibility.js
│           │   ├── debugger.js
│           │   ├── images
│           │   ├── l10n.js
│           │   ├── locale
│           │   ├── viewer.css
│           │   ├── viewer.html
│           │   └── viewer.js

Cree el siguiente archivo fxml (debe ajustar WebView en TabPane o contenedor similar para evitar problemas con el soporte de desplazamiento)










    

Para evitar que pdf.js abra un archivo pdf de demostración al iniciar, abra web/viewer.js Y limpio DEFAULT_URL valor.

var DEFAULT_URL = '';

Abierto web/viewer.html y agregue el bloque de secuencia de comandos:











Ahora el controlador (consulte los comentarios del código para obtener una explicación).

 public class WebController implements Initializable 

    @FXML
    private WebView web;

    @FXML
    private Button btn;

    public void initialize(URL location, ResourceBundle resources) 
        WebEngine engine = web.getEngine();
        String url = getClass().getResource("/web/viewer.html").toExternalForm();

        // connect CSS styles to customize pdf.js appearance
        engine.setUserStyleSheetLocation(getClass().getResource("/web.css").toExternalForm());

        engine.setJavaScriptEnabled(true);
        engine.load(url);

        engine.getLoadWorker()
                .stateProperty()
                .addListener((observable, oldValue, newValue) -> 
                    // to debug JS code by showing console.log() calls in IDE console
                    JSObject window = (JSObject) engine.executeScript("window");
                    window.setMember("java", new JSLogListener());
                    engine.executeScript("console.log = function(message) java.log(message); ;");

                    // this pdf file will be opened on application startup
                    if (newValue == Worker.State.SUCCEEDED) 
                        try 
                            // readFileToByteArray() comes from commons-io library
                            byte[] data = FileUtils.readFileToByteArray(new File("/path/to/file"));
                            String base64 = Base64.getEncoder().encodeToString(data);
                            // call JS function from Java code
                            engine.executeScript("openFileFromBase64('" + base64 + "')");
                         catch (Exception e) 
                            e.printStackTrace();
                        
                    
                );

        // this file will be opened on button click
        btn.setOnAction(actionEvent -> 
            try 
                byte[] data = FileUtils.readFileToByteArray(new File("/path/to/another/file"));
                String base64 = Base64.getEncoder().encodeToString(data);
                engine.executeScript("openFileFromBase64('" + base64 + "')");
             catch (Exception e) 
                e.printStackTrace();
            
        );
    

Algunas de las funciones de pdf.js no funcionarán: abrir archivo (porque pdf.js no tiene acceso a la URL fuera de JAR), imprimir, etc. Para ocultar los botones correspondientes de la barra de herramientas, puede agregar las siguientes líneas a web.css:

#toolbarViewerRight 
    display:none;

Eso es todo. El resto del código es trivial.

public class JSLogListener 

    public void log(String text) 
        System.out.println(text);
    


public class Launcher extends Application 

    public static void main(String[] args) 
        Application.launch();
    

    public void start(Stage primaryStage) throws Exception 
        Parent root = FXMLLoader.load(getClass().getResource("/main.fxml"));
        primaryStage.setTitle("PDF test app");
        primaryStage.setScene(new Scene(root, 1280, 576));
        primaryStage.show();
    

Espero que esto ayude a alguien.

Reseñas y puntuaciones del post

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *