使用不同的stringbuilder对象创建一个电子表格

时间:2012-11-29 09:39:19

标签: asp.net-mvc-3 web-services c#-4.0

我目前有一个从Web服务生成报告的应用程序。报告基本上是WebService从数据库中提取的数据表(使用存储过程)。

前50条记录显示在屏幕上(发送到视图),但也有一个按钮,用户可以单击该按钮将整个查询下载到Excel电子表格。这是通过将查询结果传递到模型中然后将其写入stringbuilder来实现的,stringbuilder用于创建电子表格。此操作方法的代码如下:

// 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对象然后将它们组合在一起来制作一个结果的电子表格吗?这会导致内存问题吗?

如果这似乎不可能,您可以提出替代解决方案吗?

1 个答案:

答案 0 :(得分:0)

通过使用do-while循环,我最终可以毫不费力地使用它。在HttpContext.Response中保存所有这些内容似乎没有任何内存问题,尽管创建一个包含72,000行和25列的电子表格需要3分半钟:

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();