Laden...

OpenXml überspringt leere Zellen bei import von xlsx

Erstellt von Steven85 vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.149 Views
Steven85 Themenstarter:in
99 Beiträge seit 2011
vor 11 Jahren
OpenXml überspringt leere Zellen bei import von xlsx

Hallo zusammen, ich habe eine großes Problem beim Import einer xlsx Datei mit dem OpenXML SDK. Ist eine Tabelle komplett gefüllt, funktioniert alles tadellos. Sieht eine Tabelle jedoch z.B. so aus:

Spalte1 Spalte2 Spalte3
Wert1 Wert2 Wert3
Wert1 Wert3

...importiert es das ganze so in eine DataTable:

Spalte1 Spalte2 Spalte3
Wert1 Wert2 Wert3
Wert1 Wert3

Er überspringt quasi die leeren Zellen und schiebt alles eins nach links in dem Fall.
Hier mein Code dazu.


for (int i = 2; i <= lastRow.RowIndex; i++)
{
    DataRow dr = dtData.NewRow();

    Row row = new Row();
    // An dieser Stelle jetzt wird mit row.Childelements.Count eine Zelle weniger ausgegeben
    row = worksheetPart.Worksheet.Descendants<Row>().Where(r => i == r.RowIndex).FirstOrDefault();

    int j = 0;

    if (row != null)
    {
        foreach (Cell c in row.ChildElements)
        {
            //Get cell value
            string value = cell.ElementAt(0).InnerText;

            dr[j] = value;
            j++;

            if (j == dtData.Columns.Count)
                break;
        }
    }
}

S
10 Beiträge seit 2012
vor 11 Jahren

Hallo Steven85!

Du musst Cell.CellReference auswerten, um herauszufinden, zu welcher Spalte eine Zelle gehört. CellReference enthält die typische Excel-Zellennotation, z.B. "B5" für Spalte 2 /Zeile 5.

Grüße,

Christoph

Steven85 Themenstarter:in
99 Beiträge seit 2011
vor 11 Jahren

Gibt es eine Möglichkeit in einem Array der Größe 100 z.B.,
alle Zell Referenzen zu speichern die es gibt (A1 - CV1).
Damit könnte ich dann abgleichen ob eine Zelle übersprungen wurde.

Steven85 Themenstarter:in
99 Beiträge seit 2011
vor 11 Jahren

Habs geschafft, danke für den Tipp, hat echt geholfen.

Steven85 Themenstarter:in
99 Beiträge seit 2011
vor 11 Jahren

Ein Problem hab ich jetzt noch. Das Prüfen jeder Zelle, ob sie leer ist, dauert bei einer Datei von 100 Spalten und 1000 Zeilen Stunden lang.
Könnte ich an dem Code noch was verbessern?


int readyRows = 1; // Multiplikator für fertige Rows
int jumped = 0; // Für übersprungene Zellen
for (int i = 2; i <= lastRow.RowIndex; i++)
{
    DataRow dr = dtData.NewRow();
    for (int j = 0; j < columnsCount; j++)
    {
        string sReference = worksheetPart.Worksheet.Descendants<Cell>().ToList()[j].CellReference.ToString();
        string sReferenceLetters = string.Empty;
        foreach (char letter in sReference.ToCharArray())
        {
            if (Char.IsLetter(letter)) sReferenceLetters += letter;
        }

        string value;
        Cell cell = worksheetPart.Worksheet.Descendants<Cell>().ToList().ElementAtOrDefault(j + (dtData.Columns.Count * readyRows) - jumped);
        if (cell.CellReference.Value == (sReferenceLetters + i.ToString()))
            value = GetValue(cell, stringTablePart, cfs);
        else
        {
            value = "";
            jumped++;
        }
        dr[j] = value;
    }
    dtData.Rows.Add(dr);
    readyRows++; // Um die Referenz der nächsten Zeile zu bauen
}

16.807 Beiträge seit 2008
vor 11 Jahren

Verwende einen Profiler, um zu erkennen, welcher Bereich und welche Ausführung wirklich ein HotSpot ist.

Steven85 Themenstarter:in
99 Beiträge seit 2011
vor 11 Jahren

Danke, habs gefunden. Das ToList muss außerhalb gemacht werde. Das wars schon. 😃