Blog

Kontakt

E-Mail:
info@capcom.de

   
Gefiltert nach Kategorie Tipps & Tricks Filter zurücksetzen

Vom Spreadsheet nach JSON - Daten für den Browser lesbar machen

25. September 2023, CAPCom WebTeam - Tipps & Tricks

 

Wer kleine und mittlere Webanwendungen erstellt, kennt die Situation: Auf die Frage, wie die zu verarbeitenden Daten vorliegen, bekommt man eine Arbeitsmappe im MS Excel-Format. Darin wurden die Daten bislang gepflegt, und das soll auch so bleiben. Gesucht ist also ein Weg, die Spreadsheet-Daten in ein Format zu überführen, das Browser nativ verstehen, und der möglichst wenig Arbeit bereitet, besonders im Hinblick auf spätere Aktualisierungen der Daten. Hier beschreiben wir einen effizienten Weg zu einer JSON (JavaScript Object Notation)-Datei, die man dann in die Anwendung AJAXen kann.

Ausgangspunkt
Als Beispiel nehmen wir einen Produktkatalog(auszug), der Felder wir Produktnummer, Name, Kategorie und für jedes Produkt ein bin vier Varianten mit Bezeichnung und Code enthält. Der Katalog umfasst 500 Zeilen, das erfordert noch keinen Datenbankserver, ist aber definitiv zu viel für reine Handarbeit.

Werkzeuge
Gebraucht wird erstens ein Programm, das Excel-Arbeitsmappen nach CSV exportieren kann. Wir geben LibreOffice Calc den Vorzug, weil es auf Wunsch CSV erzeugt, in dem jeder Zelleninhalt in Anführungszeichen eingeschlossen ist. Für die Weiterverarbeitung ist es wichtig, dass die Inhalte die gleiche Form haben. Mit Microsoft Excel bekommt man das auch hin, aber nur durch Einsatz eines Makros.
Zweitens wird ein Texteditor benötigt, der Suchen und Ersetzen mit regulären Ausdrücken auf einen ganzen Bereich (aber nur einmal in jeder Zeile!) anwenden kann. Wer sich mit Vi Improved anfreunden kann, findet darin ein mächtiges Werkzeug. Wer mit Linux arbeitet, kann einfach sed verwenden. Es empfiehlt sich, die Schreibweise, die das gewählte Werkzeug für reguläre Ausdrücke verwendet, nachzuschlagen. Insbesondere Verweise auf gefundene Teilausdrücke werden unterschiedlich notiert. Die Beispiele hier beziehen sich auf Vi Improved, für sed wäre die Bereichsangabe "1,$" wegzulassen.

Der Auftakt: CSV exportieren
Wie angesprochen, soll das resultierende CSV jeden Zelleninhalt in Anführungszeichen einschließen. Das Trennzeichen ist relativ beliebig, unsere Beispiele beziehen sich auf den bei LibreOffice üblichen senkrechten Strich „|“. Die Zeichenkodierung sollte UTF-8 sein. Die Titelzeile wird aus dem Export entfernt.
Wenn die Arbeitsmappe mehrere Blätter umfasst, können diese in separate CSVs exportiert, getrennt umgebaut und später in eine gemeinsame Datei gepackt werden.

CSV schrittweise zu JSON umbauen
Ein dem Spreadsheet entsprechendes JSON-Objekt enthält ein Array von Objekten, die jeweils die Spaltenköpfe als Schlüssel und die Zellinhalte als Werte enthalten. Da wollen wir also hin. Die Werte sehen nach dem Export schon fast richtig aus, aber die Schlüssel und die Struktur fehlen noch. Hier kommt jetzt Suchen und Ersetzen zum Einsatz. Anfang und Ende der JSON-Notation ergänzen wir zum Schluss, dann müssen wir keine Zeilen von der Bearbeitung ausschließen.

Als Erstes müssen wir uns um einen Spezialfall kümmern: Anführungszeichen, die in den Zellinhalten vorkommen. Der Export hat diese verdoppelt, für JSON müssen sie aber maskiert werden. Als zusätzliche Schwierigkeit können diese doppelten Anführungszeichen direkt benachbart zu einer Feldgrenze auftreten, daher verwenden wir eine ganze Serie von Ersetzungen:

1,$s/"""$/\\""|/
1,$s/"""|/\\""|/
1,$s/^"""/"\\"|/
1,$s/|"""/|"\\"/
1,$s/\([^|\\]\)""/\1\\"/g

Jetzt beginnen den Einbau der Feldschlüssel damit, den Beginn des Objekts und den ersten Feldschlüssel an die Zeilenanfänge zu setzen. Für den Editor formulieren wir das als Ersetzen des Zeilenanfangs, das auf alle Zeilen der Datei angewendet wird:

1,$s/^/ { “prodNummer”: /

Dann kommen die weiteren Felder der Zeile an die Reihe. Da die Werte alle mit Anführungszeichen beginnen und enden und zwischen ihnen Trennzeichen stehen, können wir nach der Sequenz „|” suchen. Hier wird wichtig, dass der Editor die folgende Änderung zwar auf alle Zeilen anwendet, aber nur auf das erste Auftreten in jeder Zeile. Die genannten Werkzeuge machen das so (wenn man sie nicht anders anweist). Also:

1,$s/”|”/”, “prodName”: /

Das können wir nun für jede Spalte wiederholen. Um der Anwendung die Arbeit zu erleichtern, wollen wir aber die bis zu vier Produktvarianten als Array kodieren. Daher schließen wir beim Einfügen der ersten Variantenspalte den Beginn eines Arrays und eines Objekts mit ein:

1,$s/”|”/”, [ { “variantenCode”: /

Und bei der ersten Spalte der zweiten Variante muss zusätzlich das erste Objekt abgeschlossen werden:

1,$s/”|”/” }, { “variantenCode”: /

Wenn nicht alle Produkte die maximale Anzahl von Varianten haben, bleiben in der Zeile Trennzeichen stehen, die von den Ersetzungen nicht erfasst wurden. Die entfernen wir jetzt, bevor die Zeile abgeschlossen wird, denn dann stehen sie leicht adressierbar am Ende:

1,$s/|*$//

In unserem Beispiel kann das Abschließen des letzten Objekts und des Varianten-Arrays mit dem Abschluss der Datenzeile zusammen erfolgen. Hier zielen wir auf das Zeilenende (das abschließende Komma wird benötigt, weil die Datenzeilen ja den Inhalt eines Arrays bilden):

1,$s/$/ } ] },/

Abschließende Änderungen
Jetzt sind alle Zeilen umgebaut, aber noch ist das Ergebnis kein korrektes JSON, was ja genau ein Objekt beschreibt. Daher fügen wir jetzt noch am Anfang und am Ende die große Klammer ein. Vor den Anfang setzen wir:

{ “produktDaten”: [

Indem wir die Daten an einen Schlüssel hängen (anstatt ein anonymes Array als äußerste Struktur zu verwenden), ermöglichen wir, auch noch weitere Datenpakete in dieselbe Datei zu packen, das kommt oft genug vor, um hier vorzusorgen.
Von der letzten Zeile muss noch das abschließende Komma entfernt werden, das ist in JSON, im Gegensatz zu JavaScript, nicht erlaubt:

$s/,$//

Dann wird noch der Schluss von Array und Objekt eingefügt:

] }

Damit ist die Konvertierung abgeschlossen. Der resultierenden Datei sollte man noch die Endung .json geben.

Prüfen kann man das Resultat übrigens einfach, indem man die Datei im Browser öffnet. Der zeigt dann die Objektstruktur an – oder eben eine Fehlermeldung.

Der ganze Prozess liest sich kompliziert, aber jede einzelne Anweisung baut alle Datenzeilen um, in unserem Fall also ein gutes Dutzend Kommandos für 500 Zeilen. Das lohnt sich dann schon, selbst wenn man vielleicht manchen regulären Ausdruck mehrmals testen muss. Es empfiehlt sich, die erfolgreiche Sequenz von Anweisungen zu notieren, denn die nächste Version der Arbeitsmappe kommt bestimmt, und dann geht die Konvertierung schnell von der Hand.


Excel Funktion: Durchsuchbare DropDowns

26. Juli 2023, CAPCom WebTeam - Tipps & Tricks

 

In diesem Video stellen wir Ihnen eine "neues" Excel Feature vor, welches Ihre Dateneingabe und -auswahl in Excel erheblich vereinfachen wird. Keine endlosen Scrollaktionen mehr in langen Listen, kein Übersehen des gesuchten Eintrags mehr, endlich direkt zu dem gewünschten Eintrag springen.

Auch zeigen wir Ihnen wie Sie das Feature aktivieren können, für den Fall, dass dies bei Ihnen noch nicht geschehen ist und welche Excel Version Sie benötigen. Dies Feature ist nämlich erst ab der Version 2021 bzw. 365 von Excel freischaltbar.

Für Rückfragen und Anmerkungen können Sie uns gerne einen Kommentar hinterlassen! Danke Für Ihr Interesse!

 
Wenn Sie das Video abspielen, sendet YouTube Ihnen einige Cookies!


Mehrere Excel-Dateien in PDF "drucken"

23. Juni 2023, CAPCom WebTeam - Tipps & Tricks

 

Wer regelmäßig mehrere Excel-Sheets (mit mehreren Tabellenblättern) in PDF-Dokumente zusammenfassen möchte, für den haben wir hier etwas: Ein kleines VBA Makro, dass das Erzeugen von PDFs aus mehreren Excels erleichtert.

Das Problem

Wir standen aktuell vor der Aufgabenstellung, dass wir mehrmals im Quartal einen Bericht über den Verlauf einer Dokumentation abgeben sollten. Für die Dokumentation haben wir uns für eine Excelstruktur entschieden.

Um nun nicht für jeden Zwischenbericht etliche Excel-Sheets ausdrucken zu müssen (Stichwort Green-IT und Kostenreduktion) haben wir uns für die PDF-Variante entschieden. Was für die Papierform noch einfach geht (alles Markieren -> rechte Maustaste -> Drucken) geht für die PDF-Version schon nicht mehr so einfach. Nach kurzer Suche in Excel und im Netz stellte sich raus: Ein Makro muss her! Leider haben wir auf Anhieb kein funktionierendes gefunden. Also haben wir kurzerhand selbst eines geschrieben.

Das VBA Makro

Mit diesem VBA Makro müsst Ihr nicht mehr jedes einzelne Excel zum Drucken oder Veröffentlichen öffnen und es wird auch nicht mehr gefragt ob man die Änderungen speichern möchte, nur weil man den "Drucker" auf PDF umgestellt hat.

Das VBA Makro funktioniert in allen Excel Versionen ab 2010.

 
Sub AlleDrucken()
    'Aus welchen Zellen werden die Informationen bezogen
    'Verbessert die Struktur des Excel-Makros, eigene Modifikatioen sind leichter einzupflegen
    Const z_Pfad As String = "C3"      
      'in dieser Zelle stehen die Angaben zum Pfad, an welcher Stelle die Quell Excels liegen
    Const z_Filter As String = "C4"    
      'in dieser Zelle stehen die Angaben zum Filter, welcher eine Einschränkung der betrachteten Dateien ermöglicht
    Const z_Endung As String = "C5"    
      'in dieser Zelle stehen die Angaben zur Endung der Quelldatei   

    'Konstante
    Const c_OutOrdnerName As String = "PDF"
      'Hier kann der Name eingestellt werden wie der Zielordner heißen soll + Datum und Uhrzeit

    'Variablen
    Dim v_AktuelleDatei As String      
      'Name der aktuelle Datei
    Dim v_Output As String              
      'Pfad der für die Ausgabe der PDFs zusammen gebaut wird
    Dim v_OutOrdner As String          
      'Name des neu anzulegenden Ordners (im Quellordner) für die Ausgabe 

    'Main
    Application.ScreenUpdating = False 
      'schaltet die Aktualisierung des Inhalts der Excel ab
    v_OutOrdner = "PDF_" & Format(Time, "YYYYMMDD-hhmmss") & "\"
      'ergänzt den Zielordner um das aktuelle Datum und Uhrzeit   
    MkDir (Range(z_Pfad).Value & v_OutOrdner)
      'Erstellt den Ordner für die Ausgabe im Quellverzeichnis

    v_AktuelleDatei = Dir(Range(z_Pfad).Value & Range(z_Filter).Value & Range(z_Endung).Value)
      'Gibt den ersten Dateinamen wieder, der auf die angegebenen Filterkriterien passt

    While v_AktuelleDatei <> ""
      'Eine Schleife die so lange läuft bis kein weiteres Excel mehr auf die Filterkriteren zutrifft
         OutFile = Range(z_Pfad).Value & v_OutOrdner & Replace(v_AktuelleDatei, Range(z_Endung).Value, ".pdf")
           'Pfad und Endung für die Ausgabe der Datei werden angepasst       
         Workbooks.Open Filename:=Range(z_Pfad).Value & v_AktuelleDatei, UpdateLinks:=False
           'Öffnen der zu druckenden Excel ohne den Inhalt zu aktualisieren
         ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:=OutFile
           'Export der Excels als PDF. Hier wären auch alternative "Druck" bzw Export Optionen einzustellen
         ActiveWorkbook.Close savechanges:=False
           'Excel ohne zu speichern schließen
         v_AktuelleDatei = Dir
           'Übergibt den Dateinamen der nächsten Excel die auf die Filterkriterien zutrifft

   Wend

   Application.ScreenUpdating = True
      'Ab hier werden Änderungen in der Excel wieder angezeigt
End Sub
 

Das Excel

Wichtig wäre noch zu erwähnen, dass der Pfad (C3) mit einem "\" enden sollte. Das Layout könnt Ihr dank z_Pfad, z_Filter und z_Endung leicht nach eurem Geschmack anpassen.

 
 

3 Gründe, warum Ihre Excel-Anwendung so kompliziert ist: mehr Informationen dazu hier.