-1

我有一个循环 aDataTable并将其保存为Excel Fileusing SpreadSheetLightfor的函数C#

注意到循环DataTable并保存其Excel File输出需要时间,具体取决于 a 有多少单元格、行和列DataGrid,或者从哪里DataTable提取。

在我的函数中使用之前BackgroundWorker,该函数正确执行。当然,唯一的旁注BackgroundWorker是 UI 在代码执行时冻结。通过利用BackgroundWorker我知道我可以通过在另一个线程上处理保存功能来消除这种情况。

但是BackgroundWorker在我的功能中应用后,整个保存功能都会中断。它抛出了我,Object Reference not set to an instance of an Object但我调试和跟踪并确保两个传递的变量都有值,并且不为空。我使用的循环和以前一样,我什至尝试过使用For Loop.

这是我遇到的一个片段。如您所见,下面的窗口显示cellandvalue变量都包含内容。却抛出了空引用。

在此处输入图像描述

此外,这是我的功能的完整代码

        public void exportSingleDataGridToExcelFile(DataTable dt) {
            using(var sfd = new SaveFileDialog()) {
                sfd.FileName = string.Format("WIP Monitoring-{0}", DateTime.Now.ToString("MM.dd.yyyy"));
                sfd.Filter = "Excel File (*.xlsx)|*.xlsx";

                if(sfd.ShowDialog() == DialogResult.OK) {
                    clb.Enabled = false;
                    cb.Enabled = false;
                    btn.Visible = false;
                    pb.Visible = true;
                    pb.Value = 50;

                    using(var excel = new SLDocument()) {
                        var style = excel.CreateStyle();
                        style.SetHorizontalAlignment(DocumentFormat.OpenXml.Spreadsheet.HorizontalAlignmentValues.Center);
                        style.SetVerticalAlignment(DocumentFormat.OpenXml.Spreadsheet.VerticalAlignmentValues.Center);

                        var bgw = new BackgroundWorker();
                        bgw.WorkerReportsProgress = true;

                        bgw.DoWork += (ss, ee) => {
                            var worker = ss as BackgroundWorker;

                            var count = (dt.Rows.Count + 1) * dt.Columns.Count;
                            var steps = (double) count / 100;
                            var prog = 0.0;
                            var row = 0;
                            var col = 0;

                            //Get Column Headers
                            foreach(DataColumn dc in dt.Columns) {
                                var cell = string.Format("{0}1", col.getExCol());
                                var value = dc.ColumnName;

                                excel.SetCellValue(cell, value);
                                excel.AutoFitColumn(string.Format("{0}1", col.getExCol()));
                                excel.SetCellStyle(string.Format("{0}1", col.getExCol()), style);

                                prog += steps;
                                worker.ReportProgress(((int) prog * 100));

                                col++;
                            }

                            col = 0;

                            //Get Cell Data
                            foreach(DataRow dr in dt.Rows) {
                                foreach(DataColumn dc in dt.Columns) {
                                    var cell = string.Format("{0}{1}", col.getExCol(), row);
                                    var value = dr[dc].ToString();

                                    excel.SetCellValue(cell, value);
                                    excel.AutoFitColumn(cell, row);
                                    excel.SetCellStyle(cell, style);

                                    prog += steps;
                                    worker.ReportProgress(((int) prog * 100));

                                    col++;
                                }
                                col = 0;
                                row++;
                            }
                        };

                        bgw.ProgressChanged += (ss, ee) => {
                            pb.Value = ee.ProgressPercentage / 100;
                        };

                        bgw.RunWorkerCompleted += (ss, ee) => {
                            try {
                                excel.SaveAs(sfd.FileName);
                                form.Close();
                            } catch(Exception ex) {
                                MessageBox.Show(ex.Message, "Error while saving", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        };

                        bgw.RunWorkerAsync();
                    }
                }
            }
        }

最初,在我实现我的BackgroundWorker.

希望我能在这里得到一些散步。

4

2 回答 2

2

SLDocuemnt实例内部的某些东西很可能excelnull在执行后台工作人员时。

您正在创建excel一个using声明。这意味着在using块的末尾,excel将被处置。但是在该块内,您启动了一个使用此excel变量的后台工作程序。

后台工作人员肯定比您的using块运行时间更长,因此excel当您尝试访问它并执行引发异常的行时,它已经被释放。

直接的解决方案是不要using在这里使用。但也许最好在后台工作人员的方法中实例化该变量excel,因为看起来你无论如何都不需要它。

于 2016-06-16T08:00:33.667 回答
1

在读取异常时,我很确定您的 excel变量是 Null 变量。不是方法调用中的值。

我怀疑这是由于您所做的背景工作。

于 2016-06-16T08:00:44.797 回答