2016-08-18 88 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