【问题标题】:Templating Engine to Generate Simple Reports in .NET [closed]在.NET中生成简单报告的模板引擎[关闭]
【发布时间】:2008-12-06 16:28:42
【问题描述】:

我正在寻找一个免费的模板引擎来生成简单的报告。我想要一些基本功能,例如:

  • 能够编写循环(使用任何 IEnumerable)
  • 传递变量
  • 传递模板文件(主模板、页脚、页眉)

我将使用它来生成 HTML 和 XML 格式的报告。我不是在寻找 ASP.NET 模板引擎。

这是一个 WinForms 应用程序。

我已经看到这个问题 Can you recommend a .net template engine?,但是所有这些模板引擎对我来说都是多余的,并且专注于 ASP.NET。

请只推荐免费库。

// 我仍在寻找 NVelocity,但它看起来对 .NET 没有任何希望,过于复杂,当你下载它时一堆文件不清楚要做什么,没有教程、启动文档等。

【问题讨论】:

  • 我不知道答案,但是提示:如果您想吸引更多用户,请删除问题并重新插入,并且不要设置社区 wiki 标志。 “社区 wiki” 投票不会增加用户的声誉...
  • 感谢您的提示,我不知道这个限制。我会为以后的问题这样做。

标签: .net class templates reporting report


【解决方案1】:

我第二次不推荐 nVelocity。这是一个可怕的港口。

.NET 实际上使用 CodeDOM 内置了模板功能。

这是一个很好的操作指南:

http://www.codeproject.com/KB/cs/smarttemplateengine.aspx

通过一些小的编码,您将能够创建具有内联 C# 的模板:

<html>
    <head>
         <title>My Report</title>
    </head>
    <body>
        <% foreach (ReportRow r in ReportData) { %>
             <!-- Markup and Code for Report -->
        <% } %>
    </body>
</html>

【讨论】:

  • 如果我错了,请纠正我,但它似乎不是一个非常强大的解决方案,如果我正确理解文章,它会手动使用 Regex 解析/解释模板.如果这是真的,那将是更糟糕的“string.Format”类型的解决方案。
【解决方案2】:

