2010-05-11 30 views
0

我試圖創建一些數據的csv文件。我已經寫了一個函數,成功地做到這一點....在Streamwriter對象中使用本地文件路徑ASP.Net

Private Sub CreateCSVFile(ByVal dt As DataTable, ByVal strFilePath As String) 
     Dim sw As New StreamWriter(strFilePath, False) 
     ''# First we will write the headers. 
     ''#DataTable dt = m_dsProducts.Tables[0]; 
     Dim iColCount As Integer = dt.Columns.Count 
     For i As Integer = 0 To iColCount - 1 
      sw.Write(dt.Columns(i)) 
      If i < iColCount - 1 Then 
       sw.Write(",") 
      End If 
     Next 
     sw.Write(sw.NewLine) 
     ''# Now write all the rows. 
     For Each dr As DataRow In dt.Rows 
      For i As Integer = 0 To iColCount - 1 
       If Not Convert.IsDBNull(dr(i)) Then 
        sw.Write(dr(i).ToString()) 
       End If 
       If i < iColCount - 1 Then 
        sw.Write(",") 
       End If 
      Next 
      sw.Write(sw.NewLine) 
     Next 
     sw.Close() 

    End Sub 

問題是我沒有正確使用我想要完成的Streamwriter對象。由於這是一個asp.net,我需要用戶選擇一個本地文件路徑來放置文件。如果我傳遞了這個函數的任何路徑,它會嘗試將它寫入代碼所在的服務器上指定的目錄。我想這個彈出並讓用戶選擇他們的本地機器上的一個地方放文件....

Dim exData As Byte() = File.ReadAllBytes(Server.MapPath(eio)) 
     File.Delete(Server.MapPath(eio)) 
     Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fn)) 
     Response.ContentType = "application/x-msexcel" 
     Response.BinaryWrite(exData) 
     Response.Flush() 
     Response.End() 

我打電話這樣的代碼的第一個函數...

Dim emplTable As DataTable = SiteAccess.DownloadEmployee_H() 
    CreateCSVFile(emplTable, "C:\\EmplTable.csv") 

我不想指定文件位置(因爲這會將文件放在服務器上而不是客戶機上),而是讓用戶在其客戶機上選擇位置。

有人可以幫我把它放在一起嗎?提前致謝。

我已經重新創建了我的導出函數,現在它讓usr選擇一個下載路徑,但是下載的數據中的一列有「Doe,John」形式的數據,這一列被稱爲「EPLNME」輸出文件,因爲它讀取數據中的逗號,現在數據已關閉輸出文件中的一列可以有人幫我阻止這個特定的事件我不知道我怎麼能。這裏是代碼...

Private Sub ExportCSV(ByVal data As DataTable, ByVal nameOfFile As String) 
    Dim context As HttpContext = HttpContext.Current 
    context.Response.Clear() 
    context.Response.ContentType = "text/csv" 
    context.Response.AddHeader("Content-Disposition", "attachment; filename=" + nameOfFile + ".csv") 

    ''#Write column header names 
    For i = 0 To data.Columns.Count - 1 
     If (i > 0) Then 
      context.Response.Write(",") 
     End If 
     context.Response.Write(data.Columns(i).ColumnName) 
    Next 
    context.Response.Write(Environment.NewLine) 

    ''#Write data 
    For Each row As DataRow In data.Rows 
     For i = 0 To data.Columns.Count - 1 
      If (i > 0) Then 
       context.Response.Write(",") 
      End If 
      context.Response.Write(row.Item(i).ToString()) 
     Next 
     context.Response.Write(Environment.NewLine) 
    Next 
    context.Response.End() 

End Sub 
+0

我想對您的問題進行排序的格式這是非常難以理解的。 – Yoda 2010-05-11 16:10:34

回答

2

首先替換的最後一行,你需要重載你的函數這樣的,允許直接將您的輸出到任何一個流或路徑:

Private Sub CreateCSVFile(ByVal dt As DataTable, ByVal strFilePath As String) 
    Using sw As New StreamWriter(strFilePath) 
     CreateCSVFile(dt, sw) 
    End Using 
End Sub 

Private Sub CreateCSVFile(ByVal dt As DataTable, ByVal outStream As TextWriter) 
    ''# First we will write the headers. 
    Dim delimiter As String = String.Empty 
    For Each col As DataColumn in dt.Columns 
     outStream.Write(delimiter) 
     outStream.Write(col.ColumnName) 
     delimiter = "," 
    Next col   
    outStream.Write(outStream.NewLine) 

    int flushCount = 0; 

    ''# Now write all the rows. 
    For Each dr As DataRow In dt.Rows 
     delimiter = String.Empty 
     For i As Integer = 0 To dt.Columns.Count -1 
      outStream.Write(delimiter) 

      If Not Convert.IsDBNull(dr(i)) Then 
       outStream.Write("""") ''#Wrap fields in quotes to allow for commas in field data 

       ''# Need to escape the quotes as well 
       outStream.Write(dr(i).ToString().Replace("""", """""")) 

       outStream.Write("""") 
      End If 
      delimiter = "," 
     Next i 
     outStream.Write(outStream.NewLine) 

     ''# Flush the buffer periodically 
     flushCount += 1 
     If flushCount > 100 Then 
      outStream.Flush() 
      flushCount = 0 
     End If 
    Next dr 
End Sub 

請注意,您的函數與以前幾乎完全相同,但您現在可以寫入文件或直接寫入流,並且不必重新編寫大量代碼即可使其工作。幾乎所有你用文件編寫的東西都應該這樣寫。我還對代碼做了一些其他的改進,但最主要的是這樣一種方法,實際的工作應該是總是接受TextWriter,然後只要添加重載,如果你想能夠接受任何其他的文件路徑。

現在你能做的就是頭球奔羅賓遜的回答內容類型和並使用這個新的方法來直接寫asp.net響應緩衝區:

Response.ContentType = "text/csv"; 
Response.AddHeader("Content-Disposition", "attachment; filename=NameOfFile"); 
CreateCSVFile(SiteAccess.DownloadEmployee_H(), Response.Output) 
Response.Flush() 
Response.End() 
+0

它告訴我響應不是TextWriter對象 – 2010-05-11 16:55:44

+0

@Nick - 糟糕,固定那個函數調用。我需要'Response.Output'。 – 2010-05-11 16:57:23

+0

我想我創造了適當的功能,但仍然不得不處理員工姓名的數據格式爲「Doe,John」這個逗號正在搞亂我的功能。查看編輯的問題。謝謝你的幫助! – 2010-05-11 16:58:17

0

您可以使用MemoryStream將二進制數據保存在服務器上,而不是將它們寫入文件。

1)寫淵希望把在CSV爲在需要時從MemoryStream的讀入響應內存流

2)中的內容。

希望它有幫助!

1

你真的不喜歡一個Streamwriter,它是用來在代碼運行的機器上創建文件的。使用StringBuilder建立表示CSV字符串文件,然後執行以下操作:

Response.ContentType = "text/csv"; 
Response.AddHeader("Content-Disposition", "attachment; filename=NameOfFile"); 
Response.Write(MyStringBuilder.ToString()); 

如果你需要創建一個文件,因爲你需要將其存儲在服務器上,也將其發送給用戶。創建文件,你正在做的和與

Response.TransmitFile("filePath");