web-dev-qa-db-fra.com

Affichage pdf en JavaFX

Développer une application de bureau dans JavaFX qui nécessite d'afficher un pdf. J'ai lu qu'il n'y avait pas de support pour la visualisation/affichage de pdf dans JavaFX (version actuelle), j'ai aussi lu à propos de JPedal

Maintenant, questions: 

  1. Existe-t-il un composant externe ou une bibliothèque permettant d'afficher un fichier PDF au format JavaFX? Ce devrait être un logiciel gratuit. 
  2. (Si je dois utiliser JPedal) Comment puis-je l'intégrer dans mon application? 
17
Bilbo Baggins

JPedalFX Exemple de code et d'utilisation

Un exemple de code d'utilisation de JPedalFX est fourni avec le téléchargement de JPedalFX .

C'est un peu boiteux de ma part, mais je vais simplement coller ici des exemples de code extraits qui ont été copiés à partir de la visionneuse d'échantillons fournie avec la bibliothèque JPedalFX. Le code repose sur le fichier jpedal_lgpl.jar inclus dans la distribution JPedalFX situé sur le chemin d'accès aux classes (ou sur le chemin d'accès à la bibliothèque référencée dans le manifeste de votre fichier jar d'application).

Si vous avez d'autres questions concernant l'utilisation de JPedalFX, je vous suggère de vous adresser directement au { contactez IDR solutions) } _ (ils m'ont déjà répondu).

// 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
 * ---------------
 */

SwingLabs PDF Rendu

De plus, j’utilisais jadis un vieux convertisseur de pdf basé sur SwingLabs Swing avec JavaFX pour le rendu de pdf pour mon navigateur Web JavaFX . Bien que l'intégration Swing/JavaFX ne soit pas une fonctionnalité prise en charge de JavaFX au moment où j'ai développé le navigateur, cela fonctionnait toujours bien pour moi. Le code d'intégration est dans PDFViewer.Java et BrowserWindow.Java .

Notez que incorporant JavaFX dans une application Swing est pris en charge en Java 2.2 et intégrant une application Swing en JavaFX est pris en charge en Java 8.

12
jewelsea

Je suggère d'utiliser la bibliothèque javascript PDF JS .

Créez une WebView et chargez statiquement le contenu html/javascript de cet exemple de projet javascript pdf viewer . Créez une fonction en javascript à laquelle vous pouvez envoyer le tableau d'octets pdf à afficher.

De cette façon, toute la logique du visionneur pdf est déjà présente. Vous pouvez même modifier les visualiseurs HTML pour supprimer certaines fonctionnalités là-bas.

Faites également attention à JPedalFX car je l’ai trouvé peu fiable dans les cas où il devait restituer les images ajoutées au fichier pdf. Dans mon cas, JPedalFX n'a ​​pas pu restituer une image de graphique générée avec jfreechart.

11
ALabrosk

Ok, voici mes 50 cents. En plus de @ALabrosik et @ReneEnriquez répond.

Téléchargez pdf.js dist et placez-le sous 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

Créez le fichier fxml suivant (vous devez envelopper WebView dans TabPane ou un conteneur similaire pour éviter les problèmes de prise en charge du défilement)

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.web.WebView?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="576.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="me.example.WebController">
    <center>
      <TabPane>
         <tabs>
            <Tab text="PDF test">
               <content>
                    <WebView fx:id="web" minHeight="-1.0" minWidth="-1.0" />
               </content>
            </Tab>
         </tabs>
      </TabPane>
    </center>
   <bottom>
      <Button fx:id="btn" mnemonicParsing="false" text="Open another file" BorderPane.alignment="CENTER" />
   </bottom>
</BorderPane>

Pour empêcher pdf.js d'ouvrir le fichier pdf de démonstration au démarrage, ouvrez web/viewer.js et effacez DEFAULT_URL valeur.

var DEFAULT_URL = '';

Ouvrez web/viewer.html et ajoutez un bloc de script:

<head>

<!-- ... -->
<script src="viewer.js"></script>

<!-- CUSTOM BLOCK -->
<script>
    var openFileFromBase64 = function(data) {
        var arr = base64ToArrayBuffer(data);
        console.log(arr);
        PDFViewerApplication.open(arr);
    }

    function base64ToArrayBuffer(base64) {
      var binary_string = window.atob(base64);
      var len = binary_string.length;
      var bytes = new Uint8Array( len );
      for (var i = 0; i < len; i++)        {
          bytes[i] = binary_string.charCodeAt(i);
      }
      return bytes.buffer;
    }
</script>
<!-- end of CUSTOM BLOCK -->

</head>

Maintenant le contrôleur (voir les commentaires de code pour une explication). 

 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();
            }
        });
    }
}

Certaines fonctions de pdf.js ne fonctionneront pas: fichier ouvert (car pdf.js n’a pas accès à l’URL en dehors de JAR), impression, etc. Pour masquer les boutons de barre d’outils correspondants, vous pouvez ajouter les lignes suivantes à web.css:

#toolbarViewerRight {
    display:none;
}

C'est tout. Le reste du code est 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();
    }
}

J'espère que cela aide quelqu'un.

9
enzo

Essayez JPedalFX Il est indiqué sur leur site web que "JPedalFX est un visualiseur léger PDF basé sur JavaFX 2 et la version LGPL de JPedal. Il présente une interface simple et est conçu pour visualiser rapidement et facilement PDF documents. "

http://www.idrsolutions.com/jpedalfx-viewer/

Havent essayé encore mais espère que ça aide

2
Jabir

Vous pouvez aussi essayer avec iText, je travaille avec Java Un tutoriel sur son utilisation

1
Moslem Cherif

Pour certaines personnes, il peut être utile de convertir le document PDF en HTML et de l'afficher avec une vue Web.

L'outil de ligne de commande Open Source pdf2htmlEx génère de très beaux fichiers HTML autonomes avec images et JavaScript intégré.

1
Doc Brown

ICEPDF est très facile à utiliser, gratuit et léger. Je l'ai récemment utilisé pour faire une petite application d'indexation PDF pour mon entreprise;)

0
Isaac

J'ai écrit un exemple assez simple en utilisant des vues Web et pdf.js, voici le code source disponible sur GitHub:

https://github.com/enriquezrene/curso-javafx-udemy/tree/master/clase-17/curso-javafx

Profitez-en!!!

0
Rene Enriquez