Versatile Grid Writer

Der Versatile Grid Writer (VGW) ist eine Java Library mit der man zwei dimensionale Daten in CSV und/oder in XML SpreedSheet Dateien exportieren kann.

Historie

Ich habe leider 6 Monate mit der Apache POI rumexperimentiert, um die Daten aus meinem anderen Projekt zu exportieren. Dabei handelt es sich um gewaltige Datenmengen von über 1 Million Zeilen und über 100 Spalten. Die von mir damals eingesetzte Library war nicht dafür gedacht, was ich dann später erst merkte als es zu spät war. Mit einem Speicherverbrauch von knapp 120 GB um eine 10 MB große Exceldatei zu erstellen und noch 2 Minuten darauf zu warten erschien mir nicht zielführend.

Ich habe das dann irgendwann abgebrochen und meine eine Library gebaut, nämlich diese hier. Seit dem habe ich keine Probleme mehr.

Es gibt bereits verschiedene Libraries die so etwas schon tun, die hatten aber alle immer irgendwo ein Haken, der mir nicht gefallen hatte, und auch nicht zu meinen Anforderungen gepasst hatte. In der Konsequent bleibt einem nur über, das was man braucht, selbst umzusetzen.

Funktionsweise

Die Library trennt die Daten und den Header sowie die Styles voneinander. Die Bereiche werden erst bei einem Export zusammen verknüpft. Damit lassen sich am Ende konsistente zwischen den Formaten gleiche Reports aufbauen, ohne das man irgendetwas doppelt Programmieren müsste.

Das bedeutet, man erstellt ein Daten-Objekt, welches nur die Daten beinhaltet. Weiterhin erstellt man ein Header-Objekt, welches nur den Header beinhaltet. Dieser kann dann auch Styles beinhalten, also Hintergrundfarben, Rahmen, Fonts und so weiter.

Beim Export übergibt man dann einfach nur noch die Daten und den Header, dabei spielt das Format dann keine Rolle mehr. Somit können die Daten auch mehrfach exportiert werden in verschiedene Dateiformate gleichzeitig.

Beispiel

Als Test habe ich eine Example Klasse erstellt, die Funktion example_01 gibt einmal die CSV Version aus:

Example 01 - CSV - Text Example 01 - CSV - Excel

Und natürlich auch die visuelle Version für Excel:

Example 01 - XML - Text

Und hier der Code dazu:

package net.whurst.util.vgw;

import org.junit.jupiter.api.Test;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

import static org.junit.jupiter.api.Assertions.*;

public class Examples {

