簡體   English   中英

我可以在沒有迭代的情況下從數據源導入INTO excel嗎?

[英]Can I import INTO excel from a data source without iteration?

目前,我有一個應用程序從SQLite數據庫獲取信息並將其放到Excel中。 但是,我必須采用每個DataRow,遍歷每個項目,並將每個值放入其自己的單元格中並確定突出顯示。 導致9000記錄文件導入Excel的時間是20分鍾。 我相信它可以比這更快地完成。 我的想法是,我可以使用數據源來填充Excel范圍,然后使用列標題和行號來格式化那些需要格式化的行。 但是,當我在線查看時,無論我打算輸入什么內容,它總是顯示使用Excel作為數據庫的示例,而不是導入到Excel中。 除非我忘了一個關鍵詞或者。 現在,這個函數必須在代碼中完成,因為它是更大的應用程序的一部分。 否則我只需要Excel連接到數據庫並自行提取信息。 不幸的是,事實並非如此。 任何可以幫助我快速加載excel表的信息將不勝感激。 謝謝。

附加信息:
從數據庫中提取信息必須在代碼中完成的另一個原因是,並非所有加載的計算機都會在其上安裝Excel。 可以簡單地告知使用該應用程序的人將數據導出並通過電子郵件發送給他們的主管。 安裝應用程序包含應用程序所需的dll以生成正確的格式。

示例代碼(當前):

    For Each strTemp In strColumns
        excelRange = worksheet.Cells(1, nCounter)
        excelRange.Select()
        excelRange.Value2 = strTemp
        excelRange.Interior.Color = System.Drawing.Color.Gray.ToArgb()
        excelRange.BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin, Excel.XlColorIndex.xlColorIndexAutomatic, Type.Missing)
        nCounter += 1
    Next

現在,這只是我正在進行的迭代的示例代碼。 我正在處理來自數據庫的信息,我正在遍歷dataTable的Rows,然后迭代dataRow中的項目,並且基本上與上面相同; 按值計算值,選擇范圍並將值放在單元格中,如果單元格是報表的一部分(不總是灰色),則格式化單元格,然后移動到下一組數據。 我想要做的是將所有數據放在Excel工作表中(A2:??,不是一行,而是多行)然后遍歷報表並格式化每一行。 這樣,我遍歷所有記錄的唯一時間是每條記錄都是報告的一部分。

理想代碼

excelRange = worksheet.Cells("A2", "P9000")
excelRange.DataSource = ds 'ds would be a queried dataSet, and I know there is no excelRange.DataSource.
'Iteration code to format cells

更新:

