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.
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.
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.
Als Test habe ich eine Example
Klasse erstellt, die Funktion example_01
gibt einmal die CSV Version aus:
Und natürlich auch die visuelle Version für Excel:
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 ());
}
}
}
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.
Erstes Release, ist im Produktionseinsatz und bisher keine Beschwerden.
Download VGW Production Version - 20221029081207
Bugfixes, CellStyles, CellLinks