2016-11-03 73 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的大小绑定到场景的大小(这是由屏幕的大小决定的)。无论如何,当我打印时,我会自动将页面尺寸假定为标准信纸尺寸的纸张,并将图像缩放到正常打印纸张的页边空白处。所以根据节点开始的大小决定它的缩放量。 我给你在这里接受的答案,因为它似乎真的没有办法做我想做的。 –