在Streamwriter对象ASP.Net中使用本地文件路径

时间:2010-05-11 16:07:36

标签: c# asp.net vb.net

我正在尝试创建一些数据的csv文件。我写了一个成功完成此功能的函数....

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

我不希望指定文件loaction(因为这会将文件放在服务器而不是客户端计算机上),而是让用户在客户端计算机上选择位置。

有人可以帮我把它放在一起吗?提前谢谢。

我已经重新创建了我的导出功能,现在它让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

3 个答案:

答案 0 :(得分: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然后只是添加重载如果你想成为能够接受其他任何文件路径。

现在你可以做的是从Ben Robinson的回答中获取内容类型和标题,并使用这个新方法直接写入asp.net响应缓冲区:

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

答案 1 :(得分:1)

你真的没有一个编写器,那就是在运行代码的机器上创建文件。使用StringBuilder构建表示CSV文件的字符串,然后执行以下操作:

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

如果确实需要创建文件,因为您需要将其存储在服务器上并将其传输给用户。正如您所做的那样创建文件,并用

替换最后一行
Response.TransmitFile("filePath");

答案 2 :(得分:0)

您可以使用MemoryStream将二进制数据保存在服务器上,而不是将其写入文件。

1)将您想要放入CSV的内容写入内存流

2)在需要时从MemoryStream读取响应。

希望它有所帮助!