需求:WCF搭建服务端提供导出并下载Excel文件接口,客户端使用ajax发起请求,浏览器直接下载Excel文件。
难点:WCF中并没有HttpContext对象,因此,服务端总是获取不到HttpContext.Current值。即HttpContext.Current=null。
使用WebFrom的方法已经不能实现需求了。
HttpContext.Current.Response.ContentType = "application/ms-excel";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" + HttpUtility.UrlEncode(excelConfig.FileName, Encoding.UTF8));
HttpContext.Current..Response.BinaryWrite(...);
HttpContext.Current..Response.End();
方案:兼容模式下,使用WebOperationContext.Current.OutgoingResponse
public Stream DownloadFileFromWCF()
{
Stream fileStream = null;
try
{
DataTable dtExport = null; //要导出的数据源
#region 转换为流
string fileString = ToStringCSV(dtExport, ",", true);
fileString = ToStringXLS(dtExport, false);
// byte[] array = Encoding.ASCII.GetBytes(fileString);//中文乱码
byte[] array = System.Text.Encoding.UTF8.GetBytes(fileString);//中文乱码
array = System.Text.Encoding.Default.GetBytes(fileString);
MemoryStream stream = new MemoryStream(array);
fileStream = stream;
#endregion
//从硬盘文件读取数据源
//string fileFullPath = @"C:UsersdellDesktop投注页相关接口.txt";
//fileStream = File.OpenRead(fileFullPath);
string saveFileName = "Test.xls";
//WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
//WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Encoding", "gzip");
//WebOperationContext.Current.OutgoingResponse.ContentType = "text/html; charset=utf-8";
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "attachment;filename=" + HttpUtility.UrlPathEncode(saveFileName));
}
catch (Exception ex)
{
}
return fileStream;
}
/// <summary>
/// dt转CSV格式文件字符串
/// </summary>
/// <param name="table"></param>
/// <param name="delimiter">分隔符=","</param>
/// <param name="includeHeader">是否包括数据表头</param>
/// <returns></returns>
private string ToStringCSV(DataTable dt, string delimiter, bool includeHeader)
{
var result = new StringBuilder();
if (includeHeader)
{
foreach (DataColumn column in dt.Columns)
{
result.Append(column.ColumnName);
result.Append(delimiter);
}
result.Remove(--result.Length, 0);
result.Append(Environment.NewLine);
}
string itemAsString = string.Empty;
foreach (DataRow row in dt.Rows)
{
foreach (object item in row.ItemArray)
{
itemAsString = string.Empty;
if (item is DBNull)
result.Append(delimiter);
else
{
itemAsString = item.ToString();
// Double up all embedded double quotes
itemAsString = itemAsString.Replace(""", """");
// To keep things simple, always delimit with double-quotes
// so we don't have to determine in which cases they're necessary
// and which cases they're not.
itemAsString = """ + itemAsString + """;
result.Append(itemAsString + delimiter);
}
}
result.Remove(--result.Length, 0);
result.Append(Environment.NewLine);
}
return result.ToString();
}
/// <summary>
/// dt转XLS格式文件字符串
/// </summary>
/// <param name="dt"></param>
/// <param name="includeHeader"></param>
/// <returns></returns>
private string ToStringXLS(DataTable dt, bool includeHeader)
{
var result = new StringBuilder();
string delimiter = "";
if (includeHeader)
{
foreach (DataColumn dc in dt.Columns)
{
result.Append(delimiter + dc.ColumnName);
delimiter = " ";
}
//result.Append("
");
result.Append(Environment.NewLine);
}
foreach (DataRow dr in dt.Rows)
{
delimiter = "";
for (int i = 0; i < dt.Columns.Count; i++)
{
result.Append(delimiter + dr[i].ToString());
delimiter = " ";
}
//result.Append("
");
result.Append(Environment.NewLine);
}
return result.ToString();
}