Silverlight服务器端excel基于数据库查询生成报表

我正在完全使用Silverlight 3构buildIntranet应用程序。在其中一页上,我需要生成一个Excel报告。 用户可以通过用户界面select一些参数,点击提交button,Silverlight将生成一个Excel报告并popup一个窗口,允许用户保存生成的报告。

无论如何要以简单而直接的方式实现这一点?

以下是我能想到的步骤,但仍不完全清楚如何解决这个问题。

  1. 用户selectless数combobox,并select列表框
  2. 用户点击提交button
  3. btnSubmit_Click(提交button单击事件处理程序)将调用“takeQueryParamsAsync”WCF服务调用
  4. 服务器端的WCF服务创build一个dynamic的sql查询并执行查询并获取数据
  5. Silverlight客户端得到通知,通过调用callback函数“takeQueryParamsAsync_Completed”完成获取数据

现在Silverlight客户端如何请求从服务器生成报告,以及如何将生成的报告发送给用户? 是否必须在“takeQueryParamsAsync_Completed”callback函数中调用另一个wcf服务来从获取的数据中请求报告文件? 如果是这样的话,wcf服务怎么会记住它是同一个客户端请求数据从这个特定的查询参数获取数据? 我必须维护wcf服务和silverlight之间的状态吗? 有没有更简单的解决scheme?

客户端Excel报表生成不是一个选项(因为生成的Excel文件应包含Excel图表)。 这真的很难吗? 还是我只是过度复杂自己不知道如何实现它?

任何指针或代码示例将是伟大的。 谢谢。

我相信,应该有一个优雅的解决scheme。

如果您有ASP.NET可用,您可以创build一个HTTP处理程序,您可以使用Silverlight中的HTML桥接器来调用该桥接程序,该程序会将查询string中的报告参数。 然后生成报告并将其发送回客户端。

string printUrl = string.Format("createxlsreport.ashx?param1={0}", param1); HtmlPage.Window.Navigate(new Uri(printUrl, UriKind.Relative), "_blank", "toolbar=yes,location=no,status=no,menubar=no,resizable=yes"); 

将文件发送回客户端:

 private void SendFileToClient(byte[] file, string fileName) { HttpResponse Response = HttpContext.Current.Response; Response.Clear(); Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", fileName)); // Add a HTTP header to the output stream that contains the // content length(File Size). This lets the browser know how much data is being transfered Response.AddHeader("Content-Length", file.Length.ToString()); // Set the HTTP MIME type of the output stream Response.ContentType = "application/vnd.ms-excel"; // Write the data out to the client. Response.BinaryWrite(file); Response.End(); } 

好的,我有几点想法:

你打算使用Silverlight的SaveDialog来下载文件吗? 首先,我想你知道这一点,这是使用Silverlight 3将文件保存到用户计算机的唯一方法。如果要使用该方法,则需要用户驱动的事件来保存文件(即,buttonA点击)。

所以是的,你将不得不去追加额外的电话,但不能从takeQueryParamsAsync_Completed代码中。 你可以做的是激活一个button,或者其他的东西,通知用户报表已经生成,并让他们点击downloadbutton。 还有其他的select,我最近实现了一个下载选项,使用URLredirect到服务器上的文件的URL,这使我能够解决整个问题(没有默认文件名选项,不能只是打开文件,但已先保存到硬盘等)。

至于与国家的事情的问题。 这实际上取决于你存储生成的报告的位置。 你把它存储在硬盘上,数据库中,还是保存在内存中? 这会影响您如何回忆文件。 其中一种简单的方法是将密钥返回给客户端,并将其作为链接到该文件的密钥传递回服务器。 这样你就不必维护WCF服务和Silverlight之间的状态。

编辑那么,在Wcf服务方面,你将需要额外的服务。 我的样子像

 <service behaviorConfiguration="NewBehavior" name="ALMWCFHost.FileProvider.FileService"> <endpoint address="" behaviorConfiguration="NewBehavior1" binding="webHttpBinding" bindingConfiguration="" name="File" contract="ALMWCFHost.FileProvider.IFileService" /> <host> <baseAddresses> <add baseAddress="http://localhost:8021/Files/" /> </baseAddresses> </host> </service> 

您还将不得不创build新的端点行为

 <endpointBehaviors> <behavior name="NewBehavior1"> <webHttp /> </behavior></endpointBehaviors> 

这将创build一个webHttp服务。

现在您将创build一些端点:

 [OperationContract, WebGet(UriTemplate = "GetFile/{filename}")] Stream GetFile(string filename); [OperationContract, WebGet] Stream GetYCFile(string date, string type, string format); [OperationContract, WebGet(UriTemplate = "GetFiles/Files.zip?filenames={querystring}")] Stream GetFiles(string querystring); 

你用地址传递的任何查询string都将被parsing为variables。

然后在silverlight客户端,我只是创build了一个自定义的URI(在你的情况下,可以说这个文件被称为“NewReport.xls”),指向调用“GetFile / {filename}”,那么你的Uri将看起来像HTTP ://localhost/FileService.svc/GetFile/NewReport.xls

现在你所做的就是使用HtmlPage.Window.Navigate(page, "_self"); 。 这将允许您下载文件,并仍然保持在同一个Silverlight页面上。