2016-11-03 106 views
1

我需要能夠將節點添加到PDF文檔。目前我正在將所有節點轉換爲FX可寫圖像,然後將該圖像加載到iText7中以創建PDF文件。JavaFX&iText7

例如:說我有一個JavaFX BarChart,我需要將該BarChart添加到PDF文件。目前我通過

com.itextpdf.layout.element.Image image = new com.itextpdf.layout.element.Image(ImageDataFactory.create(myLocation)); 

這是保存圖像圖表(通過快照),以一個JavaFX WritableImage轉換成我的電腦爲PNG文件,然後加載該文件對我來說似乎很有點過分。如果有任何iText技術人員看到這一點,我會非常感謝回覆。

總之(總之)我想要一種方式直接添加一個FX節點到PDF文件。如果有比iText更好的解決方案來做這件事,我就會全神貫注。

感謝

回答

2

你可以做

javafx.scene.image.Image fxImage = chart.snapshot(null, null); 
java.awt.Image awtImage = SwingFXUtils.fromFXImage(fxImage); 
com.itextpdf.layout.element.Image pdfImage = 
    new com.itextpdf.layout.element.Image(ImageDataFactory.create(awtImage, null)); 

SSCCE:

import java.io.File; 
import java.io.FileOutputStream; 
import java.util.Random; 

import com.itextpdf.io.image.ImageData; 
import com.itextpdf.io.image.ImageDataFactory; 
import com.itextpdf.kernel.pdf.PdfDocument; 
import com.itextpdf.kernel.pdf.PdfWriter; 
import com.itextpdf.layout.Document; 

import javafx.application.Application; 
import javafx.embed.swing.SwingFXUtils; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.chart.BarChart; 
import javafx.scene.chart.CategoryAxis; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart.Data; 
import javafx.scene.chart.XYChart.Series; 
import javafx.scene.control.Button; 
import javafx.scene.image.Image; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.FileChooser; 
import javafx.stage.FileChooser.ExtensionFilter; 
import javafx.stage.Stage; 

public class ITextTest extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     BarChart<String, Number> chart = new BarChart<>(new CategoryAxis(), new NumberAxis()); 
     Random rng = new Random(); 
     Series<String, Number> series = new Series<>(); 
     series.setName("Data"); 
     for (int i = 1 ; i<=10; i++) { 
      series.getData().add(new Data<>("Group "+i, rng.nextDouble())); 
     } 
     chart.getData().add(series); 

     Button save = new Button("Save to pdf"); 
     FileChooser chooser = new FileChooser(); 
     chooser.getExtensionFilters().add(new ExtensionFilter("PDF files", "*.pdf")); 
     save.setOnAction(e -> { 
      File file = chooser.showSaveDialog(primaryStage); 
      if (file != null) { 
       try { 
        Image img = chart.snapshot(null, null); 
        ImageData imgData = ImageDataFactory.create(SwingFXUtils.fromFXImage(img, null), null); 
        com.itextpdf.layout.element.Image pdfImg = new com.itextpdf.layout.element.Image(imgData); 

        PdfWriter writer = new PdfWriter(new FileOutputStream(file)); 
        PdfDocument pdfDoc = new PdfDocument(writer); 
        Document doc = new Document(pdfDoc); 
        doc.add(pdfImg); 
        doc.close(); 
       } catch (Exception exc) { 
        exc.printStackTrace(); 
       }    
      } 
     }); 

     BorderPane.setAlignment(save, Pos.CENTER); 
     BorderPane.setMargin(save, new Insets(10)); 
     BorderPane root = new BorderPane(chart, null, null, save, null); 

     Scene scene = new Scene(root, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 


    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

因此,這使得過程簡單一點buuuuut保存圖像通過快照PDF嚴重,使打印輸出看起來就像是從90年代大聲笑。這就是爲什麼我想要一種直接添加節點的方式。 –

+0

@PhilipVaughn嘗試創建比您需要的尺寸大2或4倍的節點,然後縮小圖像尺寸。 –

+0

我也一直在努力。節點的大小很明顯是由屏幕大小決定的,所以我實際上結束了將tableview的大小綁定到場景的大小(這是由屏幕的大小決定的)。無論如何,當我打印時,我會自動將頁面尺寸假定爲標準信紙尺寸的紙張,並將圖像縮放到正常打印紙張的頁邊空白處。所以根據節點開始的大小決定它的縮放量。 我給你在這裏接受的答案,因爲它似乎真的沒有辦法做我想做的。 –