-1

a をループしてforを使用しDataTableて保存する関数がありますExcel FileSpreadSheetLightC#

をループしてDataTableその出力を保存するには、セルと行と列の数、または抽出元の場所Excel Fileに応じて時間がかかることに注意してください。DataGridDataTable

BackgroundWorker私の関数で使用する前に、関数は正しく実行されます。BackgroundWorkerもちろん、コードの実行中にUIがフリーズするという唯一の補足事項があります。利用するBackgroundWorkerことで、別のスレッドで保存機能を処理することでこれを排除できることがわかっています。

しかし、関数に適用BackgroundWorkerした後、保存関数全体が壊れます。それは私をスローしますObject Reference not set to an instance of an Objectが、私はデバッグしてトレースし、渡された両方の変数に値があり、null ではないことを確認しました。私が使用したループは以前と同じで、For Loop.

ここに私が遭遇したもののスニペットがあります。ご覧のとおり、下のウィンドウは変数cellvalue変数の両方に内容があることを示しています。まだ null 参照をスローします。

ここに画像の説明を入力

さらに、ここに私の関数の完全なコードがあります

        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インスタンス内の何かが発生する可能性が非常に高くなりexcelます。null

ステートメントで作成excelしています。usingつまり、usingブロックの最後で、excelが破棄されます。しかし、そのブロック内で、このexcel変数を使用するバックグラウンド ワーカーを開始します。

バックグラウンドワーカーは確実にusingブロックよりも長く実行されるためexcel、アクセスして例外をスローする行を実行しようとすると、すでに破棄されています。

当面の解決策は、ここでは使用しないことusingです。しかし、バックグラウンドワーカーのメソッドexcelでその変数をインスタンス化する方が良いかもしれません.とにかく外部では必要ないようです.

于 2016-06-16T08:00:33.667 に答える
1

例外を読むとき、あなたの excel変数はNullであると確信しています。メソッド呼び出しの値ではありません。

これは、あなたが行っているバックグラウンド作業によるものだと思います。

于 2016-06-16T08:00:44.797 に答える