1

基本上我需要将一堆数据插入到 Excel 文件中。创建 OleDB 连接似乎是最快的方法,但我发现遇到了内存问题。当我执行 INSERT 查询时,进程使用的内存似乎在不断增长。我已将它们缩小到仅在输出到 Excel 文件时发生(内存保持稳定而没有输出到 Excel)。我关闭并重新打开每个工作表之间的连接,但这似乎对内存使用没有影响(Dispose() 也是如此)。数据写入成功,因为我可以使用相对较小的数据集进行验证。如果有人有见识,将不胜感激。

在构造函数中调用initializeADOConn()

initADOConnInsertComm()创建插入参数化插入查询

每当写入新记录时都会调用writeRecord() 。根据需要创建新工作表。

public bool initializeADOConn()
        {
            /* Set up the connection string and connect.*/
            string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
                "Data Source=" + this.destination + ";Extended Properties=\"Excel 8.0;HDR=YES;\"";
            //DbProviderFactory factory =
                //DbProviderFactories.GetFactory("System.Data.OleDb");
            conn = new OleDbConnection(connectionString);
            conn.ConnectionString = connectionString;
            conn.Open();

            /* Intialize the insert command. */
            initADOConnInsertComm();
            return true;
        }
    public override bool writeRecord(FileListerFileInfo file)
            {
                /* If all available sheets are full, make a new one. */
                if (numWritten % EXCEL_MAX_ROWS == 0)
                {
                    conn.Close();
                    conn.Open();
                    createNextSheet();
                }
                /* Count this record as written. */
                numWritten++;
                /* Get all of the properties of the FileListerFileInfo record and add
                 * them to the parameters of the insert query. */
                PropertyInfo[] properties = typeof(FileListerFileInfo).GetProperties();
                for (int i = 0; i < insertComm.Parameters.Count; i++)
                    insertComm.Parameters[i].Value = properties[i].GetValue(file, null);
                /* Add the record. */
                insertComm.ExecuteNonQuery();

                return true;
            }

编辑:

不,我根本不使用 Excel。我故意避免使用 Interop.Excel,因为它的性能很差(至少从我对它的涉猎来看)。

4

3 回答 3

2

答案是肯定的,你描述的公式确实等于一个糟糕的时间。

如果您有一个方便的数据库(SQL Server 或 Access 很适合),您可以在数据库表中执行所有插入操作,然后将表一次全部导出到 Excel 电子表格中。

一般来说,数据库擅长处理大量插入,而电子表格则不然。

于 2008-11-11T06:07:26.127 回答
1

这里有几个想法:

目标工作簿是否打开?有一个错误(当您使用 ActiveX 数据对象查询打开的 Excel 工作表时会发生内存泄漏),IIRC 实际上位于 Jet(您正在使用的)的 OLE DB 提供程序中,尽管在上面的文章中没有确认这一点。

无论如何,批量插入似乎是要走的路。

您可以使用相同的 Jet OLE DB 提供程序来执行此操作:您所需要的只是一个单行表。你甚至可以即时制造一个。要创建新的 Excel 工作簿,CREATE TABLE请使用连接字符串中不存在的 xls 文件执行 DDL,提供程序将为您创建工作簿,并使用工作表来表示表格。您已连接到 Excel 工作簿,因此您可以执行以下操作:

CREATE TABLE [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable 
(
   x FLOAT
);

(更好的 IMO 将是制作一个 Jet 数据库,即 .mdb 文件)。

用于INSERT创建虚拟行:

INSERT INTO [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable (x) 
   VALUES (0);

然后,仍然使用与目标工作簿的连接,您可以使用类似于以下内容的内容INSERT一次性创建您的值的派生表 (DT1):

INSERT INTO MyExcelTable (key_col, data_col)
SELECT DT1.key_col, DT1.data_col
FROM (
   SELECT 22 AS key_col, 'abc' AS data_col
   FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable
   UNION ALL
   SELECT 55 AS key_col, 'xyz' AS data_col
   FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable
   UNION ALL
   SELECT 99 AS key_col, 'efg' AS data_col
   FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable
) AS DT1;
于 2008-11-11T08:39:59.033 回答
0

除了一次写入一条记录,您能找到一种插入批量容量的方法吗?我尽量不使用疯狂的 DataSet 东西,但是有没有办法让你的所有插入首先发生在本地,然后让它们一举上去?此过程是否在后台打开 Excel?这些过程之后会死吗?

于 2008-11-11T05:16:05.513 回答