System.Net.ConnectStream 转换为 MemoryStream 内存流
项目经理来了一份奇特要求:
在asp.net 2.0 webfrom 的老项目页面上去调用 .net 4.0的webapi接口去下载Excel 哈哈 脑洞大开
非常迅速的创建了一个接口 返回Excel转换的数据流代码如下:
[HttpPost] public HttpResponseMessage ExportQuoteReport(ExportQuoteCountModel searchModel) { try { List<string> listtitle = new List<string>() { "群(", "本部", "事业部", "实施", "资源", "名称", "项目编号", "项目名称", "客户", "状态","TS天数","正常报天数","0天数","无天数", "负责人编号", "负责人" }; var list = ReportService.GetQuoteReportForExcel(searchModel); IWorkbook book = new XSSFWorkbook(); ISheet sheet = book.CreateSheet("Sheet1"); IRow rowTitle = sheet.CreateRow(0); ICellStyle style = book.CreateCellStyle(); for (int i = 0; i < listtitle.Count; i++) { rowTitle.CreateCell(i).SetCellValue(listtitle[i]); } for (int i = 0; i < list.Count; i++) { var m = list[i]; IRow row = sheet.CreateRow(i + 1); row.CreateCell(0).SetCellValue(m.BG); row.CreateCell(1).SetCellValue(m.BD); row.CreateCell(2).SetCellValue(m.BU); row.CreateCell(3).SetCellValue(m.CC); row.CreateCell(4).SetCellValue(m.ResNo); row.CreateCell(5).SetCellValue(m.ResName); row.CreateCell(6).SetCellValue(m.PrjCode); row.CreateCell(7).SetCellValue(m.PrjName); row.CreateCell(8).SetCellValue(m.ClientGroupName); row.CreateCell(9).SetCellValue(m.ContractStatus); row.CreateCell(10).SetCellValue(m.TSFillDay); row.CreateCell(11).SetCellValue(m.NormalQuoteDay); row.CreateCell(12).SetCellValue(m.ZeroQuoteDay); row.CreateCell(13).SetCellValue(m.NoQuoteDay); row.CreateCell(14).SetCellValue(m.PrjResEmpNo); row.CreateCell(15).SetCellValue(m.PrjResEmpName); } NpoiMemoryStream ms = new NpoiMemoryStream(); ms.AllowClose = false; book.Write(ms); ms.Flush(); ms.Seek(0, SeekOrigin.Begin); ms.AllowClose = true; //测试用保存到本地 //byte[] bytes = ms.GetBuffer(); //var testPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log//"); //FileStream outputFile = new FileStream(testPath + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx", FileMode.OpenOrCreate); //outputFile.Write(bytes, 0, bytes.Length); //outputFile.Flush(); //outputFile.Close(); //outputFile.Dispose(); try { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new StreamContent(ms); result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); result.Content.Headers.ContentDisposition.FileName = $"{System.DateTime.Now.ToString("yyyyMMddHHmmss")}.xls"; return result; } catch { return new HttpResponseMessage(HttpStatusCode.NoContent); } } catch (Exception ex) { LogService.Write("ExportQuoteReport Exception:" + ex.ToString()); return null; } }
在.net 2.0项目中去请求webapi接口 序列化实体时 意外遇到了 k_BackingField 问题;
参考了博友 https://www.cnblogs.com/jeffwongishandsome/archive/2012/05/31/2529196.html 的此篇文章后暴力解决;
[DataContract] public class ExportQuoteCountModel { [DataMember] public long EmpID { get; set; } [DataMember] public DateTime StartDate { get; set; } [DataMember] public DateTime EndDate { get; set; } [DataMember] public string PrjInput { get; set; } [DataMember] public string ResInput { get; set; } public string Changer { get; set; } }
public static string WriteFromObject<T>(T obj) where T : class { DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(T)); using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { dcjs.WriteObject(ms, obj); return Encoding.Default.GetString(ms.ToArray()); } } public static T GetObjectByJson(string jsonString) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); object ob = serializer.ReadObject(stream); T ls = (T)ob; return ls; }
但是在转换数据流的时候又出现了这个错误:
无法将类型为“System.Net.ConnectStream”的对象强制转换为类型“System.IO.FileStream
在我坚持不懈的百度bing下找到了答案:
Stream sourceStream = ... // the ConnectStream byte[] array; using (var ms = new MemoryStream()) { sourceStream.CopyTo(ms); array = ms.ToArray(); }
最终在我的bing下还是找到了终极方案 哈哈:
public static MemoryStream GetStreamByAPI(string uri, string parameters) { try { byte[] bytes = Encoding.UTF8.GetBytes(parameters);//这里需要指定提交的编码 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); webRequest.Method = "POST"; webRequest.ContentType = "application/json"; webRequest.Accept = "application/json"; webRequest.ContentLength = bytes.Length; Stream dataStream = webRequest.GetRequestStream(); dataStream.Write(bytes, 0, bytes.Length); dataStream.Close(); HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); MemoryStream ms = null; using (var stream = webResponse.GetResponseStream()) { Byte[] buffer = new Byte[webResponse.ContentLength]; int offset = 0, actuallyRead = 0; do { actuallyRead = stream.Read(buffer, offset, buffer.Length - offset); offset += actuallyRead; } while (actuallyRead > 0); ms = new MemoryStream(buffer); } webResponse.Close(); return ms; } catch (Exception ex) { return null; } }
在webform 后台需要加上响应类型为文件类型
MemoryStream res = br.GetFileStream(param,url); if (res != null) exportBinaryToExcel(res.ToArray(), "test.xlsx"); private void exportBinaryToExcel(byte[] bytes, string filename) { Response.AddHeader("Content-Disposition", "attachment; filename=" + filename); Response.AddHeader("Content-Length", bytes.Length.ToString()); Response.ContentType = "application/octet-stream"; Response.BinaryWrite(bytes); Response.Flush(); }
一次奇特的搜索经历记录下来
本文来自博客园,作者:十四,转载请注明原文链接:https://www.cnblogs.com/yanghucheng/p/13503239.html