我正在将一堆FOXPRO / FOXWEB应用转换为ASP.NET。
底层数据库仍然是foxpro(暂时)。
我正在将表传递给一些VB.NET代码,我希望将其转换为CSV文件并发送回客户端进行下载。它的工作原理!排序...它有时会起作用,但在其他时候,它不是问我是否要下载CSV文件,而是将文件喷出到浏览器窗口。
在asp方面,我传递了响应对象,表和csv文件名。
<%
Dim xls_fn As String = "test01.csv"
'OLEDB call to fill up 'tbl' ... this works.
sendTableAsCSVtoClient(response, tbl, xls_fn)
%>
在文件clsCommon.vb中,我有以下代码:
Option Explicit On
'Option Strict On
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.Page
Imports System.IO
Imports Microsoft.VisualBasic
Imports System.Diagnostics
Imports System.Data
Imports System.Data.OleDb
Public Class clsCommon
Inherits Page
Public Shared Function enq(ByVal str As String) As String
Dim dq As String
dq = """"
Return dq & str & dq
End Function
' some other functions and subs defined in here ... blah blah blah
' ...
Public Shared Function sendTableAsCSVtoClient(ByVal resp As HttpResponse, ByVal sqlTable As DataTable, ByVal xls_fn As String) As Boolean
Dim r As DataRow
Dim c As DataColumn
Dim sep As String = ","
Dim FileExtension As String
Dim lcFileNameONLY As String
Dim i As Integer
Dim dq As String = """"
FileExtension = UCase(Path.GetExtension(xls_fn))
lcFileNameONLY = UCase(Path.GetFileNameWithoutExtension(xls_fn))
resp.Clear()
resp.ClearContent()
resp.ClearHeaders()
resp.ContentType = "application/vnd.ms-excel"
resp.AddHeader("Content-Disposition", "inline; filename=" & lcFileNameONLY & ".csv")
For Each c In sqlTable.Columns
resp.Write(UCase(c.ColumnName) & sep)
Next
resp.Write(vbCrLf)
For Each r In sqlTable.Rows
For i = 0 To sqlTable.Columns.Count - 1
resp.Write(enq(r(i)) & sep)
Next
resp.Write(vbCrLf)
Next
resp.End()
Return True
End Function
End Class
我猜测数据源是一个表并不重要。 请注意,该文件是即时创建的,并且从不存在于服务器的文件系统中。
TX, TFF
答案 0 :(得分:2)
使用Content-Disposition
而不是使用Inline
的{{1}}标头,而是始终提示下载。
更改以下行:
Attachment
到
resp.AddHeader("Content-Disposition", "inline; filename=" & lcFileNameONLY & ".csv")
内联类型意味着浏览器可以自由呈现内联(在浏览器中),如果在知道如何。
请参阅this问题,询问为什么resp.AddHeader("Content-Disposition", "attachment; filename=" & lcFileNameONLY & ".csv")
有时会提示下载(与您的问题完全相反......)。
答案 1 :(得分:1)
问题是您的Content-disposition
标题。它应该是"attachment"
而不是"inline"
。
您可能还想将内容类型设置为"text/csv"
而不是"application/vnd.ms-excel"
。通过这种方式,您可以更加准确,如果他们更喜欢使用其他内容来处理CSV,那么它应该会更好。但是对于内部应用程序,也许vnd.ms-excel可能会更好用吗?
答案 2 :(得分:1)
我同意Oded和chmullig你应该改变Content-Disposition,但是我也建议使用缓冲区并用flush来完成响应:
resp.Clear()
resp.Buffer = true
'build csv
resp.Flush()
resp.Close()
我相信对.End()的调用会抛出一个ThreadAbortException来停止执行,这可能会导致问题,具体取决于您处理异常的方式。 See here for more info