2010-05-11 2 views
0

J'essaie de créer un fichier csv de certaines données. Je l'ai écrit une fonction qui fait avec succès cette ....Utilisation d'un chemin de fichier local dans un objet 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 

Le problème est que je ne suis pas en utilisant l'objet StreamWriter correctement ce que je tente d'accomplir. Comme il s'agit d'un asp.net j'ai besoin que l'utilisateur sélectionne un chemin de fichier local pour mettre le fichier. Si je passe un chemin à cette fonction, il va essayer de l'écrire dans le répertoire spécifié sur le serveur où le code est. Je voudrais que cela popups et laisser l'utilisateur de sélectionner un endroit sur leur machine locale pour mettre le fichier ....

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

J'appelle la première fonction dans le code comme ça ...

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

Où je ne veux pas avoir à spécifier le fichier loaction (parce que cela va mettre le fichier sur le serveur et non sur une machine client) mais plutôt laisser l'utilisateur sélectionner l'emplacement sur leur machine client.

Quelqu'un peut-il m'aider à mettre cela ensemble? Merci d'avance.

J'ai recréé ma fonction d'exportation et maintenant il permet à l'usr de sélectionner un chemin de téléchargement, mais une colonne dans les données téléchargées a des données sous la forme de "Doe, John" cette colonne est appelée "EPLNME" le fichier de sortie parce que sa lecture de la virgule dans les données et maintenant les données sont désactivées par une colonne dans le fichier de sortie peut quelqu'un m'aider à arrêter cet incident spécifique je ne sais pas comment je peux. Voici le code ...

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

Je trierait la mise en forme sur votre question out, c'est très illisible. – Yoda

Répondre

2

D'abord, vous devez surcharger votre fonction comme celui-ci, pour permettre l'envoi de votre sortie directement soit à un flux ou un chemin:

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 

Notez que votre fonction fonctionne à peu près exactement comme avant, mais vous pouvez maintenant écrire dans un fichier ou directement dans un flux et vous n'avez pas besoin de réécrire beaucoup de code pour le faire fonctionner. Presque tout ce que vous écrivez qui fonctionne avec des fichiers doit être écrit de cette façon. J'ai fait quelques autres améliorations au code aussi, mais la chose principale est la méthode que le travail réel devrait toujours accepter un TextWriter puis ajouter des surcharges si vous voulez être en mesure d'accepter quelque chose d'autre comme un chemin de fichier .

Maintenant, ce que vous pouvez faire est de prendre le type de contenu et en-tête de la réponse de Ben Robinson et utiliser cette nouvelle méthode pour écrire directement dans la mémoire tampon de réponse asp.net:

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

son me dire Réponse n'est pas un objet TextWriter –

+0

@Nick - Oups, fixe cet appel de fonction. J'avais besoin de "Response.Output" là. –

+0

Je pense que j'ai créé la fonction appropriée, mais encore avoir à traiter avec les noms des employés ont des données dans le format de "Doe, John" cette virgule gâche ma fonction. Voir la question éditée. Merci de votre aide! –

0

Vous pouvez utiliser un MemoryStream pour contenir les données binaires sur le serveur, au lieu de les écrire dans un fichier.

1) le contenu youn voulez mettre dans le fichier CSV dans le flux de mémoire

2) Lire le MemoryStream dans la réponse au besoin.

J'espère que ça aide!

1

Vous, ne lisez pas vraiment un streamwriter, c'est pour créer des fichiers sur la machine où le code est en cours d'exécution. Utilisez un StringBuilder pour construire la chaîne qui représente le fichier CSV puis procédez comme suit:

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

Si vous avez besoin de créer un fichier parce que vous devez stocker sur le serveur et transmettre également à l'utilisateur. Créez le fichier que vous faites et remplacer la dernière ligne avec

Response.TransmitFile("filePath"); 
Questions connexes