Excel._Worksheet中的单元格没有正确填充数据
在我的文章' 如何将DateTime,TimeSpan,string和双精度值从WPF MVVM应用程序导出到Excel? '我问如何使用VSTO从WPF MVVM应用程序中导出MS Excel。 不等待答案,我决定尝试自己去做。 我的电脑上有'MS Excel 2016 MSO(16.0.4432.1000)64-bit版本'。 我一直在写下面的代码来实现导出。
// 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时设置的布尔标志,当用户closures此导出时取消设置。 以下是closuresExcel的方法:
// 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)在活动WorkSheet上为表格创build标题,并为XLSX文件定义名称。 2)在_isAbsoluteChartDataBeingExported == true的同时,不断轮询ConcurrentQueue实例以获取现有数据。 3)从ConcurrentQueue实例中取出AGC_DataRecordToSave(record to export)的当前实例。 4)从AGC_DataRecordToSave实例中获取字段的值,并将这些字段值通过单元格的适当索引(cellIndexvariables)赋值给WorkSheet的单元格。 5)更正单元格的索引并再次轮询ConcurrentQueue实例以获得新logging。 等当前活动工作表上的行数达到限制(抛出COMException)时,转到下一张WorkBook(使此列表处于活动状态),然后重复2) – 5)项。 等当用户转出口到MS Excelclosures写入工作簿(与数据表)到XLSX文件。 但是我无法达到预期的效果。 下面是如何在MS Excel中看到的结果。
只有第一张有数据。 所有剩余的纸张都是空的。 然而,正如你所看到的,一个不同的枚举枚举(1,2,109,108,…)。 但是纸张的数量必须如下(1,2,3,4,…)。 我做错了什么? 请帮助我纠正并消除错误,并使“exportToExcel”方法正常工作。
有一个简单的方法来使用npoi.mapper只有2行以下。 而且它不需要在服务器上安装MS Office。
var mapper = new Mapper(); mapper.Save("test.xlsx", objects, "newSheet");