我会推荐 StringTemplate (http://www.stringtemplate.org)。我用它来生成邮件。您可以使用存储在文件系统或数据库中的模板组(需要一点工作)。

【讨论】:

  • 你知道任何网站上的一些字符串模板的 .NET 示例吗?
  • stringtemplate 网站上的 wiki 显示了最受支持的语言的示例,包括 c#。但是模板的语法对于所有语言都是相同的。只有模板的实例不同。
【解决方案3】:

我们使用 NVelocity 作为基于 MonoRail 的网站的一部分。老实说,我不会推荐 NVelocity。它是从 Java 版本到 .NET 版本的直接端口(直接我的意思是 CTRL+C、CTRL+V,将一些 Java 关键字更改为 C# 关键字——这是不可维护的)。 Castle 不得不分叉它以添加一些面向 .NET 的功能(字典访问、花哨的 foreach 循环),因为最初的 .NET 维护人员将其置于不健康的状态。在转义自己的某些指令时遇到问题,如果您尝试将长 if 语句拆分为多行,您会感到非常恼火。我并不是想把它全部扔掉,它是一种很好的语言,它是免费的,而且它在我们的网站上使用,它每天处理数千个请求——我只是不会再使用它,除非我看到一个新的实现语法相同。

对于系统中生成电子邮件的其他区域,我只是使用老式方法替换字符串中的 $SPECIAL_KEYWORDS$(即,将关键字映射到值的字典,遍历并替换)。效率不高,但效果很好。

期待阅读其他一些答案。

【讨论】:

  • Nicholas - Castle 的 NVelocity 分支是活生生的,我认为既然他们将它用于 Windsor 配置,它应该相当稳定。我个人对此没有任何问题。 jonorossi.com/blog/archive/2009/09/29/…
【解决方案4】:

虽然我看到你已经接受了答案,但我还是鼓励你看看Spark view engine

来自网站的示例:

<viewdata products="IEnumerable[[Product]]"/>
<ul if="products.Any()">
  <li each="var p in products">${p.Name}</li>
</ul>
<else>
  <p>No products available</p>
</else>

【讨论】:

    【解决方案5】:

    感谢您的帮助,CodeDOM 专门向我展示了一个不错的方法, 现在我正在处理这个:http://www.stefansarstedt.com/templatemaschine.html

    这不是最好的,有点脏,但对我有用。它是适合我的 LGPL,而且很短。

    我查看了其他建议,但不喜欢它们,对于我想要的东西来说太复杂了(而且相当混乱 - 大量 DLL、依赖项等-)

    【讨论】:

      【解决方案6】:

      John Resig 有一个很棒的 Javascript 模板结尾,名为 micro-template。模板的语法是:

      <script type="text/html" id="item_tmpl">
        <div id="<%=id%>" class="<%=(i % 2 == 1 ? " even" : "")%>">
          <div class="grid_1 alpha right">
            <img class="righted" src="<%=profile_image_url%>"/>
          </div>
          <div class="grid_6 omega contents">
            <p><b><a href="/<%=from_user%>"><%=from_user%></a>:</b> <%=text%></p>
          </div>
        </div>
      </script>
      

      模板函数将支持 Javascript 的使用,因此您可以获得循环功能和对 DOM 的完全访问权限,因此任何 jQuery 或其他框架都可供您使用。这是一种非常灵活的方法,因为它允许您以很少的努力和更改快速将新功能包含到网页中。它也适用于 .Net,如 Dave Ward 的 post 所示。

      模板可以是一个 html 文件,您可以使用 $.get() 命令检索该文件。您为模板提供一个 JSON 对象作为数据源。最后,还有一个功能可以让你预编译模板。

      【讨论】:

        【解决方案7】:

        这是另一个模板引擎:UltTemplate Engine

        这是模板代码:

        Dear $User.FullName$,
        {%set orders=User.GetOrders() /}
        Thank you for your order of $orders.Length$ items, We believe you will be very satisfied with the quality of costume pieces included in each. It is this quality that makes our imaginative play apparel so unique.
        
        We created an account for you to track your orders. Here is the login information:
        Email: $User.EmailAddress$
        Password: $User.Password$
        
        Following is the details of your order (OrderId: $OrderId$):
        #   Part ID    Name            Quantity     Price(per unit)       Sub Total
        {%set Total=0.0 /}{%foreach orderproduct,i in orders%}{%set Total = Total + orderproduct.Price * orderproduct.Quantity/}
        {%rendertemplate orderproducttemplate item=orderproduct/}{$foreach%}
                                                                                                       Total: $PadLeft(Format(Total,"$$#.##"),11)$
        
        If you have any concern, please call us at 913-555-0115.
        
        Sincerely,
        
        $CompanyName$
        
        {%template orderproducttemplate%}$PadLeft(i,4)$$PadLeft(item.PartId, 7)$    $PadRight(item.ProductName, 15)$        $PadRight(item.Quantity, 5)$        $PadLeft(Format(item.Price,"$$#.##"), 7)$   $PadLeft(Format(item.Price*item.Quantity,"$$#.##"), 12)${$template%}
        

        这是输出:

        Dear John Borders,
        
        Thank you for your order of 3 items, We believe you will be very satisfied with the quality of costume pieces included in each. It is this quality that makes our imaginative play apparel so unique.
        
        We created an account for you to track your orders. Here is the login information:
        Email: myemail@somedomain.com
        Password: 123abc
        
        Following is the details of your order (OrderId: 1625DGHJ):
        #   Part ID    Name            Quantity     Price(per unit)       Sub Total
        
           0   1239    Product A              3            $104.09        $312.27
           1     22    Product B              1            $134.09        $134.09
           2    167    Product C              5              $14.7          $73.5
        
                                                       Total:     $519.86
        
        If you have any concern, please call us at 913-555-0115.
        
        Sincerely,
        
        My Company Name
        

        这是 C# 代码:

                class OrderProduct
                {
                    private int _partId;
                    private string _productName;
                    private int _quantity;
                    private float _price;
        
                    public int PartId
                    {
                        get { return _partId; }
                        set { _partId = value; }
                    }
        
                    public string ProductName
                    {
                        get { return _productName; }
                        set { _productName = value; }
                    }
        
                    public int Quantity
                    {
                        get { return _quantity; }
                        set { _quantity = value; }
                    }
        
                    public float Price
                    {
                        get { return _price; }
                        set { _price = value; }
                    }
                }
        
                class User
                {
                    private string _fullName;
                    private string _emailAddress;
                    private string _password;
        
                    public string FullName
                    {
                        get { return _fullName; }
                        set { _fullName = value; }
                    }
        
                    public string EmailAddress
                    {
                        get { return _emailAddress; }
                        set { _emailAddress = value; }
                    }
        
                    public string Password
                    {
                        get { return _password; }
                        set { _password = value; }
                    }
        
                    public OrderProduct[] GetOrders()
                    {
                        OrderProduct[] ops = new OrderProduct[3];
        
                        ops[0] = new OrderProduct();
                        ops[0].PartId = 1239;
                        ops[0].Price = 104.09f;
                        ops[0].ProductName = "Product A";
                        ops[0].Quantity = 3;
        
                        ops[1] = new OrderProduct();
                        ops[1].PartId = 22;
                        ops[1].Price = 134.09f;
                        ops[1].ProductName = "Product B";
                        ops[1].Quantity = 1;
        
                        ops[2] = new OrderProduct();
                        ops[2].PartId = 167;
                        ops[2].Price = 14.7f;
                        ops[2].ProductName = "Product C";
                        ops[2].Quantity = 5;
        
                        return ops;
                    }
                }
        
                private void btnRun_Click(object sender, EventArgs e)
                {
                    try
                    {
                        dt.LoadFromString(txtSource.Text);
                        dt.SetValue("CompanyName", "My Company Name");
        
                        User u = new User();
                        u.EmailAddress = "myemail@somedomain.com";
                        u.FullName = "John Borders";
                        u.Password = "123abc";
                        dt.SetValue("User", u);
                        dt.SetValue("OrderId", "1625DGHJ");
        
                        txtOutput.Text = dt.Run();
                    }
                    catch (Exception exc)
                    {
                        MessageBox.Show("An error occurred: " + exc.Message);
                    }
                }
        

        【讨论】:

          【解决方案8】:

          当我阅读这些答案时,我不禁注意到所有答案和库等对于较小的应用程序来说都相当复杂。因此我想建议T4T Text Templates

          这是Writing 的教程。它不需要任何不包含在 Visual Studio 中的库。如果您不需要过于复杂的模板或报告,可能值得一看。

          模板代码示例:

              <#@ template language="C#" #>
          <html><body>
          <h1>Sales for Previous Month</h2>
          <table>
              <# for (int i = 1; i <= 10; i++)
                 { #>
                   <tr><td>Test name <#= i #> </td>
                       <td>Test value <#= i * i #> </td> </tr>
              <# } #>
           </table>
          This report is Company Confidential.
          </body></html>
          

          在您的应用程序代码中,您可以使用如下调用生成模板的内容:

          MyWebPage page = new MyWebPage();
          String pageContent = page.TransformText();
          System.IO.File.WriteAllText("outputPage.html", pageContent);
          

          【讨论】:

          • 看起来不错,但MyWebPage 是什么?它是如何到达那里的?
          猜你喜欢
          • 1970-01-01
          • 2016-05-21
          • 2014-06-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-01
          相关资源
          最近更新 更多