Asp.net mvc 3 使用不同的stringbuilder对象创建一个电子表格
我目前有一个从Web服务生成报告的应用程序。这些报告基本上是由WebService(使用存储过程)从数据库中提取的数据表 前50条记录显示在屏幕上(发送到视图),但还有一个按钮,用户可以单击该按钮将整个查询下载到excel电子表格。这是通过将查询结果传递到模型中,然后将其写入用于创建电子表格的stringbuilder来实现的。此操作方法的代码如下所示:Asp.net mvc 3 使用不同的stringbuilder对象创建一个电子表格,asp.net-mvc-3,web-services,c#-4.0,Asp.net Mvc 3,Web Services,C# 4.0,我目前有一个从Web服务生成报告的应用程序。这些报告基本上是由WebService(使用存储过程)从数据库中提取的数据表 前50条记录显示在屏幕上(发送到视图),但还有一个按钮,用户可以单击该按钮将整个查询下载到excel电子表格。这是通过将查询结果传递到模型中,然后将其写入用于创建电子表格的stringbuilder来实现的。此操作方法的代码如下所示: // WebService call var reportResult = SubscriberService.GetReport(repor
// WebService call
var reportResult = SubscriberService.GetReport(reportName, criteria.CurrentPageNumber - 1, 0, getReportParameters(model.GroupId, criteria));
model.Result = getModel(reportResult);
// if file name is not ended with .csv we there it as prefix and file will be prefix_{date}.csv
if (String.IsNullOrEmpty(fileName) || fileName.LastIndexOf(".csc", StringComparison.InvariantCultureIgnoreCase) != fileName.Length - 4)
fileName = string.Format("{0}_{1}.csv", fileName, DateTime.Now.ToShortDateString());
HttpContext.Response.ContentType = "text/csv";
HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
if (model.Result != null)
{
StringBuilder sb = new StringBuilder();
exportRowHeader(sb);
HttpContext.Response.Write(sb.ToString());
sb.Clear();
foreach (var item in model.Result.Members)
{
exportRowData(sb, model.Result, item);
HttpContext.Response.Write(sb.ToString());
sb.Clear();
}
HttpContext.Response.Write(sb.ToString());
}
else
{
HttpContext.Response.Write(ReportResources.Report_Exporting_NoDataAvailable);
}
HttpContext.Response.Flush();
我这里的问题是,对于大型查询,与Web服务的通信花费的时间太长并且超时。通过WebService发送的最大数据量也存在问题
所以我想做的是打破WebService调用。WebService能够对其发送回的结果进行分页。所以我基本上一次调用200个结果(直到返回所有结果)
通过简单地创建额外的stringbuilder对象,然后将它们组合在一起,生成一个结果电子表格,是否可以做到这一点?这会导致内存问题吗
如果这似乎不可能,你能建议一个替代的解决方案吗?我通过使用do-while循环,让它最终相当轻松地工作起来。在HttpContext中保存所有这些内容似乎没有任何内存问题。尽管创建一个包含72000行和25列的电子表格花费了3.5分钟,但响应:
int pageNum = 0;
int pageSize = 2000;
// if file name is not ended with .csv we there it as prefix and file will be prefix_{date}.csv
if (String.IsNullOrEmpty(fileName) || fileName.LastIndexOf(".csc", StringComparison.InvariantCultureIgnoreCase) != fileName.Length - 4)
fileName = string.Format("{0}_{1}.csv", fileName, DateTime.Now.ToShortDateString());
HttpContext.Response.ContentType = "text/csv";
HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
do
{
var reportResult = SubscriberService.GetReport(reportName, pageNum, pageSize,
getReportParameters(model.GroupId, criteria));
model.Result = getModel(reportResult);
if (model.Result != null)
{
StringBuilder sb = new StringBuilder();
if (pageNum == 0)
{
exportRowHeader(sb);
HttpContext.Response.Write(sb.ToString());
sb.Clear();
}
foreach (var item in model.Result.Members)
{
exportRowData(sb, model.Result, item);
HttpContext.Response.Write(sb.ToString());
sb.Clear();
}
HttpContext.Response.Write(sb.ToString());
}
else
{
HttpContext.Response.Write(ReportResources.Report_Exporting_NoDataAvailable);
break;
}
pageNum++;
} while (model.Result.Members.Count==pageSize);
HttpContext.Response.Flush();
StringBUilder有一个Append方法,该方法接收要附加到上一个内容的字符串。所以我想你可以做这个。webservice还可以提供一种方法,返回接收所有信息所需的大小,这样您就可以从一开始就调整基本stringbuilder的大小,而无需隐式调整大小。