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;
}
}
}
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
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.
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
}
Verwende einen Profiler, um zu erkennen, welcher Bereich und welche Ausführung wirklich ein HotSpot ist.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Danke, habs gefunden. Das ToList muss außerhalb gemacht werde. Das wars schon. 😃