2016-08-18 76 views
0

我想加载一个CSV或TSV到Excel中,并且对于小文件它工作得很好;小文件是< 5kb。问题是,当我尝试将更大的文件加载到Excel中时,该过程可能需要很长时间。我需要应用程序加载的文件可以包含5到100列的任何地方,并且可以包含5到20000行。快速加载文本到excel

我已经尝试过使用BackgroundWorker,Threadpools,Parallel.For,Parallel.ForEach,但它们似乎都具有与此任务相同的性能。

该应用程序本身旨在从单独的文本文件中获取标题列表,然后将其加载到Excel中,应用格式设置,然后将实际的CSV/TSV文件加载到Excel中。

这是我到目前为止,这一分得到由后台工作拉开序幕:

Private Sub LoadTextFile(ByVal xlApp As Excel.Application, ByVal xlWb As Excel.Workbook, ByVal xlWs As Excel.Worksheet, ByVal xlRange As Excel.Range) 
    Dim SheetName As String = "Sheet1" 
    If xlWs Is Nothing Then 
     xlWs = DirectCast(xlWb.Sheets.Add(After:=xlWb.Sheets(xlWb.Sheets.Count), Count:=1, Type:=Excel.XlSheetType.xlWorksheet), Excel.Worksheet) 
    End If 

    'Read lines and store in a string array 
    Dim lines() As String = File.ReadAllLines(FileToLoad) 

    'Parse and write lines to Excel 
    For i As Integer = 0 To lines.Length - 1 
     'Set new row range 
     xlRange = xlWs.Range(startCol + (i + 2).ToString + ":" + endCol + (i + 2).ToString) 

     'Parse the line to load 
     Dim lineDetail() As String = lines(i).Split(fileDelimiter) 

     'Load into Excel 
     xlRange.Value = lineDetail 
    Next 
End Sub 

下面是一些执行时间:

89列 - 2000行:平均加载时间= 7秒。

89列 - 4,000行:平均加载时间= 12秒。

91列 - 10,000行:平均加载时间= 28秒。

91列 - 24,000行:平均加载时间= 70秒。

107列 - 8,732行:平均加载时间= 17秒。

我一直在想,“Excel如何几乎立即加载这些文件?!?”无论如何,我会非常感激任何能够帮助我优化这一点的人,因此将数据导入Excel并不需要很长时间。先谢谢你。

+1

'“Excel如何加载这些文件几乎立即?!? '你有没有想过使用Excel的宏记录器来获取导入文件的命令? – TnTinMn

+0

@TnTinMn我有,但我不认为它足够灵活。我将不得不为每个我需要的不同格式创建48个不同的宏。我还需要尽可能让用户使用它。我拥有的用户群不知道如何使用Excel宏。最后,我需要一种每年更新2个列的方法,我不想每年重新创建48个宏2次。它现在的工作方式是从文本文件中提取标题,并且可以非常容易地进行更新。 –

+0

我不是在建议您将VB.Net应用程序转换为一组Excel宏。我试图教你使用宏记录器来发现你可能不知道的Excel对象模型命令。将VBA Interop语句转换为.Net Interop语句只需一点点努力。 – TnTinMn

回答

0

这是我想出来的,我认为它工作得很好。感谢TnTinMn为我指出正确的方向:)

Dim xlApp As New Excel.Application 
    Dim xlWb As Excel.Workbook 
    Dim xlWs As Excel.Worksheet 
    Dim xlRange As Excel.Range 

    'Start Excel and Create Application Object 
    xlApp = CreateObject("Excel.Application") 

    'Set invisible until all loading is completed 
    xlApp.Visible = False 

    'Get/Set references of active workbook/sheet 
    xlWb = xlApp.Workbooks.Add 
    xlWb = xlApp.ActiveWorkbook 
    xlWs = xlWb.ActiveSheet 
    xlRange = xlWs.Range("$A$1") 

    'Used to specify the data type for each column. 2 = Text 
    Dim array = New Object() {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _ 
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 _ 
     , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _ 
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} 

    'TextFilePlatform ANSI: 1252 
    With xlWs.QueryTables.Add(Connection:="TEXT;" + cfg.filePath, Destination:=xlRange) 
     .Name = "sec" 
     .FieldNames = True 
     .RowNumbers = False 
     .FillAdjacentFormulas = False 
     .PreserveFormatting = True 
     .RefreshOnFileOpen = False 
     .RefreshStyle = Excel.XlCellInsertionMode.xlInsertDeleteCells 
     .SavePassword = False 
     .SaveData = True 
     .AdjustColumnWidth = True 
     .RefreshPeriod = 0 
     .TextFilePromptOnRefresh = False 
     .TextFilePlatform = 1252 
     .TextFileStartRow = 1 
     .TextFileParseType = Excel.XlTextParsingType.xlDelimited 
     .TextFileTextQualifier = Excel.XlTextQualifier.xlTextQualifierDoubleQuote 
     .TextFileConsecutiveDelimiter = False 
     .TextFileTabDelimiter = cfg.fileTSV 
     .TextFileSemicolonDelimiter = False 
     .TextFileCommaDelimiter = cfg.fileCSV 
     .TextFileSpaceDelimiter = False 
     .TextFileColumnDataTypes = array 
     .TextFileTrailingMinusNumbers = True 
     .Refresh(BackgroundQuery:=False) 
    End With 

    'Add headers do formatting here 
    '<Additional Worksheet formats here> 

    xlApp.Visible = True