项目经理来了一份奇特要求:
在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();
}
一次奇特的搜索经历记录下来