2016-10-06 6 views
0

In meinem Beitrag unter 'How to export DateTime, TimeSpan, string and double values to Excel from WPF MVVM application?' frage ich nach dem Export in MS Excel von WPF MVVM-Anwendung mit VSTO. Ohne auf eine Antwort zu warten, beschloss ich, es selbst zu versuchen. Ich habe MS Excel 2016 MSO (16.0.4432.1000) 64-Bit-Version auf meinem Computer. Ich habe den folgenden Code geschrieben, um den Export zu implementieren.Zellen in Excel._Worksheet sind nicht korrekt mit Daten gefüllt

// Exports to MS Excel. 
    private async void exportToExcel() 
    { 
     await Task.Run(() => 
     { 
      // Cell index. 
      int cellIndex = 2; 
      // MS Excel application instance. 
      Excel.Application oXL = null; 
      // Work book. 
      Excel._Workbook oWB; 
      // Active work sheet. 
      Excel._Worksheet oSheet; 
      // Cell range. 
      Excel.Range oRng; 
      // Next sheet index. 
      int sheetIndex = 2; 

      try 
      { 
       //Start Excel and get Application object. 
       oXL = new Excel.Application(); 
       oXL.Visible = false; 
       //Get a new workbook. 
       oWB = oXL.Workbooks.Add(Missing.Value); 
       // Get shets quantity. 
       int sheetsQuantity = oWB.Sheets.Count; 
       // Get active sheet. 
       oSheet = (Excel._Worksheet)oWB.ActiveSheet; 

       //Add table headers going cell by cell. 
       oSheet.Cells[1, 1] = "Date"; 
       oSheet.Cells[1, 2] = "Time"; 
       oSheet.Cells[1, 3] = "Beam"; 
       oSheet.Cells[1, 4] = "Direction"; 
       oSheet.Cells[1, 5] = "Value"; 
       //Format A1:E1 as bold, vertical alignment = center. 
       oSheet.get_Range("A1", "E1").Font.Bold = true; 
       oSheet.get_Range("A1", "E1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; 

       // Get name of file to export to Excel. 
       string fileDateTime = DateTime.Now.ToString("dd.mm.yyyy hh:mm:ss"); 
       fileDateTime = fileDateTime.Replace(".", ""); 
       fileDateTime = fileDateTime.Replace(":", ""); 
       fileDateTime = fileDateTime.Replace(' ', '_'); 
       string fileName = "test_" + fileDateTime + ".xlsx"; 

       // Exporting in Excel. 
       while (this._isAbsoluteChartDataBeingExported) 
       { 
        AGC_DataRecordToSave record; 
        if (this._agcAbsoluteDataRecordsToSaveBuf.TryDequeue(out record)) 
        { 
         try 
         { 
          oSheet.Range["A" + cellIndex].Value = record.Date.ToString("d"); 
          oSheet.Range["B" + cellIndex].Value = record.Time.ToString("T"); 
          oSheet.Range["C" + cellIndex].Value = record.MeasuringBeam.ToString(); 
          oSheet.Range["D" + cellIndex].Value = record.Direction; 
          oSheet.Range["E" + cellIndex].Value = record.Value; 
         } 
         catch(COMException) 
         { 
          //AutoFit columns A:E. 
          oRng = oSheet.get_Range("A1", "E1"); 
          oRng.EntireColumn.AutoFit(); 

          // If sheets number more than one. 
          if (sheetsQuantity > 1) 
          { 
           // If next sheet index is less than quantity of sheets then get next sheet and activate it. 
           if (sheetIndex < sheetsQuantity) 
           { 
            oSheet = oWB.Sheets[sheetIndex]; 
            oSheet.Activate(); 
            sheetIndex += 1; 

            cellIndex = 2; 
            //Add table headers going cell by cell. 
            oSheet.Cells[1, 1] = "Date"; 
            oSheet.Cells[1, 2] = "Time"; 
            oSheet.Cells[1, 3] = "Beam"; 
            oSheet.Cells[1, 4] = "Direction"; 
            oSheet.Cells[1, 5] = "Value"; 
            //Format A1:E1 as bold, vertical alignment = center. 
            oSheet.get_Range("A1", "E1").Font.Bold = true; 
            oSheet.get_Range("A1", "E1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; 
            continue; 
           } 
           else 
           { 
            // Else, add new sheet in workbook. 
            oWB.Sheets.Add(Missing.Value, oSheet, 1, Excel.XlSheetType.xlWorksheet); 
            oSheet = oWB.Sheets[2]; 
            oSheet.Visible = Excel.XlSheetVisibility.xlSheetHidden; 
            sheetsQuantity += 1; 
            sheetIndex += 1; 

            cellIndex = 2; 
            //Add table headers going cell by cell. 
            oSheet.Cells[1, 1] = "Date"; 
            oSheet.Cells[1, 2] = "Time"; 
            oSheet.Cells[1, 3] = "Beam"; 
            oSheet.Cells[1, 4] = "Direction"; 
            oSheet.Cells[1, 5] = "Value"; 
            //Format A1:E1 as bold, vertical alignment = center. 
            oSheet.get_Range("A1", "E1").Font.Bold = true; 
            oSheet.get_Range("A1", "E1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; 
            continue; 
           } 
          } 
          else 
          { 
           // Else, add new sheet in workbook. 
           oWB.Sheets.Add(Missing.Value, oSheet, 1, Excel.XlSheetType.xlWorksheet); 
           oSheet = oWB.Sheets[2]; 
           oSheet.Visible = Excel.XlSheetVisibility.xlSheetHidden; 
           sheetsQuantity += 1; 
           sheetIndex += 1; 

           cellIndex = 2; 
           //Add table headers going cell by cell. 
           oSheet.Cells[1, 1] = "Date"; 
           oSheet.Cells[1, 2] = "Time"; 
           oSheet.Cells[1, 3] = "Beam"; 
           oSheet.Cells[1, 4] = "Direction"; 
           oSheet.Cells[1, 5] = "Value"; 
           //Format A1:E1 as bold, vertical alignment = center. 
           oSheet.get_Range("A1", "E1").Font.Bold = true; 
           oSheet.get_Range("A1", "E1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; 
           continue; 
          } 
         } 
        } 
        cellIndex++; 
       } 

       // Save work book in XLSX-file. 
       if (!File.Exists(Path.Combine(this.PathToCsvRepository, fileName))) 
        oWB.SaveAs(Path.Combine(this.PathToCsvRepository, fileName), Missing.Value, Missing.Value, Missing.Value, true, true, Excel.XlSaveAsAccessMode.xlNoChange, 
         Excel.XlSaveConflictResolution.xlLocalSessionChanges, Missing.Value, Missing.Value, Missing.Value, true); 
      } 
      catch (IOException ex) 
      { 
       string errorMessage = string.Empty; 
       errorMessage = string.Concat(errorMessage, ex.Message); 
       errorMessage = string.Concat(errorMessage, " Line: "); 
       errorMessage = string.Concat(errorMessage, ex.Source); 
       MessageBox.Show(errorMessage, "Ошибка"); 
      } 
      catch (Exception ex) 
      { 
       string errorMessage = string.Empty; 
       errorMessage = string.Concat(errorMessage, ex.Message); 
       errorMessage = string.Concat(errorMessage, " Line: "); 
       errorMessage = string.Concat(errorMessage, ex.Source); 
       MessageBox.Show(errorMessage, "Ошибка"); 
      } 
      finally 
      { 
       // Complete work with Excel. 
       CloseExcel(oXL); 
      } 
     }); 
    } 

Wo _agcAbsoluteDataRecordsToSaveBuf ist ConcurrentQueue Instanz und _isAbsoluteChartDataBeingExported ist die Boolesche Flag, das gesetzt wird, wenn der Benutzer auf den Export nach MS Excel dreht und ungesetzt, wenn der Benutzer diesen Export erlischt. Und unten ist die Methode Excel zum Schließen:

// Closes Excel. 
    private static void CloseExcel(Excel.Application theApp) 
    { 
     int id = 0; 
     IntPtr intptr = new IntPtr(theApp.Hwnd); 
     System.Diagnostics.Process p = null; 
     try 
     { 
      GetWindowThreadProcessId(intptr, out id); 
      p = System.Diagnostics.Process.GetProcessById(id); 
      if (p != null) 
      { 
       p.Kill(); 
       p.Dispose(); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("CloseExcel:" + ex.Message); 
     } 
    } 

Was ich brauche, ist: 1) Erstellen Sie die Kopfzeile für die Tabelle auf aktive Arbeitsblatt und definieren Sie den Namen für XLSX-Datei. 2) Fortlaufende Abfrage der ConcurrentQueue-Instanz für vorhandene Daten, während _isAbsoluteChartDataBeingExported == true ist. 3) Nehmen Sie die aktuelle Instanz von AGC_DataRecordToSave (Datensatz zum Exportieren) von der ConcurrentQueue-Instanz. 4) Nimm die Werte der Felder von dieser AGC_DataRecordToSave-Instanz und ordne diese Feldwerte durch einen geeigneten Index für die Zellen (CellIndex-Variable) den Zellen von WorkSheet zu. 5) Korrigieren Sie den Index für die Zellen, und rufen Sie die ConcurrentQueue-Instanz erneut für den neuen Datensatz ab. Etc. Wenn die Anzahl der Zeilen auf dem aktuellen aktiven Blatt ein Limit erreicht (COMException wird ausgelöst), gehen Sie zum nächsten Sheet of WorkBook (machen Sie diese Liste aktiv) und wiederholen Sie 2) - 5) Elemente. Etc. Wenn der Benutzer den Export in MS Excel ausführt, schreib WorkBook (mit Blättern mit Daten) in die XLSX-Datei. Aber ich kann den gewünschten Effekt nicht erreichen. Im Folgenden sehen Sie, wie das Ergebnis in MS Excel angezeigt wird.

enter image description here Und nur das erste Blatt hat Daten. Alle übrigen Blätter sind leer. Und doch, wie Sie sehen können, hat eine ungleiche Aufzählung von Blättern Platz (1, 2, 109, 108, ...). Die Nummerierung der Blätter muss jedoch die folgenden sein (1, 2, 3, 4, ...). Was mache ich falsch? Bitte helfen Sie mir, die Fehler zu korrigieren und zu beseitigen und die 'exportToExcel'-Methode korrekt auszuführen.

Antwort

1

Es gibt eine einfache Möglichkeit, npoi.mapper mit knapp unter 2 Zeilen zu verwenden. Und es ist nicht erforderlich, MS Office auf dem Server zu installieren.

var mapper = new Mapper(); 
mapper.Save("test.xlsx", objects, "newSheet"); 
+0

Ich packe Ihre Entschuldigung, DonnyTian, ​​aber ich frage nicht, welche Bibliothek besser ist, habe ich gefragt, was ich in meinem Code tun sollte, um das richtige Ergebnis zu erhalten. – Prohor

Verwandte Themen