我知道我的例子是在VB中,但這是因為我也試圖編寫VB版本的應用程序,因為我的老板更喜歡VB。 但是,這是我使用Recordset的最終代碼。 ConvertToRecordset函數是從這里獲得的。

        private void CreatePartSheet(Excel.Worksheet excelWorksheet)
        {
            _dataFactory.RevertDatabase();
            excelWorksheet.Name = "Part Sheet";
            string[] strColumns = Constants.strExcelPartHeaders;
            CreateSheetHeader(excelWorksheet, strColumns);

            System.Drawing.Color clrPink = System.Drawing.Color.FromArgb(203, 192, 255);
            System.Drawing.Color clrGreen = System.Drawing.Color.FromArgb(100, 225, 137);

            string[] strValuesAndTitles = {/*...Column Names...*/};

            List<string> lstColumns = strValuesAndTitles.ToList<string>();

            System.Data.DataSet ds = _dataFactory.GetDataSet(Queries.strExport);
            ADODB.Recordset rs = ConvertToRecordset(ds.Tables[0]);
            excelRange = excelWorksheet.get_Range("A2", "ZZ" + rs.RecordCount.ToString());
            excelRange.Cells.CopyFromRecordset(rs, rs.RecordCount, rs.Fields.Count);
            int nFieldCount = rs.Fields.Count;

            for (int nCounter = 0; nCounter < rs.RecordCount; nCounter++)
            {
                int nRowCounter = nCounter + 2;
                List<ReportRecord> rrPartReports = _lstReports.FindAll(rr => rr.PartID == nCounter).ToList<ReportRecord>();
                excelRange = (Excel.Range)excelWorksheet.get_Range("A" + nRowCounter.ToString(), "K" + nRowCounter.ToString());
                excelRange.Select();
                excelRange.NumberFormat = "@";

                if (rrPartReports.Count > 0)
                {
                    excelRange.Interior.Color = System.Drawing.Color.FromArgb(230, 216, 173).ToArgb(); //Light Blue

                    foreach (ReportRecord rr in rrPartReports)
                    {
                        if (lstColumns.Contains(rr.Title))
                        {
                            excelRange = (Excel.Range)excelWorksheet.Cells[nRowCounter, lstColumns.IndexOf(rr.Title) + 1];
                            excelRange.Interior.Color = rr.Description.ToUpper().Contains("TAG") ? clrGreen.ToArgb() : clrPink.ToArgb();

                            if (rr.Description.ToUpper().Contains("TAG"))
                            {
                                rs.Find("PART_ID=" + (nCounter + 1).ToString(), 0, ADODB.SearchDirectionEnum.adSearchForward, "");
                                excelRange.AddComment(Environment.UserName + ":  " + _dataFactory.GetTaggedPartPrevValue(rs.Fields["POSITION"].Value.ToString(), rr.Title));
                            }
                        }
                    }
                }

                if (nRowCounter++ % 500 == 0)
                {
                    progress.ProgressComplete = ((double)nRowCounter / (double)rs.RecordCount) * (double)100;
                    Notify();
                }
            }

            rs.Close();

            excelWorksheet.Columns.AutoFit();
            progress.Message = "Done Exporting to Excel";
            Notify();
            _dataFactory.RestoreDatabase();
        }

我以前使用Excel XML文件格式直接寫入輸出文件或流。 它可能不適合您的應用程序,但編寫XML要快得多,並且繞過了與Excel應用程序交互的開銷。 查看此Excel XML文章簡介

更新:還有一些庫(免費和商業)可以使創建excel文檔更容易,例如,不支持新格式的excellibrary 從C#創建Excel(.XLS和.XLSX)文件的答案中提到了其他一些

你可以使用ODBC嗎?

''http://www.ch-werner.de/sqliteodbc/

dbName = "c:\docs\test"
scn = "DRIVER=SQLite3 ODBC Driver;Database=" & dbName _
& ";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;"

Set cn = CreateObject("ADODB.Connection")
cn.Open scn

Set rs = CreateObject("ADODB.Recordset")
rs.Open "select * from test", cn

Worksheets("Sheet3").Cells(2, 1).CopyFromRecordset rs

順便說一下,Excel對HTML和內部樣式表非常滿意。

Excel可以使用CopyFromRecordset方法在單個操作中寫入ADO或DAO記錄集中的所有數據。

代碼段:

    Sheets("Sheet1").Range("A1").CopyFromRecordset rst

我通常建議使用Excel從SQLite中提取數據。 使用Excel的“其他數據源”。 然后,您可以選擇您的OLE DB提供程序,使用連接字符串,你有什么。 替代文字

然而,聽起來,代碼的真正價值在於單元格的格式化 ,而不是數據的傳輸。

也許重構過程:

  • 有Excel導入數據
  • 使用您的代碼打開Excel電子表格,並應用格式

我不確定這對你來說是否是一套合適的流程,但也許需要考慮一下?

也許發布一些代碼,我們也許能夠找到任何問題。

我會考慮這一系列事件:

  • 查詢SQLite數據庫中的數據集。
  • 將數據移出ADO.NET對象,並移入POCO對象。 停止使用DataTables / Rows。
  • 使用For Each插入Excel。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM