在c#中每500毫秒读取一个excel文件中的数据

时间:2016-07-04 09:15:06

标签: c# excel

我有一个包含一些记录的excel文件,以及在一秒钟内刷新的记录。我想将所有记录存储在SQL Server数据库中。所以我的意图是每隔500毫秒就将这个文件中的数据读入我的数据库。我已成功读取数据并存储在我的数据库中。但几分钟后,excel挂起并处于无响应状态。

Excel._Application excel = (Excel._Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
clsDBOLiveData objDBOLiveData = new clsDBOLiveData();
clsDatabase objDatabase = new clsDatabase();

private static System.Timers.Timer aTimerLive_1;
private static System.Timers.Timer aTimerHist_1;
private static System.Timers.Timer aTimerLive_2;
private static System.Timers.Timer aTimerHist_2;


//Here I declare all variables.

public TradeData()
{
    SetTimer1_Data();
    SetTimer2_Data();
    SetTimerHist_1_Data();
    SetTimerHist_2_Data();
}


private void SetTimerLiveMCX_1_Data()
{
    aTimerLive_1 = new System.Timers.Timer(500);
    aTimerLive_1.Elapsed += OnTimedEvent_1;
    aTimerLive_1.AutoReset = true;
    aTimerLive_1.Enabled = true;
}

private void OnTimedEvent_1(Object source, ElapsedEventArgs e)
{
    try
    {
        Excel.Workbook workbook = excel.Workbooks[1];
        Excel.Worksheet workSheet = workbook.Worksheets.get_Item(1);
        Excel.Range range = workSheet.UsedRange;
        for (int j = 3; j < range.Rows.Count; j = j + 5)
        {
            if ((range.Cells[j, 2] as Excel.Range).Value2 == null || Convert.ToString((range.Cells[j, 2] as Excel.Range).Value2)=="")
                continue;
            clsDBOLiveData objDBOLiveData = new clsDBOLiveData();
            objDBOLiveData.SYMBOL_NAME = (string)(range.Cells[j, 8] as Excel.Range).Value2;
            objDBOLiveData.BAR_TIME= (double)(range.Cells[j, 2] as Excel.Range).Value2;
            objDBOLiveData.HIGH= (decimal)(range.Cells[j, 3] as Excel.Range).Value2;
            objDBOLiveData.LAST = (decimal)(range.Cells[j, 4] as Excel.Range).Value2;
            objDBOLiveData.LOW = (decimal)(range.Cells[j, 5] as Excel.Range).Value2;
            objDBOLiveData.OPEN = (decimal)(range.Cells[j, 6] as Excel.Range).Value2;
            objDBOLiveData.VOLUME = (decimal)(range.Cells[j, 7] as Excel.Range).Value2;
            objDBOLiveData.STATUS = (string)(range.Cells[j, 9] as Excel.Range).Value2;
            string strErrorMgs = "";
            if (!objDatabase.SaveData_1(objDBOLiveData, ref strErrorMgs)){}
        }
    }
    catch(Exception ex)
    {
    }
}

2 个答案:

答案 0 :(得分:1)

处理对象.. Excel对象很重

答案 1 :(得分:0)

哦天哪,这里有几件事。

首先,正如其他读者所提到的那样。当您使用Excel COM对象时,必须释放它们。

以下是我如何设计代码的样式:

byte[] out = str.getBytes(StandardCharsets.UTF_8);

其次,我真的不相信同一行中包含Excel.Workbook workbook = null; Excel.Worksheet workSheet = null; Excel.Range range = null; try { workbook = excel.Workbooks[1]; workSheet = workbook.Worksheets.get_Item(1); range = workSheet.UsedRange; . . . } catch(Exception ex) { } finally { if (range != null) Marshal.FinalReleaseComObject(range); if (worksheet != null) Marshal.FinalReleaseComObject(worksheet); if (workbook != null) Marshal.FinalReleaseComObject(workbook); // Garbage collection GC.Collect(GC.MaxGeneration, GCCollectionMode.Default, false); } Excel.Range的所有行:

Value2

Google搜索&#34; Excel COM双点&#34; (很多)解释为什么这是一个坏主意。

就个人而言,如果您的所有数据都在一个工作表中,我建议您在整个工作表中阅读objDBOLiveData.SYMBOL_NAME = (string)(range.Cells[j, 8] as Excel.Range).Value2; 数组,然后循环显示其中的值。

object[,]

如果您的代码更容易使用,您也可以将此变量转换为object[,] cellValues = (object[,])range.Value2;

Array

一次性读取所有单元格数据效率更高,COM对象遗留的可能性更小。

最后一件事:小心System.Array arr = (System.Array)cellValues; int numOfRows = arr.GetUpperBound(0); int numOfColumns = arr.GetUpperBound(1);

UsedRange

我们已经举例说明这已经返回了巨大的范围(例如16,000列,当时实际上只有7列数据),这反过来会导致我们的代码崩溃,因为它试图迭代通过巨大的(空白)细胞范围。

阅读以下StackOverflow文章,以描述查找电子表格中哪些单元格确实包含数据的唯一安全方法:

Alternative to UsedRange

呼。