	@Test
	void example_01 () {

		int groupIndex;
		Header header = new Header ();
		GridData gridData = new GridData ();
		Style columnStyle;

		// Header definieren mit allen Styles, Farben und Fonts und allem
		Style titleStyle = new Style ();
		titleStyle.setBackgroundColor (280.0/360.0, 0.05, 1.0);
		titleStyle.setBorderBottom (true);
		titleStyle.setFontName (Style.FONT_NAME.ARIAL);
		titleStyle.setFontSize (14);
		titleStyle.setFontBold (true);
		titleStyle.setIndent (3);
		titleStyle.setVerticalAlignment (Style.VERTICAL_ALIGNMENT.MIDDLE);
		header.setTitle ("Example 01 - Devices And Interfaces", titleStyle);

		// Wir setzen für alle Gruppen Header die Defaults
		Style groupHeaderStyle = new Style ();
		groupHeaderStyle.setHorizontalAlignment (Style.HORIZONTAL_ALIGNMENT.CENTER);
		groupHeaderStyle.setFontName (Style.FONT_NAME.CALIBRI);
		groupHeaderStyle.setFontSize (14);
		groupHeaderStyle.setFontBold (true);
		header.setGroupHeaderParentStyle (groupHeaderStyle);

		// Wir setzen für alle Spalten Header die Defaults
		Style columnHeaderStyle = new Style ();
		columnHeaderStyle.setHorizontalAlignment (Style.HORIZONTAL_ALIGNMENT.LEFT);
		columnHeaderStyle.setBorderBottom (true);
		columnHeaderStyle.setFontSize (11);
		columnHeaderStyle.setFontBold (true);
		header.setColumnHeaderParentStyle (columnHeaderStyle);

		// Wir setzen für alle Spalten die Defaults
		Style dataStyle = new Style ();
		dataStyle.setHorizontalAlignment (Style.HORIZONTAL_ALIGNMENT.LEFT);
		dataStyle.setFontName (Style.FONT_NAME.CALIBRI);
		dataStyle.setFontSize (11);
		dataStyle.setFontBold (false);
		header.setGroupDataParentStyle (dataStyle);

		groupHeaderStyle = new Style ();
		groupHeaderStyle.setBackgroundColor (0.1, 0.2, 1.0);

		columnStyle = new Style ();
		columnStyle.setBackgroundColor (0.1, 0.1, 1.0);

		groupIndex = header.addGroup ("DEVICE", "Device", groupHeaderStyle, columnStyle);
		header.addColumn (groupIndex, "NAME", "Name", null, null);
		header.addColumn (groupIndex, "TYPE", "Type", null, null);

		groupHeaderStyle = new Style ();
		groupHeaderStyle.setBackgroundColor (0.2, 0.2, 1.0);

		columnStyle = new Style ();
		columnStyle.setBackgroundColor (0.2, 0.1, 1.0);

		groupIndex = header.addGroup ("INTERFACE", "Interface Data", groupHeaderStyle, columnStyle);
		header.addColumn (groupIndex, "DESC", "Description", null, null);
		header.addColumn (groupIndex, "SPEED", "Speed", null, null);
		header.addColumn (groupIndex, "STATE", "Status", null, null);

		// Phantasie Daten erstellen
		gridData.addCell ("MERKUR"); gridData.addCell ("Linux"); gridData.addCell ("eno1");
		gridData.addCell ("10000"); gridData.addCell ("UP/UP"); gridData.nextLine ();

		gridData.addCell ("MERKUR"); gridData.addCell ("Linux"); gridData.addCell ("eno2");
		gridData.addCell ("10000"); gridData.addCell ("UP/down"); gridData.nextLine ();

		gridData.addCell ("MERKUR"); gridData.addCell ("Linux"); gridData.addCell ("eno3");
		gridData.addCell ("0"); gridData.addCell ("down/down"); gridData.nextLine ();

		gridData.addCell ("NEPTUN"); gridData.addCell ("FreeBSD"); gridData.addCell ("fpx0");
		gridData.addCell ("1000"); gridData.addCell ("down/UP"); gridData.nextLine ();

		gridData.addCell ("NEPTUN"); gridData.addCell ("FreeBSD"); gridData.addCell ("fpx1");
		gridData.addCell ("1000"); gridData.addCell ("UP/UP"); gridData.nextLine ();

		gridData.addCell ("PLUTO"); gridData.addCell ("FreeBSD"); gridData.addCell ("fpx0");
		gridData.addCell ("1000"); gridData.addCell ("UP/UP"); gridData.nextLine ();

		gridData.addCell ("GECKO"); gridData.addCell ("Windows 10"); gridData.addCell ("lan0");
		gridData.addCell ("10000"); gridData.addCell ("UP/UP"); gridData.nextLine ();

		gridData.addCell ("GECKO"); gridData.addCell ("Windows 10"); gridData.addCell ("wlan0");
		gridData.addCell ("155"); gridData.addCell ("UP/UP"); gridData.nextLine ();

		gridData.addCell ("FALCON"); gridData.addCell ("QNAP"); gridData.addCell ("eth0");
		gridData.addCell ("1000"); gridData.addCell ("UP/UP"); gridData.nextLine ();

		// XML konfigurieren
		ConfigurationXml configurationXml = new ConfigurationXml ();
		configurationXml.setSheetName ("InterfaceList");
		configurationXml.setGenerateGroupHeaderBorderOnly (true);

		// CSV konfigurieren
		ConfigurationCsv configurationCsv = new ConfigurationCsv ();

		// Jetzt die Dateien schreiben
		try {
			File tempDir = new File ("temp");
			tempDir.mkdir ();

			FileOutputStream fileOutputStreamXML = new FileOutputStream ("temp/example_01.xml");
			Writer.write (configurationXml, header, gridData, fileOutputStreamXML);

			FileOutputStream fileOutputStreamCSV = new FileOutputStream ("temp/example_01.csv");
			Writer.write (configurationCsv, header, gridData, fileOutputStreamCSV);

			assertTrue (true);

		} catch (Exception e) {
			fail (e.getLocalizedMessage ());
		}
	}
}

Downloads

Die Pakete beinhalten das JAR, JavaDocs, alle Unit-Tests und die Beispiele, es gibt auch Anfänge einer Klassen-Dokumentation, aber da fehlt mir die Zeit.

Version main-20221029081207

Erstes Release, ist im Produktionseinsatz und bisher keine Beschwerden.

Download VGW Production Version - 20221029081207

Version main-20231003022321

Bugfixes, CellStyles, CellLinks

Download VGW Production Version - 20231003022321