在JavaFX
中开发需要显示pdf的桌面应用程序。我读到JavaFX
(当前版本)中不支持pdf查看/显示,我也读到了JPedal
。
现在,问题:
JPedal
)如何将其嵌入我的应用程序中。 答案 0 :(得分:12)
JPedalFX示例代码和用法
使用JPedalFX的示例代码随JPedalFX download提供。
对我来说有点蹩脚,但我只是在这里粘贴从JPedalFX库提供的示例查看器中复制的代码片段示例代码。代码依赖于JPedalFX发行版中包含的jpedal_lgpl.jar文件,该文件位于类路径(或应用程序jar清单中引用的库路径)上。
如果您对JPedalFX的使用有任何疑问,我建议您contact IDR solutions directly(他们过去一直对我做出回应)。
// 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渲染器
另外,我过去使用旧的基于SwingLabs Swing的pdf渲染器和JavaFX来渲染我的JavaFX web browser的pdf。虽然Swing / JavaFX集成在我开发浏览器时并不是JavaFX的支持功能,但它仍然适用于我。集成代码位于PDFViewer.java和BrowserWindow.java。
请注意,Java 2.2支持embedding JavaFX in a Swing app,Java 8支持embedding a Swing app in JavaFX。
答案 1 :(得分:11)
我建议使用PDF JS javascript库。
创建一个WebView并静态加载此javascript pdf viewer example project的html / javascript内容。在javascript中创建一个函数,您可以向其发送要显示的pdf字节数组。
这样,pdf查看器的所有逻辑都已存在。您甚至可以修改查看器html以删除其中的某些功能。
还要注意 JPedalFX ,因为我发现它必须渲染添加到pdf文件中的图像时不可靠。在我的情况下,JPedalFX无法渲染使用jfreechart
生成的图表图像答案 2 :(得分:9)
好的,这是我的50美分。除了@ALabrosik和@ReneEnriquez答案。
下载pdf.js dist并将其放在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
创建以下fxml文件(您应该在 TabPane 或类似的容器中包装 WebView 以避免滚动支持的问题)
<?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>
要阻止pdf.js在启动时打开演示pdf文件,请打开web/viewer.js
并清除DEFAULT_URL
值。
var DEFAULT_URL = '';
打开web/viewer.html
并添加脚本块:
<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>
现在是控制器(请参阅代码注释以获得解释)。
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();
}
});
}
}
某些pdf.js函数不起作用:打开文件(因为pdf.js无法访问JAR之外的URL),打印等。要隐藏相应的工具栏按钮,可以将以下行添加到web.css:
#toolbarViewerRight {
display:none;
}
这就是全部。其余的代码是微不足道的。
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();
}
}
希望这对某人有帮助。
答案 3 :(得分:2)
尝试JPedalFX在他们的网站上声明“JPedalFX是一个基于JavaFX 2的轻量级PDF查看器和JPedal的LGPL版本。它具有简单的界面,旨在快速方便地查看PDF文档。”< / p>
http://www.idrsolutions.com/jpedalfx-viewer/
尚未尝试但希望有所帮助
答案 4 :(得分:1)
您也可以尝试使用iText,我在java中使用它 A tutorial about how to use it
答案 5 :(得分:1)
对于某些人来说,将PDF文档转换为HTML并使用WebView显示它可能是一种解决方法。
开源命令行工具pdf2htmlEx生成非常漂亮的独立HTML文件,其中嵌入了图像和JavaScript。
答案 6 :(得分:0)
ICEPDF非常易于使用,免费且轻量级。我最近用它为我的公司制作了一个小的PDF索引应用程序;)
答案 7 :(得分:0)
我用Web视图和pdf.js写了一个非常简单的例子,这是GitHub上提供的源代码:
https://github.com/enriquezrene/curso-javafx-udemy/tree/master/clase-17/curso-javafx
享受它!!!
答案 8 :(得分:-1)
import android.support.v4.app.Fragment;
...
public class BottomPictureFragment extends Fragment { ... }