JavaFX JavaFX Chart in Apache Poi Excel Datei

Hallo zusammen

Ich will aus einer BarChart eine Image erstellen und die direkt in eine Excel includen. Ich habe unten ein Code Beispiel, bekomme es nicht zum Laufen. kann mir mal jemand sagen was ich da falsch gemacht habe?

Code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class BarChartSample extends Application {
    final static String austria = "Austria";

    final static String brazil = "Brazil";

    final static String france = "France";

    final static String italy = "Italy";

    final static String usa = "USA";

    @Override
    public void start(Stage stage) {
        stage.setTitle("Bar Chart Sample");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final BarChart<String, Number> bc = new BarChart<>(xAxis, yAxis);
        bc.setTitle("Country Summary");
        xAxis.setLabel("Country");
        yAxis.setLabel("Value");

        XYChart.Series series1 = new XYChart.Series();
        series1.setName("2003");
        series1.getData().add(new XYChart.Data(austria, 25601.34));
        series1.getData().add(new XYChart.Data(brazil, 20148.82));
        series1.getData().add(new XYChart.Data(france, 10000));
        series1.getData().add(new XYChart.Data(italy, 35407.15));
        series1.getData().add(new XYChart.Data(usa, 12000));

        XYChart.Series series2 = new XYChart.Series();
        series2.setName("2004");
        series2.getData().add(new XYChart.Data(austria, 57401.85));
        series2.getData().add(new XYChart.Data(brazil, 41941.19));
        series2.getData().add(new XYChart.Data(france, 45263.37));
        series2.getData().add(new XYChart.Data(italy, 117320.16));
        series2.getData().add(new XYChart.Data(usa, 14845.27));

        XYChart.Series series3 = new XYChart.Series();
        series3.setName("2005");
        series3.getData().add(new XYChart.Data(austria, 45000.65));
        series3.getData().add(new XYChart.Data(brazil, 44835.76));
        series3.getData().add(new XYChart.Data(france, 18722.18));
        series3.getData().add(new XYChart.Data(italy, 17557.31));
        series3.getData().add(new XYChart.Data(usa, 92633.68));

        Scene scene = new Scene(bc, 800, 600);
        bc.getData().addAll(series1, series2, series3);

        bc.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                try {
                    XSSFWorkbook my_workbook = new XSSFWorkbook();
                    XSSFSheet my_sheet = my_workbook.createSheet("MyLogo");
                    WritableImage bImage = bc.snapshot(new SnapshotParameters(), null);
                    int width = (int) bImage.getWidth();
                    int height = (int) bImage.getHeight();
                    byte[] pixelBytes = new byte[width * height * 4];
                    int my_picture_id = my_workbook.addPicture(pixelBytes, Workbook.PICTURE_TYPE_PNG);
                    XSSFDrawing drawing = my_sheet.createDrawingPatriarch();
                    XSSFClientAnchor my_anchor = new XSSFClientAnchor();
                    my_anchor.setCol1(2);
                    my_anchor.setRow1(1);
                    XSSFPicture my_picture = drawing.createPicture(my_anchor, my_picture_id);
                    my_picture.resize();
                    FileOutputStream out = new FileOutputStream(new File("C:\\test.xlsx"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
StackTrace:
Code:
Exception in thread "JavaFX Application Thread" java.util.NoSuchElementException
    at javax.imageio.spi.FilterIterator.next(ServiceRegistry.java:836)
    at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:528)
    at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:513)
    at org.apache.poi.ss.util.ImageUtils.getImageDimension(ImageUtils.java:64)
    at org.apache.poi.xssf.usermodel.XSSFPicture.getImageDimension(XSSFPicture.java:278)
    at org.apache.poi.xssf.usermodel.XSSFPicture.getPreferredSize(XSSFPicture.java:203)
    at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:170)
    at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:152)
    at util.BarChartSample$1.handle(BarChartSample.java:92)
    at util.BarChartSample$1.handle(BarChartSample.java:1)
Quelle: http://thinktibits.blogspot.com/2012/12/Excel-XLSX-Insert-PNG-JPG-Image-Java-POI-Example.html

Grüße
lam

P.S. kann man diesen Thread noch in JavaFX Kategorie verschieben?
 
Zuletzt bearbeitet:
Zwei Dinge die mir aufgefallen sind:
1. Du befüllst das byte Array nirgends. Ich persönlich würde das Bild aber auch wie folgt zu einem byte Array machen:
Java:
WritableImage image = bc.snapshot(...);

byte[] pixelBytes = null;
BufferedImage bImage = SwingFXUtils.fromFXImage(image, null);
try(ByteArrayOutputStream s = new ByteArrayOutputStream()) {
    ImageIO.write(bImage, "png", s);
    pixelBytes = s.toByteArray();
}

int my_picture_id = my_workbook.addPicture(pixelBytes, ..);
2. Du hast am Ende vergessen, den Outputstream in das Workbook zu schreiben. (siehe deine Quelle)
Java:
FileOutputStream out = new FileOutputStream(new File("C:\\test.xlsx"));
my_workbook.write(out);
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben