Excel Sylk Dateien parsen mit Python

Vor ein paar Wochen hatte ich das erste Mal mit Microsoft Sylk Dateien zu tun. SLK ist ein Microsoft Format, das von Excel gelesen werden kann, mehr dazu im entsprechenden Wikipedia-Artikel. Ein Vorteil dieses Formats ist es, dass auch gewisse Formatierungen und verbundene Zellen unterstützt werden. Leider gibt es keine offizielle API dafür, das Format unterstützt anscheinend auch nur Windows-Encoding.

In meinem konkreten Fall sah der Input so aus:

ID;PWXL;N;E
P;PGeneral
P;P0
P;P0.00
P;P0.000
P;P0.0000
P;P0.00000
P;P0.000000
P;Pdd.mm.yyyy
C;Y1;X1;K"Inhalt der Zelle A1"
C;Y1;X2;K"Inhalt der Zelle B1"
C;Y2;X1;K"Inhalt der Zelle A2"
C;Y2;X2;K"Inhalt der Zelle B2"
E

In den ersten Zeilen standen irgendwelche Format-Anweisungen, die mich glücklicherweise nicht interessieren mussten. Mir waren nur die Zeilen wichtig, die mit „C“ begannen.

Das folgende Python-Programm habe ich dann genutzt, um die Inhalte zu extrahieren.

import pandas as pd
 
 
def get_sylk_dimension(file):
        """
        Suche die maximale Zeile und Spalte mit Inhalt
        das ist die letzte Zeile mit einem 'C' am Anfang
        gib Tupel aus X und Y-Koordinate zurück
        """
 
        with open(file, 'r', encoding="latin-1") as input:
            for line in input:
                if line[0] in ('E', 'F', 'I','K', 'P'):
                    pass # nicht verarbeiten
                else:
                    contentline = line
                    contentlist = contentline.split(';')
            return int(contentlist[2][1:]), int(contentlist[1][1:])
 
 
def sylk2df(file):
    """
        Wandelt MS SYLK Datei in DataFrame um
    """
 
    x, y = get_sylk_dimension(file)
    df = pd.DataFrame(index=range(y),columns=range(x))
 
    with open(file, 'r', encoding="latin-1") as input:
        for line in input:
            # filtere non-C Zellen raus
            if line[0] in ('E', 'F', 'I','K', 'P'):
                pass
            else:
                columns = line.split(';')
 
                # Erstelle die Koordinaten
                columns[1] = int(columns[1].lstrip('Y'))
                columns[2] = int(columns[2].lstrip('X'))
 
                # bereinige den eigentlichen Inhalt
                columns[3] = columns[3].lstrip('K')
                columns[3] = columns[3].strip().replace('"','')
                columns[3] = columns[3].strip().replace('\n','')
 
                # trage die Inhalte ein
                df.at[columns[1]-1, columns[2]-1] = columns[3]
    return df
 
 
x = sylk2df('test.slk')
print(x)

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website