2011-08-06 79 views
9

我正在構建一個ASP.NET MVC3 Web應用程序,我想要使用水晶報表生成一些報表並使用水晶報表查看器來顯示它們。 我通過網絡搜索,我沒有找到任何堅實的方式在MVC3網絡應用程序中做到這一點。 你有什麼提示/想法如何做到這一點?水晶報表查看器與MVC3

回答

4

如果你不介意一些黑客,它實際上很容易。 (假設CR4VS2010)

首先將WebForms頁面添加到您的項目並添加水晶報表查看器控件。

驗證它添加到引用:

CrystalDescisions.CrystalReports.EngineCrystalDescisions.ReportSourceCrystalDescisions.Shared, 和CrystalDescisions.Web

然後添加一個PageRoute到您的應用程序,導致新添加的頁面。

最後,這是BLANK最大的麻煩,你需要讓Crystal的圖像處理程序工作。有許多應該如何,都圍繞着網絡和在這裏SO,他們沒有真正爲我工作,所以我使出作弊:

public class CrystalImageHandlerController : Controller 
{ 
    // 
    // GET: /CrystalImageHandler.aspx 

    public ActionResult Index() 
    { 
     return Content(""); 
    } 

    protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 

     var handler = new CrystalDecisions.Web.CrystalImageHandler(); 
     var app = (HttpApplication)filterContext.RequestContext.HttpContext.GetService(typeof(HttpApplication)); 
     if (app == null) return; 

     handler.ProcessRequest(app.Context); 

    } 
} 

添加路由到該控制器爲/CrystalReportsImageHandler.aspx,這是哪裏CR期望它的處理程序是。這也可以在區域中使用,只需根據需要更改處理程序和頁面路線。

請記住,您將無法使用剃刀布局。所以你需要採取其他手段來獲得視覺連續性。 (我使用IFrames)

+0

