读取Excel单元格需要花费大量时间

时间:2015-11-25 20:29:09

标签: c# excel performance

我有一个Excel文件,它有360行和181列(65,160个单元格)。大多数细胞都是空的,我只想保存非空细胞。

主要问题是,当我运行我的代码时,处理所有单元格大约需要六分钟,并且应该为3,000个Excel文件执行此过程。我在form_load事件中写了这段代码:

        Excel.Application xlapp;
        Excel.Workbook xlwb;
        Excel.Worksheet xlws;

        object misValue = System.Reflection.Missing.Value;

        xlapp = new Excel.Application();
        xlwb = xlapp.Workbooks.Open("test.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
        xlws = (Excel.Worksheet)xlwb.Worksheets.get_Item(1);

        int i = 0;
        int j = 0;

        Int32 last_row = Convert.ToInt32(xlws.UsedRange.Rows.Count);
        Int32 last_column = Convert.ToInt32(xlws.UsedRange.Columns.Count);

        label1.Text = "";

        for ( j = 1; j <=last_row; j++)
        {
            for ( i = 1; i <= last_column; i++)
            {
                if (xlws.Cells[j,i].value != null)
                {
                    label1.Text = label1.Text + xlws.Cells[j, i].value.ToString();
                }
            }
            label1.Text += "\n";
        }

        xlwb.Close(true, misValue, misValue);
        xlapp.Quit();

        releaseObject(xlws);
        releaseObject(xlwb);
        releaseObject(xlapp);

这是我的releaseObject函数:

        private void releaseObject(object obj)
    {

        try
        {System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
         obj = null;}

        catch (Exception ex)
        {obj = null;
         MessageBox.Show("Unable to release the Object " + ex.ToString());}

        finally

        {GC.Collect();}

    }  

有没有办法减少浪费的时间?

2 个答案:

答案 0 :(得分:1)

我的公司有几个访问Excel工作簿的内部工具。有几种方法可以做到这一点。将工作簿作为数据源处理并使用OleDb查询它可以很好地工作。根据我的经验,它比使用Excel Automation快得多。以下是来自现有项目的一些示例代码。它查询具有2个电子表格的工作簿,一个用于度量单位,一个用于英制(英制)单位。希望它有所帮助...

// get Excel file that should be imported
string strFilePath = "";
this.openFileDialog.Title = "Select Excel File For Importing";
this.openFileDialog.Filter = "Excel Files|*.xls;";
this.openFileDialog.CheckFileExists = true;
this.openFileDialog.Multiselect = false;
this.openFileDialog.ShowDialog();
strFilePath = this.openFileDialog.FileName;
this.txtExcelFileName.Text = this.openFileDialog.FileName;

string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strFilePath + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;ImportMixedTypes=Text;\"";
System.Data.OleDb.OleDbDataAdapter dataAdapterExcel = new System.Data.OleDb.OleDbDataAdapter();
System.Data.OleDb.OleDbConnection oledbConnection = new System.Data.OleDb.OleDbConnection(strConnectionString);
DataTable tblEnglishTab = new DataTable("English");
DataTable tblMetricTab = new DataTable("Metric");
DataSet datasetExcelData = new DataSet();

oledbConnection.Open();
System.Data.OleDb.OleDbCommand cmdselect = new System.Data.OleDb.OleDbCommand();

try
{
    cmdselect.CommandText = "SELECT * FROM [English$A1:N10000]";
    cmdselect.Connection = oledbConnection;
    dataAdapterExcel.SelectCommand = cmdselect;
    dataAdapterExcel.Fill(tblEnglishTab);
    datasetExcelData.Tables.Add(tblEnglishTab);
}    
catch (Exception)
{
    MessageBox.Show("Please verify the Excel file type.\nUnable to locate the English worksheet in the specified file."Excel Import", MessageBoxButtons.OK, MessageBoxIcon.Error);
}    
try
{
    cmdselect.CommandText = "SELECT * FROM [Metric$A1:N10000]";
    cmdselect.Connection = oledbConnection;
    dataAdapterExcel.SelectCommand = cmdselect;
    dataAdapterExcel.Fill(tblMetricTab);
    datasetExcelData.Tables.Add(tblMetricTab);
}
catch (Exception)
{
    MessageBox.Show("Please verify the Excel file type.\nUnable to locate the Metric worksheet in the specified file.", "Excel Import", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
oledbConnection.Close();
dataAdapterExcel = null;

答案 1 :(得分:0)

  

String对象是不可变的。每次使用其中一种方法   在System.String类中,您在内存中创建一个新的字符串对象,   这需要为新对象重新分配空间。

从excel填充数据时使用StringBuilder,然后将其放入label1.Text

以下是示例:

label1.Text = "";

StringBuilder excelContent = new StringBuilder();

for ( j = 1; j <=last_row; j++)
{
    for ( i = 1; i <= last_column; i++)
    {
        if (xlws.Cells[j,i].value != null)
        {
            excelContent.Append(xlws.Cells[j, i].value.ToString());
        }
    }
    excelContent.Append("\n");
}

label1.Text = excelContent.ToString();

您可以详细了解StringBuilder here