Excel._Worksheet中的单元格未正确填充数据

时间:2016-10-06 10:56:32

标签: c# wpf excel export-to-excel

在我的帖子'How to export DateTime, TimeSpan, string and double values to Excel from WPF MVVM application?'中,我询问如何使用VSTO从WPF MVVM应用程序中导出MS Excel。不等待答案,我决定尝试自己去做。我的计算机上有'MS Excel 2016 MSO(16.0.4432.1000)64位版本'。我一直在编写以下代码来实现导出。

    // 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)在活动的WorkSheet上创建表的标题,并定义XLSX文件的名称。 2)在_isAbsoluteChartDataBeingExported == true时,继续轮询ConcurrentQueue instanse以获取现有数据。 3)从ConcurrentQueue实例获取AGC_DataRecordToSave的当前实例(要导出的记录)。 4)从该AGC_DataRecordToSave实例中获取字段的值,并通过适当的单元格索引(cellIndex变量)将这些字段值设置为WorkSheet的单元格。 5)更正单元格的索引并再次轮询ConcurrentQueue实例以获取新记录。等等。当当前活动工作表上的行数达到限制(抛出COMException)时,转到下一张工作簿(使此列表激活)并再次重复2) - 5)项目。等等。当用户将导出到MS Excel时,将WorkBook(带有数据的表格)写入XLSX文件。但我无法达到预期的效果。以下是在MS Excel中看到结果的方法。

enter image description here 只有第一张表有数据。所有剩余的纸张都是空的。然而,正如您所看到的,已经存在不均匀的页面枚举(1,2,109,108,...)。但是表格的编号必须是以下(1,2,3,4,...)。我做错了什么?请帮我纠正并消除错误并让'exportToExcel'方法正常工作。

1 个答案:

答案 0 :(得分:1)

有一种简单的方法可以使用npoi.mapper只有2行以下。并且它不需要在服务器上安装MS Office。

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