我可以从数据源导入 INTO excel 而无需迭代吗?

发布于 2024-09-24 07:41:42 字数 4749 浏览 1 评论 0原文

目前我有一个应用程序,它从 SQLite 数据库获取信息并将其放入 Excel。但是,我必须获取每个 DataRow,迭代每个项目,并将每个值放入其自己的单元格中并确定突出显示。这导致将 9000 条记录文件导出到 Excel 需要 20 分钟。我确信可以比这更快地完成。我的想法是,我可以使用数据源填充 Excel 范围,然后使用列标题和行号仅对需要格式化的行进行格式化。然而,当我在网上查看时,无论我看起来输入什么,它总是显示使用Excel作为数据库的示例,而不是导入到excel中。除非我忘记了一个关键词或者to。现在,此功能必须在代码中完成,因为它是更大应用程序的一部分。否则我只会让 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。但是,这是我使用记录集的最终代码。 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();
        }

Currently I have an application that takes information from a SQLite database and puts it to Excel. However, I'm having to take each DataRow, iterate through each item, and put each value into it's own cell and determine highlighting. What this is causing is 20 minutes to export a 9000 record file into Excel. I'm sure it can be done quicker than that. My thoughts are that I could use a data source to fill the Excel Range and then use the column headers and row numbers to format only those rows that need to be formatted. However, when I look online, no matter what I seem to type, it always shows examples of using Excel as a database, nothing about importing into excel. Unless I'm forgetting a key word or to. Now, this function has to be done in code as it's part of a bigger application. Otherwise I would just have Excel connect to the DB and pull the information itself. Unfortunately that's not the case. Any information that could assist me in quick loading an excel sheet would be appreciated. Thanks.

Additional Information:
Another reason why the pulling of the information from the DB has to be done in code is that not every computer this is loaded on will have Excel on it. The person using the application may simply be told to export the data and email it to their supervisor. The setup app includes the needed dlls for the application to make the proper format.

Example Code (Current):

    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

Now, this is only example code in terms of the iteration I'm doing. Where I'm really processing the information from the database I'm iterating through a dataTable's Rows, then iterating through the items in the dataRow and doing essentially the same as above; value by value, selecting the range and putting the value in the cell, formatting the cell if it's part of a report (not always gray), and moving onto the next set of data. What I'd like to do is put all of the data in the excel sheet (A2:??, not a row, but multiple rows) then iterate through the reports and format each row then. That way, the only time I iterate through all of the records is when every record is part of a report.

Ideal Code

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

Update:

I know my examples were in VB, but it's because I was also trying to write a VB version of the application since my boss prefers VB. However, here's my final code using a Recordset. The ConvertToRecordset function was obtained from 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();
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深居我梦 2024-10-01 07:41:43

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

我会考虑这一系列事件:

  • 查询 SQLite 数据库中的数据集。
  • 将数据从 ADO.NET 对象移出并移入 POCO 对象。停止使用数据表/行。
  • 使用 For Each 插入到 Excel 中。

Perhaps post some code, and we might be able to track down any issues.

I'd consider this chain of events:

  • query the SQLite database for your dataset.
  • move the data out of ADO.NET objects, and into POCO objects. Stop using DataTables/Rows.
  • use For Each to insert into Excel.
云归处 2024-10-01 07:41:42

可以使用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 和内部样式表非常满意。

Can you use 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 is quite happy with HTML and internal style sheets.

尹雨沫 2024-10-01 07:41:42

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

更新:
还有许多库(免费和商业)可以使创建 Excel 文档变得更容易,例如 excellibrary< /a> 尚不支持新格式。 创建 Excel(.XLS 和 .XLSX)的答案中还提到了其他内容) 来自 C# 的文件

I have used the Excel XML file format in the past to write directly to an output file or stream. It may not be appropriate for your application, but writing XML is much faster and bypasses the overhead of interacting with the Excel Application. Check out this Introduction to Excel XML post.

Update:
There are also a number of libraries (free and commercial) which can make creating excel document easier for example excellibrary which doesn't support the new format yet. There are others mentioned in the answers to Create Excel (.XLS and .XLSX) file from C#

指尖凝香 2024-10-01 07:41:42

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

代码片段:

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

Excel has the facility to write all the data from a ADO or DAO recordset in a single operation using the CopyFromRecordset method.

Code snippet:

    Sheets("Sheet1").Range("A1").CopyFromRecordset rst
人│生佛魔见 2024-10-01 07:41:42

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

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

也许将流程重构为:

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

我不确定这是否是适合您的一组流程,但也许需要考虑一些事情?

I'd normally recommend using Excel to pull in the data from SQLite. Use Excel's "Other Data Sources". You could then choose your OLE DB provider, use a connection string, what-have-you.alt text

It sounds, however, that the real value of your code is the formatting of the cells, rather than the transfer of data.

Perhaps refactor the process to:

  • have Excel import the data
  • use your code to open the Excel spreadsheet, and apply formatting

I'm not sure if that is an appropriate set of processes for you, but perhaps something to consider?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文