### 通过C＃在Excel中打开CSV文件？

#### [英]Open a CSV file in Excel via C#?

Using a solution presented by Max Galkin, I put together the following procedure which transfers all data in a ListView to a .CSV file. I'm having issues with 2 parts however:

1. I have not figured out how to successfully open the newly created .CSV when user clicks YES on the appropriate dialogue.
2. 当用户在相应的对话框上单击“是”时，我还没有想出如何成功打开新创建的.CSV。
3. It seems that some users (on Virtual PC's unlike myself) are not able to open or view the the new file unless they first close down the application. I believe this is due to the Application still having a process tied to the created file. The message that appears when trying to open the file is: 'FileName.csv' cannot be accessed. The file may be corrupted, located on a server that is not responding, or read-only.
4. 似乎有些用户（在Virtual PC上与我不同）无法打开或查看新文件，除非他们首先关闭应用程序。我相信这是由于应用程序仍然有一个与创建的文件绑定的进程。尝试打开文件时出现的消息是：'FileName.csv'无法访问。该文件可能已损坏，位于未响应的服务器上或只读。

Here is my current code:

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";

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....?
}
}

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();
}


Anyone have any thoughts for how I might resolve these last 2 issues? I thought File.Open() may suffice for the first issue, but visually nothing occurs and the document does not open.

## 2 个解决方案

### #1

10

1) Excel registers itself as the default handler for .csv files. To open any file using the default file handler for the type, just do this:

1）Excel将自身注册为.csv文件的默认处理程序。要使用类型的默认文件处理程序打开任何文件，只需执行以下操作：

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


2) File.WriteAllText should close the file at the end. The code you show above also has a line that reads File.Open(csvFileName... that opens the file in exclusive write mode. Since you don't close that file, Excel can't open it until either a) the process terminates or b) the file is closed by the garbage collector. I bet the garbage collector hasn't yet run in cases where the access-denied error occurs.

2）File.WriteAllText应该在最后关闭文件。您在上面显示的代码也有一行读取File.Open（csvFileName ...以独占写入模式打开文件。由于您不关闭该文件，Excel无法打开它，直到a）进程终止或b）垃圾收集器关闭文件。我敢打赌，在发生访问拒绝错误的情况下，垃圾收集器尚未运行。

Final recommendation: Remove the File.Open and replace with Process.Start and you may see different results.

### #2

8

You need to add a reference to the Microsoft Excel Interop library in your project :

using Excel = Microsoft.Office.Interop.Excel;


Then you can open the CSV file by using this code :

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

ExcelApp.Visible = true;
}