2

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

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

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

这适用于 WinForms 应用程序。

我看过这个问题你能推荐一个.net模板引擎吗?,但是所有这些模板引擎对我来说都是多余的,并且专注于 ASP.NET。

请只推荐免费图书馆。

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

4

8 回答 8

3

我第二次不推荐 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>
于 2008-12-06T17:33:00.640 回答
2

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

于 2008-12-06T16:51:52.567 回答
2

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

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

期待阅读其他一些答案。

于 2008-12-06T16:57:38.997 回答
2

尽管我看到您已经接受了答案,但我还是鼓励您查看Spark 视图引擎

来自网站的示例:

<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>
于 2010-05-09T23:37:39.153 回答
0

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

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

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

于 2008-12-06T20:26:56.470 回答
0

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 或其他框架。这是一种非常灵活的方法,因为它允许您以很少的努力和更改快速将新功能包含到网页中。如Dave Ward的这篇文章所示,它也适用于 .Net 。

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

于 2009-12-30T12:30:35.203 回答
0

这是另一个模板引擎: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);
            }
        }
于 2010-05-09T23:21:43.510 回答
0

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

这是一个写作教程。它不需要任何不包含在 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);
于 2016-02-29T09:28:57.200 回答