2017-01-13 6 views
0

Ich habe herausgefunden, wie man den Inhalt eines Zeichenkettenarrays in Excel in dem Format schreiben kann, das ich will, aber jetzt habe ich Probleme sicherzustellen, dass es nicht über bereits vorhandene Zellen schreibt in einer Excel-Datei gefüllt.OpenXML Schreiben von Werten in leere Zellen in Excel

Momentan versuche ich den Inhalt der Excel-Datei zuerst zu lesen und dann basierend darauf, wo es keine Werte gibt. Das habe ich derzeit.

private static void WriteToExcel(string[] contents, char[] desiredColumns) 
{ 
    string filePath = @"D:\Folder\test.xlsx"; 
    try 
    { 
     using (SpreadsheetDocument StatsCollection = SpreadsheetDocument.Open(filePath, true)) 
     { 
      WorkbookPart bookPart = StatsCollection.WorkbookPart; 
      string sheetName = "Sheet1"; 
      SharedStringTablePart sstpart = bookPart.GetPartsOfType<SharedStringTablePart>().First(); 
      SharedStringTable sst = sstpart.SharedStringTable; 
      Sheet mySheet = bookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName).FirstOrDefault(); 
      WorksheetPart sheetPart = (WorksheetPart)(bookPart.GetPartById(mySheet.Id)); 
      Worksheet sheet = sheetPart.Worksheet; 
      var rows = sheet.Descendants<Row>(); 
      foreach (Row row in rows) 
      { 
       foreach (Cell currentCell in row.Elements<Cell>()) 
       { 
        int totalRows = contents.Length/15; 
        int contentsIndex = 0; 
        for (uint indexRow = 1; indexRow <= totalRows; indexRow++) 
        { 
         for (int indexCol = 1; indexCol < 16; indexCol++) 
         { 
          SharedStringTablePart shareStringPart; 
          if (StatsCollection.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0) 
          { 
           shareStringPart = StatsCollection.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First(); 
          } 
          else 
          { 
           shareStringPart = StatsCollection.WorkbookPart.AddNewPart<SharedStringTablePart>(); 
          } 
          int index = InsertSharedStringItem(contents[contentsIndex], shareStringPart); 
          if (currentCell.CellValue.InnerText == "") 
          { 
           Cell newCell = InsertCellInWorksheet(desiredColumns[indexCol - 1].ToString(), indexRow, sheetPart); 
           if (IsNumeric(contents[contentsIndex])) 
           { 
            newCell.DataType = new EnumValue<CellValues>(CellValues.Number); 
            newCell.CellValue = new CellValue(contents[contentsIndex]); 
           } 
           else 
           { 
            newCell.DataType = new EnumValue<CellValues>(CellValues.SharedString); 
            newCell.CellValue = new CellValue(index.ToString()); 
           } 
          } 
          else 
          { 
           break; 
          } 
          sheetPart.Worksheet.Save(); 
          contentsIndex++; 
         } 
        } 
       } 
      } 
     } 
     Console.WriteLine("Copy Complete."); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine("Cannot find output Excel file.\n" + ex.Message); 
    } 
} 

Mein Denkprozess war hier, dass, wenn ich den Code verwenden könnte in den Informationen auf meinem Excel-Blatt zu lesen, ich here fand ich könnte dann einsetzen, wenn diese null ist. Sobald ich festgestellt habe, ob etwas null ist, breche ich dann von meiner innersten Schleife (die meine Spalten behandelt) ab, um meine äußere Schleife (die Zeilen behandelt) zu inkrementieren. Das scheint jedoch nicht zu funktionieren. Ich habe überprüft, dass ich tatsächlich die Informationen aus dem Blatt lese, die ich einfach nicht darauf basierend schreiben kann.

Warum kann ich den Inhalt meiner Datei lesen, aber nicht basierend auf den vorhandenen Zellen schreiben?

Update:

Für alle, die über diese Frage kommt ich Microsoft.Office.Interop Schalt landete auf meine Daten auf das Ende einer Excel-Datei anhängen. Ich zögere, das als Antwort zu sagen, weil es nicht beantwortet, wie man es in OpenXML macht, was meine Frage war. Aber mit einer Antwort könnte jemand anderes das nützlich finden.

Antwort

1

Diese Funktion versucht, einen Wert aus einer Zelle

zu greifen, wenn die Zelle eine SharedStringValue hat, wird es, dass zurückgeben oder wenn es nur eine Reihe

Oder Rückkehr " ", wenn kein Wert

public static string GetCellV(Cell cell, SharedStringTable ss) 
    { 
     string cellV = null; 

     try 
     { 
      cellV = cell.CellValue.InnerText; 
      if (cell.DataType != null 
       && cell.DataType.Value == CellValues.SharedString) 
      { 
       cellV = ss.ElementAt(Int32.Parse(cellV)).InnerText; 
      } 
      else 
      { 

       cellV = cell.CellValue.InnerText; 
      } 
     } 
     catch (Exception) 
     { 
      cellV = " "; 
     } 

     return cellV; 
    } 

Ich bin sicher, dass Sie den letzten Teil für Ihre Bedürfnisse bearbeiten können.

HINWEIS:

Interop nicht sehr einfallsreich ist und ist sehr langsam bei der Ausführung, achten Sie auf Excel-Prozesse, die nicht geschlossen werden, wenn Sie die Ausführung beendet haben.

Open XML ist wesentlich schneller, da der XML-Code direkt bearbeitet wird.

+0

Ich habe gehört, dass OpenXML besser als Interop ist, aber ich stieß auf ein Problem mit '.xls' vs' .xlsx' und dem oben genannten Problem, also zu der Zeit war es nur schneller, zu Interop zu wechseln. Mehr Leute stehen mir zur Verfügung. – BlueBarren

+0

Kluge Wahl, wenn Sie jemals Excel-Pakete wie dieses wieder verwenden müssen, schauen Sie sich EPPlus an: http://epplus.codeplex.com/ –

Verwandte Themen