2009-06-03 66 views
2

我不確定如何在我的asp.net mvc應用程序中將我的ActiveReports報表文檔導出到XLS。如何在ASP.Net MVC應用程序中將ActiveReport導出到XLS?

我到目前爲止的概念是有一個下拉導出類型和一個提交按鈕,將該值提交給我的控制器。當我在控制器上時,我重新生成報告並將其傳遞給我的Export方法。我不確定該導出方法返回的是什麼。我也在實際的xlsExport.Export方法中出現了超出範圍的錯誤。以下是我的導出方法。還要注意,reportBase.Report是一個ActiveReport3對象。

private ActionResult Export(ReportBase reportBase) 
     { 
      Response.ClearContent(); 
      Response.ClearHeaders(); 

      var exportType = Request.Form["exportType"]; 

      switch (exportType) 
      { 
       case "RTF": 
        Response.ContentType = "application/octet-stream"; 
        Response.AddHeader("Content-Disposition", "attachment;filename=report.rtf"); 
        var rtfExport = new RtfExport(); 
        rtfExport.Export(reportBase.Report.Document, Response.OutputStream); 
        break; 
       case "TIFF": 
        Response.ContentType = "image/tiff"; 
        Response.AddHeader("Content-Disposition", "attachment;filename=report.tif"); 
        var tiffExport = new TiffExport(); 
        var filePath = System.IO.Path.GetTempFileName(); 
        tiffExport.Export(reportBase.Report.Document, filePath); 

        var fileStream = System.IO.File.Open(filePath, System.IO.FileMode.Open); 
        var bufferLength = (int)fileStream.Length; 
        var output = new byte[bufferLength]; 
        var bytesRead = fileStream.Read(output, 0, bufferLength); 

        Response.OutputStream.Write(output, 0, bytesRead); 
        System.IO.File.Delete(filePath); 
        break; 
       case "XLS": 
        Response.ContentType = "application/octet-stream"; 
        Response.AddHeader("Content-Disposition", "attachment;filename=report.xls"); 
        var xlsExport = new XlsExport(); 
        xlsExport.Export(reportBase.Report.Document, Response.OutputStream); 
        break; 
      } 

      Response.Flush(); 
      Response.End(); 

      return View("Display", reportBase); 

     } 

回答

6

我沒有你的問題的答案。包括完整的例外信息會很有幫助。沒有足夠的信息可以幫助我,但我會檢查以確保reportBase.Report.Document不爲空。

但是,我想對您的代碼進行一般評論。您的控制器操作不遵循ASP.NET MVC的約定。它不應直接寫入響應流。首先,單元測試很難。其次,它往往會讓你的行動承擔責任(它已經比我更喜歡我最大的控制器的大4倍)Response.End縮短了行動,「返回View()」什麼也不做。我會做這樣的事情:

var exportType = Request.Form["exportType"]; 
switch (exportType) 
{ 
    case "RTF": 
    return new RtfExportResult(reportBase.Report.Document); 
    case "TIFF": 
    return new TiffExportResult(reportBase.Report.Document); 
    case "XLS": 
    return new XlsExportResult(reportBase.Report.Document); 
} 

return View("Error"); // unsupported export type 

然後你XlsExportResult會是什麼樣子:

public class XlsExportResult : ActionResult 
{ 
    private readonly Document document; 

    public XlsExportResult(Document document) 
    { 
     this.document= document; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     var response = context.HttpContext.Response; 
     response.ContentType = "application/octet-stream"; 
     response.AddHeader("Content-Disposition", "attachment;filename=report.xls"); 
     var xlsExport = new XlsExport(); 
     xlsExport.Export(this.document, response.OutputStream); 
    } 
} 

然後,您可以編寫測試更容易行使只有XlsExport一部分。 (我也會找到一種方法來將XlsExport隱藏在界面後面)。通過一些創意(爲文件名等內容添加額外的屬性),您可以在項目中重複使用* Result類。

+0

謝謝Talljoe!這不僅使我的代碼看起來更好,它解決了問題。我不確定如何操縱MVC方式的響應。謝謝您的幫助! – 2009-06-04 13:20:01

相關問題