2016-11-03 3 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)); 

이를 통해 그 파일을로드 PNG 파일로 내 컴퓨터에 해당 이미지를 절약 자바 FX WritableImage에 (스냅 샷을 통해) 차트를 변환하고있어 상당히 과도한 것 같다. 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)의 크기가 바인딩됩니다. 어쨌든, 내가 인쇄 할 때 자동으로 페이지 크기를 표준 레터 크기 용지로 가정하고 이미지를 일반 용지의 여백에 맞게 조정합니다. 따라서 노드의 크기에 따라 시작하여 노드의 크기를 결정합니다. 내가 원하는 것을 실제로 할 수있는 방법이 없기 때문에 여기에 답을 들려주었습니다. –