2016-10-06 2 views
0

В моем посте в 'How to export DateTime, TimeSpan, string and double values to Excel from WPF MVVM application?' Я спрашиваю о том, как делать экспорт в MS Excel из приложения WPF MVVM, используя VSTO. Не дожидаясь ответа, я решил попробовать себя. У меня есть «MS Excel 2016 MSO (16.0.4432.1000) 64-бит версия» на моем компьютере. Я пишу следующий код для реализации экспорта.Ячейки в Excel._Worksheet неправильно заполнены данными

// 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); 
      } 
     }); 
    } 

Где _agcAbsoluteDataRecordsToSaveBuf является ConcurrentQueue экземпляра и _isAbsoluteChartDataBeingExported является логическим флагом, который устанавливается, когда пользователь поворачивает на экспорт в MS Excel и снят с охраной, когда пользователь выключает этот экспорт. И ниже метод закрытия Excel:

// 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); 
     } 
    } 

Что мне нужно: 1) Создать заголовок для таблицы на активном листе и определяют имя XLSX-файл. 2) Проведите одновременное опробование ConcurrentQueue для существующих данных, тогда как _isAbsoluteChartDataBeingExported == true. 3) Возьмите текущий экземпляр AGC_DataRecordToSave (запись для экспорта) из экземпляра ConcurrentQueue. 4) Возьмите значения полей из этого экземпляра AGC_DataRecordToSave и присвойте эти значения поля ячейкам WorkSheet соответствующим индексом для ячеек (переменная cellIndex). 5) Исправьте индекс для ячеек и опросите экземпляр ConcurrentQueue снова для новой записи. И т.д. Когда количество строк на текущем активном листе достигает предела (вызывается COMException), перейдите к следующему листу WorkBook (сделайте этот список активным) и повторите снова 2) - 5). И т.д. Когда пользователь превращает экспорт в MS Excel, вы можете записать WorkBook (с листами с данными) в XLSX-файл. Но я не могу добиться желаемого эффекта. Ниже приведен пример результата в MS Excel.

enter image description here И только первый лист имеет данные. Все остальные листы пусты. И все же, как вы видите, неравномерное перечисление листов имеет место (1, 2, 109, 108, ...). Но нумерация листов должна быть следующей (1, 2, 3, 4, ...). Что я делаю неправильно? Пожалуйста, помогите мне исправить ошибки и устранить их и получить метод «exportToExcel» для правильной работы.

ответ

1

Существует простой способ использования npoi.mapper с чуть ниже 2 линий. И не требуется устанавливать MS Office на сервер.

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

Я прошу прощения, ДонниТиан, но я не спрашиваю о том, какая библиотека лучше, я спросил, что должен сделать в своем коде, чтобы получить правильный результат. – Prohor

Смежные вопросы