【问题标题】:Cells in Excel._Worksheet do not correctly filled with dataExcel._Worksheet 中的单元格未正确填充数据
【发布时间】:2016-10-06 10:56:32
【问题描述】:

在“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-bite version”。我一直在编写以下代码来实现导出。

    // 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) 当 _isAbsoluteChartDataBeingExported == true 时,继续轮询 ConcurrentQueue 实例以获取现有数据。 3) 从 ConcurrentQueue 实例中获取 AGC_DataRecordToSave 的当前实例(要导出的记录)。 4) 从此 AGC_DataRecordToSave 实例中获取字段值,并通过单元格的适当索引(cellIndex 变量)将这些字段值分配给 WorkSheet 的单元格。 5) 更正单元格的索引并再次轮询 ConcurrentQueue 实例以获取新记录。 ETC。当当前活动工作表上的行数达到限制(抛出 COMException)时,转到工作簿的下一个工作表(使此列表处于活动状态)并再次重复 2) - 5) 项。 ETC。当用户关闭导出到 MS Excel 时,将工作簿(带有数据表)写入 XLSX 文件。但我无法达到预期的效果。下面是结果在 MS Excel 中的显示方式。

而且只有第一张纸有数据。所有剩余的工作表都是空的。然而,正如您所看到的,不均匀的工作表枚举存在(1、2、109、108,...)。但是工作表的数量必须如下(1、2、3、4,...)。我做错了什么?请帮助我纠正和消除错误并让“exportToExcel”方法正常工作。

【问题讨论】:

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


    【解决方案1】:

    有一个简单的方法来使用npoi.mapper,只需不到 2 行。而且它不需要在服务器上安装MS Office。

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

    【讨论】:

    • 请原谅,DonnyTian,但我不问哪个库更好,我问的是我应该在代码中做什么才能得到正确的结果。
    猜你喜欢
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 2012-03-16
    相关资源
    最近更新 更多