我可以在没有迭代的情况下从数据源导入INTO excel吗?

时间:2010-09-20 13:53:50

标签: excel visual-studio-2008 vba export-to-excel

目前我有一个应用程序从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函数是从here获得的。

        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();
        }

6 个答案:

答案 0 :(得分:2)

我过去曾使用Excel XML文件格式直接写入输出文件或流。它可能不适合您的应用程序,但编写XML要快得多,并且绕过了与Excel应用程序交互的开销。查看此Introduction to Excel XML帖子。

<强>更新 还有一些库(免费和商业)可以使创建excel文档更容易,例如excellibrary,它不支持新格式。 Create Excel (.XLS and .XLSX) file from C#

的答案中提到了其他一些内容

答案 1 :(得分:2)

你能使用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

BTW,Excel对HTML和内部样式表非常满意。

答案 2 :(得分:2)

Excel可以使用 CopyFromRecordset 方法在单个操作中写入ADO或DAO记录集中的所有数据。

代码段:

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

答案 3 :(得分:1)

我通常建议使用Excel从SQLite中提取数据。使用Excel的“其他数据源”。然后,您可以选择您的OLE DB提供程序,使用连接字符串,有什么用户。alt text

但是,听起来,代码的真正价值在于单元格的格式,而不是数据的传输。

或许可以将流程重构为:

  • 让Excel导入数据
  • 使用您的代码打开Excel电子表格,然后应用格式

我不确定这对你来说是否是一套合适的流程,但也许需要考虑一下?

答案 4 :(得分:0)

答案 5 :(得分:0)

也许发布一些代码,我们也许能够找到任何问题。

我会考虑这一系列事件:

  • 在SQLite数据库中查询您的数据集。
  • 将数据移出ADO.NET对象,然后移入POCO对象。停止使用DataTables / Rows。
  • 使用For Each插入Excel。