【问题标题】:Silverlight server side excel report generation based on database querySilverlight服务器端基于数据库查询的excel报表生成
【发布时间】:2011-01-15 14:11:18
【问题描述】:

我正在完全使用 Silverlight 3 构建 Intranet 应用程序。在其中一个页面上,我需要生成一个 Excel 报告。用户可以通过UI选择几个参数,然后点击提交按钮,然后silverlight会生成一个excel报告并弹出一个窗口让用户保存生成的报告。

有没有办法以简单直接的方式实现这一点?

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

  1. 用户选择几个组合框,然后选择列表框
  2. 用户点击提交按钮
  3. btnSubmit_Click(提交按钮单击事件处理程序)将调用“takeQueryParamsAsync”WCF 服务调用
  4. 服务器端的 WCF 服务创建动态 sql 查询并执行查询并获取数据
  5. Silverlight 客户端通过调用回调函数“takeQueryParamsAsync_Completed”收到获取数据已完成的通知

silverlight 客户端现在如何向服务器请求生成报告以及如何将生成的报告提供给用户?它是否必须在“takeQueryParamsAsync_Completed”回调函数中调用另一个 wcf 服务才能从获取的数据中请求报告文件?如果是这样,wcf 服务将如何记住使用这些特定查询参数从 db 请求数据获取的客户端是同一个客户端?我必须保持 wcf 服务和 silverlight 之间的状态吗?没有更简单的解决方案吗?

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

任何指针或代码示例都会很棒。谢谢。

我确信应该有一个优雅的解决方案。

【问题讨论】:

    标签: wcf silverlight excel


    【解决方案1】:

    如果您有可用的 ASP.NET,您可以创建一个 HTTP 处理程序,您可以使用 Silverlight 中的 HTML 桥接器调用该处理程序,该处理程序将在查询字符串中获取您的报告参数。然后生成报告并发回给客户端。

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

    【讨论】:

    • @DaveB 太棒了!谢谢你。我会试一试的。
    【解决方案2】:

    好的,我对此有一些想法:

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

    所以是的,您将不得不进行那个额外的调用,但不能从 takeQueryParamsAsync_Completed 代码内部进行。您可以做的是激活一个按钮或其他东西,这将通知用户报告已生成并让他们单击download 按钮。不过还有其他选项,我最近实现了一个下载选项,该选项利用 URL 重定向到服务器上的文件 URL,这使我能够解决整个问题(没有默认文件名选项,不能只打开文件,但有先将其保存到 HDD 等)。

    关于状态的问题。这实际上取决于您存储生成的报告的位置。您是将其存储在硬盘驱动器中、数据库中还是保存在内存中?这会影响您如何调用文件。一种简单的方法是向客户端返回一个密钥,它作为链接到文件的密钥传递回服务器。这样您就不必维护 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>
    

    您还必须创建一个新的端点行为

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

    这将创建一个 webHttp 服务。

    现在您将创建一些端点:

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

    您通过地址传递的任何查询字符串都将被解析为变量。

    然后在 silverlight 客户端我简单地创建了一个自定义 URI(在您的情况下,假设文件名为“NewReport.xls”)指向调用“GetFile/{filename}”,然后您的 Uri 将看起来类似http://localhost/FileService.svc/GetFile/NewReport.xls

    现在您只需使用HtmlPage.Window.Navigate(page, "_self"); 之类的内容导航到该 URL。这将允许您下载该文件,并且仍然停留在与您相同的 Silverlight 页面上。

    【讨论】:

    • 谢谢约翰内斯。 URL 重定向似乎很有趣。您是如何在 Silverlight 中实现它的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-01
    • 1970-01-01
    • 2017-04-10
    相关资源
    最近更新 更多