2014-04-15 65 views
2

使用Max Galkin提供的解決方案,我將以下過程將ListView中的所有數據傳輸到.CSV文件。我在用2份然而問題:通過C#在Excel中打開一個CSV文件?

  1. 我還沒有想出如何成功地打開新創建的.CSV當用戶點擊YES在適當的對話。
  2. 似乎有些用戶(在Virtual PC上與我不同)無法打開或查看新文件,除非他們首先關閉應用程序。我相信這是由於應用程序仍然有一個與創建文件相關的進程。出現試圖打開該文件時,該消息是:'FileName.csv' cannot be accessed. The file may be corrupted, located on a server that is not responding, or read-only.

這裏是我當前的代碼:

private void btnCSVExcel_Click(object sender, EventArgs e) 
     { 
      if (!Directory.Exists(@"C:\TEMP\")) 
      { 
       Directory.CreateDirectory(@"C:\temp\"); 
      } 
      if (!Directory.Exists(@"C:\temp\Exported CSV Files\")) 
      { 
       Directory.CreateDirectory(@"C:\temp\Exported CSV Files\"); 
      } 

      string csvPath = @"C:\temp\Exported CSV Files\"; 

      ListViewToCSV(lvData, csvPath, false); 
     } 

     // https://stackoverflow.com/questions/1008556/export-listview-to-csv 
     public static void ListViewToCSV(ListView listView, string filePath, bool includeHidden) 
     { 
      string csvFileName = filePath + DateTime.Now.ToString("yyyy-MM-dd-hh.mm.ss.ffffff") + ".csv"; 

      //make header string 
      StringBuilder result = new StringBuilder(); 
      WriteCSVRow(result, listView.Columns.Count, i => includeHidden || listView.Columns[i].Width > 0, i => listView.Columns[i].Text); 

      //export data rows 
      foreach (ListViewItem listItem in listView.Items) 
      { 
       WriteCSVRow(result, listView.Columns.Count, i => includeHidden || listView.Columns[i].Width > 0, i => listItem.SubItems[i].Text); 
      } 

      File.WriteAllText(csvFileName, result.ToString()); 

      var openCSVFile = MessageBox.Show("Export Complete. CSV file saved as: " + csvFileName + ". \n\n Open File Now?", "CSV Exported", MessageBoxButtons.YesNo, MessageBoxIcon.Information); 
      if (openCSVFile == DialogResult.Yes) 
      { 
       // NEED TO OPEN THE CSV FILE IN EXCEL....? 
       File.Open(csvFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
      } 
     } 

     private static void WriteCSVRow(StringBuilder result, int itemsCount, Func<int, bool> isColumnNeeded, Func<int, string> columnValue) 
     { 
      bool isFirstTime = true; 
      for (int i = 0; i < itemsCount; i++) 
      { 
       if (!isColumnNeeded(i)) 
        continue; 

       if (!isFirstTime) 
        result.Append(","); 
       isFirstTime = false; 

       result.Append(String.Format("\"{0}\"", columnValue(i))); 
      } 
      result.AppendLine(); 
     } 

任何人有我怎麼可能解決這些過去2個問題有什麼想法?我認爲File.Open()可能足以解決第一個問題,但在視覺上沒有任何問題,並且文檔無法打開。

+0

[This](https://stackoverflow.com/a/46590110/3967709)爲我工作。 – Gokul

回答

9

1)Excel中的寄存器:

using Excel = Microsoft.Office.Interop.Excel; 

然後,您可以通過使用此代碼打開CSV文件本身作爲.csv文件的默認處理程序。打開使用該類型的默認文件處理程序的任何文件,只是這樣做:

Process.Start(@"c:\full\path\to\file.csv"); 

2)File.WriteAllText應在年底關閉文件。您在上面顯示的代碼也有一行,其內容爲File.Open(csvFileName...,以獨佔寫入模式打開文件。由於您沒有關閉該文件,Excel無法打開它,直到a)進程終止或b)文件被垃圾收集器關閉。我敢打賭,垃圾收集器在發生拒絕訪問錯誤的情況下還沒有運行。

最終推薦:刪除File.Open並替換爲Process.Start,您可能會看到不同的結果。

+0

感謝您的迴應邁克爾!我根據您對Sebs解決方案的意見和您的觀點差異嘗試瞭解決方案問題1。它似乎在工作。實際上,我從一個不同的導出過程中引用了Excel Interop,但是由於我的用戶沒有足夠的處理能力在虛擬機上直接將所有數據加載到Excel電子表格中,所以我確實有一個超時。(對於普通PC用戶工作得很好)。關於問題#2的任何想法? –

+0

剛剛在#2上看到了你的部分,對不起。我會給它一個鏡頭! –

+0

感謝Michael的幫助!這似乎已經訣竅:) –

8

您需要參考您的項目添加到Microsoft Excel的互操作庫:

static void OpenCSVWithExcel(string path) 
    { 
     var ExcelApp = new Excel.Application(); 
     ExcelApp.Workbooks.OpenText(path, Comma:true); 

     ExcelApp.Visible = true; 
    } 
+0

這將工作,但它很容易出錯,需要額外的依賴。我建議對csv文件使用'Process.Start'而不是使用自動化。 –

+1

我看到了你的答案,但我不同意你的看法。 Process.Start將使用Windows中的默認應用程序啓動CSV。如果用戶使用文本板映射CSV文件,則該文件不會在Excel中打開。 – Seb

+0

同意。在我絕對需要這種工作的情況下,我手動查找註冊表項'HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ App Paths \ excel.exe'的默認值並手動啓動該過程。自動化只是有很多問題。 (在這裏有13年的Office自動化經驗。) –