2013-08-13 14 views
14

Entwickeln einer Desktopanwendung in JavaFX, die ein PDF anzeigen muss. Ich lese, dass es keine Unterstützung für PDF-Anzeige/Anzeige in JavaFX (aktuelle Version) gibt, ich lese auch über JPedal.Anzeigen von PDF in JavaFX

nun Fragen:

  1. Gibt es eine externe Komponente oder Bibliothek pdf in JavaFX zu sehen? Es sollte eine Freeware sein.
  2. (Wenn ich JPedal verwenden muss) Wie kann ich es in meiner Anwendung einbetten.

Antwort

11

JPedalFX Beispielcode und Nutzungs

Beispielcode hilft JPedalFX zur Verwendung mit dem JPedalFX download zur Verfügung gestellt.

Irgendwie lahm von meiner Seite, aber ich füge nur Code-Schnipsel ein, die aus dem Sample Viewer der JPedalFX-Bibliothek kopiert wurden. Der Code basiert auf der Datei jpedal_lgpl.jar, die in der JPedalFX-Verteilung enthalten ist, die sich auf dem Klassenpfad (oder dem Bibliothekspfad, auf den im Manifest des Anwendungs-jars verwiesen wird) befindet.

Sollten Sie weitere Fragen zur Verwendung von JPedalFX haben, schlage ich Ihnen vor, dass Sie contact IDR solutions directly (sie haben in der Vergangenheit auf mich reagiert haben).

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

Additionaly, benutzte ich eine alte SwingLabs Swing-basierte PDF-Renderer mit JavaFX in der Vergangenheit für PDF-Dateien für meine JavaFX web browser Rendering. Obwohl die Swing/JavaFX-Integration zu der Zeit, als ich den Browser entwickelte, keine unterstützte Funktion von JavaFX war, funktionierte sie immer noch gut für mich. Code für die Integration ist in PDFViewer.java und BrowserWindow.java.

Beachten Sie, dass embedding JavaFX in a Swing app in Java unterstützt 2.2 und embedding a Swing app in JavaFX wird in Java unterstützt 8.

+0

vielen Dank. –

+4

JPedalFX ist jetzt nicht frei:/ – GlacialMan

2

Try JPedalFX es auf ihrer Website heißt, dass „JPedalFX ein leichter PDF-Viewer auf JavaFX 2 und der LGPL Version von JPedal basierte. Es hat eine einfache Schnittstelle und ist für eine schnelle und einfache Anzeige von PDF-Dokumenten entworfen . "

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

Havent versuchte noch, aber hoffen, dass es

+0

Jabir danke für die Antwort, aber ich habe schon darüber gelesen. Ich möchte wissen, wie man es benutzt. Wenn Sie einen Beispielcode bereitstellen können, wäre es nett. –

+0

Es gibt ein Tutorial unter http://blog.idrsolutions.com/2014/01/writing-javafx-pdf-viewer-plugin-netbeans-1-introduction/ –

0

ICEPDF wirklich einfach mit, frei zu arbeiten, und leicht. Ich habe es vor kurzem eine kleine PDF Indizieranwendung für mein Unternehmen zu machen;)

1

Sie mit iText versuchen, ich arbeite mit ihm in Java A tutorial about how to use it

+1

Kannst du Inhalte von deinem Link posten? – Robert

+0

guck mal wieder auf den code was ich gepostet habe –

-1
package de.vogella.itext.write; 

import java.io.FileOutputStream; 
import java.util.Date; 

import com.itextpdf.text.Anchor; 
import com.itextpdf.text.BadElementException; 
import com.itextpdf.text.BaseColor; 
import com.itextpdf.text.Chapter; 
import com.itextpdf.text.Document; 
import com.itextpdf.text.DocumentException; 
import com.itextpdf.text.Element; 
import com.itextpdf.text.Font; 
import com.itextpdf.text.List; 
import com.itextpdf.text.ListItem; 
import com.itextpdf.text.Paragraph; 
import com.itextpdf.text.Phrase; 
import com.itextpdf.text.Section; 
import com.itextpdf.text.pdf.PdfPCell; 
import com.itextpdf.text.pdf.PdfPTable; 
import com.itextpdf.text.pdf.PdfWriter; 