謝謝。我從[這裏](http://www.highoncoding.com/Articles/550_Creating_Crystal_Report_in_ASP_NET.aspx)獲得了Webform部分,並將其與您的控制器相結合,我設法查看了我的報告。 –

+0

太棒了!我也應該讓你知道這個珍聞:當使用Web查看器時,它在瀏覽器中有一個JS API。沒有找到任何文檔,但是當它使用我的網站佈局,使用iframe時,我發現它的調整大小的方法是無價的。對象名稱是 _UI。 –

+0

您提到:「將路由作爲/CrystalReportsImageHandler.aspx添加到此控制器中」。我到底該怎麼做? –

4

在我們的項目中,我們直接以PDF格式返回報告。我們選擇在同一個項目中不使用WebForms和MVC,主要是因爲保持了代碼清理。

這些報告是針對手動創建的「啞」數據集生成的,數據由服務類填充,可以通過NHibernate檢索所需的所有信息(因爲我們使用了一層ORM持久性和數據庫抽象,Crystal Reports不得直接連接到數據庫)。

如果你的項目沒有顯示爲「預覽模式」在瀏覽器中報告的必要性,這裏是我寫的這種情況自定義的ActionResult:

public class PdfReportResult : ViewResult 
{ 
    /// <summary> 
    /// Crystal Report filename 
    /// </summary> 
    public string reportFileName { get; set; } 

    /// <summary> 
    /// DataSet used in the report 
    /// </summary> 
    public DataSet reportDataSet { get; set; } 

    /// <summary> 
    /// Report parameters 
    /// </summary> 
    IDictionary<string, object> parameters { get; set; } 

    public PdfReportResult(string reportFileName, DataSet reportDataSet, IDictionary<string, object> parameters) 
    { 
    if (string.IsNullOrEmpty(reportFileName)) 
     throw new ArgumentException("Report filename not informed", "reportFileName"); 

    if (reportDataSet == null) 
     throw new ArgumentException("DataSet not informed", "reportDataSet"); 

    if (parameters == null) 
     this.parameters = new Dictionary<string, object>(); 
    else 
     this.parameters = parameters; 

    this.reportDataSet = reportDataSet; 
    this.reportFileName = reportFileName; 
    } 

    public PdfReportResult(string reportFileName, DataSet reportDataSet) 
    : this(reportFileName, reportDataSet, null) 
    { } 

    public override void ExecuteResult(ControllerContext context) 
    { 
    if (context == null) 
     throw new ArgumentNullException("context"); 

    if (string.IsNullOrEmpty(this.ViewName)) 
     this.ViewName = context.RouteData.GetRequiredString("action"); 

    // Alias to make the code more legible 
    HttpResponseBase response = context.HttpContext.Response; 

    // Generating the report 
    using (ReportDocument report = new ReportDocument()) 
    { 
     // Load the report 
     report.Load(context.HttpContext.Server.MapPath("~/Reports/" + reportFileName)); 

     // Set the dataset 
     report.SetDataSource(reportDataSet); 

     // Set the parameters (if any) 
     foreach (var parameter in parameters) 
     report.SetParameterValue(parameter.Key, parameter.Value); 

     // Send back the PDF to the user 
     using (MemoryStream oStream = (MemoryStream)report.ExportToStream(ExportFormatType.PortableDocFormat)) 
     { 
     response.Clear(); 
     response.Buffer = true; 
     response.AddHeader("Content-Disposition", this.ViewName + ".pdf"); 
     response.ContentType = "application/pdf"; 
     response.BinaryWrite(oStream.ToArray()); 
     response.End(); 
     } 
    } 
    } 
} 
2

由於水晶報表是一個服務器控件,我們需要一個網頁/用戶控件來顯示報表。並且絕對不要把這個webform/user控件放在mvc的views文件夾中,你會在CrViewer中得到404錯誤的按鈕。您還可以在剃鬚刀視圖中使用Iframe來顯示報告。以下是一個工作模式[VS2010],請通過。

步驟1:設置水晶報表
1.在網站根目錄下創建頂級文件夾。
2.將Crystal report.rpt文件放入此文件夾
3.將網頁(.aspx)添加到此文件夾中。此頁面用作報告查看器頁面。在這個頁面中添加一個CrystalReportViewer控件。

div align="center" style="width:100%; height:100%;" 
     CR:CrystalReportViewer ID="crViewer" runat="server" AutoDataBind="true" 
div 

4.下面的程序集註冊將被添加到aspx頁面的頂部。

<%@ Register Assembly="CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" Namespace="CrystalDecisions.Web" TagPrefix="CR" %>. 
  1. 檢查的CrystalReportViewer的版本。爲此,從VS側欄上的工具箱中選擇「選擇項目」。將此版本與aspx頁面頂部的CrystalDecisions.Web版本進行比較。如果兩者相同,則保留它,否則請改變與CRViewer相同的程序集註冊版本。

  2. 轉到網站根文件夾下的web.config文件;檢查標籤下的'CrystalDecisions'開頭的程序集。更改它們的版本與CrystalReportViewer版本相同(此處版本= 13.0.2000.0)。

2步:設置控制器,動作&查看
1.添加在報告控制器類新動作。
2.編寫必要的步驟從數據庫/文件加載數據。
3.將數據設置爲Session。
4.不要爲此操作添加視圖。而是使用Response.Redirect方法。

public class ReportController : Controller 
    { 
    public ActionResult reportView(string id) 
    { 
    Session["ReportSource"] = GetdataFromDb(); 
    Response.Redirect("~/Reports/WebForm1.aspx"); 
    return View(); 
    } 
    } 
  1. 添加頁面加載事件到.aspx頁面。

    protected void Page_Load(object sender, EventArgs e) 
    { 
    CrystalDecisions.CrystalReports.Engine.ReportDocument report = 
    new CrystalDecisions.CrystalReports.Engine.ReportDocument(); 
    report.Load(Server.MapPath("~/Reports/CR_report.rpt")); 
    report.SetDataSource(Session["ReportSource"]); 
    crViewer.ReportSource =report; 
    } 
    

步驟3:在Global.asax中
1.小黑客爲了避免「會話狀態已創建一個會話ID,但無法保存它,因爲響應已被刷新的應用程序「。錯誤或」空白水晶報告頁面輸出「在Global.asax中添加以下代碼。

void Session_Start(object sender, EventArgs e) 
    { 
    string sessionId = Session.SessionID; 
    } 

現在您可以調用ReportController中的reportView()動作來顯示Crystal Report。
祝您有美好的一天!