public class FirstPdf { 
    private static String FILE = "c:/temp/FirstPdf.pdf"; 
    private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, 
     Font.BOLD); 
    private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12, 
     Font.NORMAL, BaseColor.RED); 
    private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, 
     Font.BOLD); 
    private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12, 
     Font.BOLD); 

    public static void main(String[] args) { 
    try { 
     Document document = new Document(); 
     PdfWriter.getInstance(document, new FileOutputStream(FILE)); 
     document.open(); 
     addMetaData(document); 
     addTitlePage(document); 
     addContent(document); 
     document.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

    // iText allows to add metadata to the PDF which can be viewed in your Adobe 
    // Reader 
    // under File -> Properties 
    private static void addMetaData(Document document) { 
    document.addTitle("My first PDF"); 
    document.addSubject("Using iText"); 
    document.addKeywords("Java, PDF, iText"); 
    document.addAuthor("Lars Vogel"); 
    document.addCreator("Lars Vogel"); 
    } 

    private static void addTitlePage(Document document) 
     throws DocumentException { 
    Paragraph preface = new Paragraph(); 
    // We add one empty line 
    addEmptyLine(preface, 1); 
    // Lets write a big header 
    preface.add(new Paragraph("Title of the document", catFont)); 

    addEmptyLine(preface, 1); 
    // Will create: Report generated by: _name, _date 
    preface.add(new Paragraph("Report generated by: " + System.getProperty("user.name") + ", " + new Date(), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 
     smallBold)); 
    addEmptyLine(preface, 3); 
    preface.add(new Paragraph("This document describes something which is very important ", 
     smallBold)); 

    addEmptyLine(preface, 8); 

    preface.add(new Paragraph("This document is a preliminary version and not subject to your license agreement or any other agreement with vogella.com ;-).", 
     redFont)); 

    document.add(preface); 
    // Start a new page 
    document.newPage(); 
    } 

    private static void addContent(Document document) throws DocumentException { 
    Anchor anchor = new Anchor("First Chapter", catFont); 
    anchor.setName("First Chapter"); 

    // Second parameter is the number of the chapter 
    Chapter catPart = new Chapter(new Paragraph(anchor), 1); 

    Paragraph subPara = new Paragraph("Subcategory 1", subFont); 
    Section subCatPart = catPart.addSection(subPara); 
    subCatPart.add(new Paragraph("Hello")); 

    subPara = new Paragraph("Subcategory 2", subFont); 
    subCatPart = catPart.addSection(subPara); 
    subCatPart.add(new Paragraph("Paragraph 1")); 
    subCatPart.add(new Paragraph("Paragraph 2")); 
    subCatPart.add(new Paragraph("Paragraph 3")); 

    // add a list 
    createList(subCatPart); 
    Paragraph paragraph = new Paragraph(); 
    addEmptyLine(paragraph, 5); 
    subCatPart.add(paragraph); 

    // add a table 
    createTable(subCatPart); 

    // now add all this to the document 
    document.add(catPart); 

    // Next section 
    anchor = new Anchor("Second Chapter", catFont); 
    anchor.setName("Second Chapter"); 

    // Second parameter is the number of the chapter 
    catPart = new Chapter(new Paragraph(anchor), 1); 

    subPara = new Paragraph("Subcategory", subFont); 
    subCatPart = catPart.addSection(subPara); 
    subCatPart.add(new Paragraph("This is a very important message")); 

    // now add all this to the document 
    document.add(catPart); 

    } 

    private static void createTable(Section subCatPart) 
     throws BadElementException { 
    PdfPTable table = new PdfPTable(3); 

    // t.setBorderColor(BaseColor.GRAY); 
    // t.setPadding(4); 
    // t.setSpacing(4); 
    // t.setBorderWidth(1); 

    PdfPCell c1 = new PdfPCell(new Phrase("Table Header 1")); 
    c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
    table.addCell(c1); 

    c1 = new PdfPCell(new Phrase("Table Header 2")); 
    c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
    table.addCell(c1); 

    c1 = new PdfPCell(new Phrase("Table Header 3")); 
    c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
    table.addCell(c1); 
    table.setHeaderRows(1); 

    table.addCell("1.0"); 
    table.addCell("1.1"); 
    table.addCell("1.2"); 
    table.addCell("2.1"); 
    table.addCell("2.2"); 
    table.addCell("2.3"); 

    subCatPart.add(table); 

    } 

    private static void createList(Section subCatPart) { 
    List list = new List(true, false, 10); 
    list.add(new ListItem("First point")); 
    list.add(new ListItem("Second point")); 
    list.add(new ListItem("Third point")); 
    subCatPart.add(list); 
    } 

    private static void addEmptyLine(Paragraph paragraph, int number) { 
    for (int i = 0; i < number; i++) { 
     paragraph.add(new Paragraph(" ")); 
    } 
    } 
} 
+1

die frage war ein existenter anzusehen oder es einzubetten –

11

I PDF JS JavaScript-Bibliothek empfehlen die Verwendung.

Erstellen Sie ein WebView und laden Sie statisch den html/javascript-Inhalt dieser javascript pdf viewer example project. Erstellen Sie eine Funktion in Javascript, an die Sie das anzuzeigende PDF-Byte-Array senden können.

So ist die ganze Logik des PDF-Viewers bereits da. Sie können sogar die Viewer-HTML ändern, um einige Funktionen dort zu entfernen.

Seien Sie auch vorsichtig über JPedalFX, da ich es nicht zuverlässig in Fällen fand, in denen es Bilder rendern musste, die der pdf-Datei hinzugefügt wurden. In meinem Fall konnte JPedalFX kein Diagramm Bild machen, die mit jfreechart generiert wurde

+1

Kannst du da noch etwas mehr ausarbeiten? – Tommo

1

Für einige Leute kann es ein Workaround sein, das PDF-Dokument in HTML zu konvertieren und es mit einem WebView anzuzeigen.

Das Open-Source-Befehlszeilenprogramm pdf2htmlEx produziert wirklich gut aussehende eigenständige HTML-Dateien mit eingebetteten Bildern und JavaScript.

5

Ok, hier sind meine 50 Cent. Zusätzlich zu @ALabrosik und @ReneEnriquez Antworten.

Herunterladen pdf.js dist und legen Sie sie unter 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 

Erstellen Sie die folgende fxml Datei

<?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> 
(Sie WebView in TabPane oder ähnliche Behälter Probleme zu vermeiden, mit Scroll-Unterstützung wickeln sollte)

Um zu verhindern, dass pdf.js die Demo-PDF-Datei beim Start öffnet, öffnen Sie web/viewer.js und löschen Sie DEFAULT_URL Wert.

var DEFAULT_URL = ''; 

öffnen web/viewer.html und fügen Sie Skriptblock:

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

Damit ist der Regler (siehe Code-Kommentaren zur Erläuterung).

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

Einige Pdf.js Funktionen funktionieren nicht: offene Datei (Ursache Pdf.js haben keinen Zugriff auf URL außerhalb JAR), Druck usw. entsprechenden Schaltflächen der Symbolleiste verbergen Sie die folgenden Zeilen zu Web hinzufügen. css:

#toolbarViewerRight { 
    display:none; 
} 

Das ist alles. Der Rest des Codes ist 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(); 
    } 
} 

Hoffen, dass dies jemand hilft.

+0

Vielen Dank für Ihre Erklärung und Ihre Beispiele! Ich habe es an meiner Bewerbung arbeiten lassen. Ich habe gerade einige Änderungen vorgenommen, weil relative ".." Links in JAR nicht funktionieren. Der Viewer funktionierte nicht, wenn alles gebündelt war. Ich habe einen schnellen Artikel erstellt, der weitgehend von Ihrem Kommentar mit meinen Änderungen inspiriert wurde: https://blog.samirhadzic.com/2017/02/09/show-pdf-in-your-application/ Vielen Dank! – Maxoudela

+0

Zeigen Sie Ihre 'Importe' für die' WebController' Klasse. – Sedrick