Templating Engine to Generate Simple Reports in .NET [closed]

江枫思渺然 提交于 2019-12-18 04:25:23

问题


I'm looking for a free templating engine to generate simple reports. I want some basic features such as :

  • Ability to Write Loops (with any IEnumerable)
  • Passing Variables
  • Passing Templates Files (main template, footer, header)

I'll use this to generate reports in HTML and XML. I'm not looking for a ASP.NET Template Engine.

This is for a WinForms applications.

I've seen this question Can you recommend a .net template engine?, however all of those template engines are total overkill for me and focused for ASP.NET.

Please only recommend free libraries.

// I'm still looking an NVelocity but it doesn't look any promising for .NET, overly complicated, when you download it's bunch of files not clear what to do, no tutorial, startup document etc.


回答1:


I second not recommending nVelocity. It is a horrible port.

.NET actually has built in templating abilities by using CodeDOM.

Here is a pretty good walkthrough of how to do it:

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

With some minor coding, you'll be able to create templates that have inline C#:

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



回答2:


I would recommend StringTemplate (http://www.stringtemplate.org). I used it for generation of mails. You can use Template Groups stored on Filesystem or in a database (costs a little bit of work).




回答3:


We use NVelocity as part of our MonoRail-based Web site. In all honesty, I would not recommend NVelocity. It's a direct port (and by direct I mean CTRL+C, CTRL+V, change some Java keywords to C# keywords -- this is not maintainable) from the Java version to the .NET version. Castle had to fork it to add some .NET-oriented features (dictionary access, fancy foreach loops) since the original .NET maintainers are leaving it in an unhealthy state. Has problems escaping some of its own directives, gets really irritated should you try to split a long if statement across multiple lines. I don't mean to dump all over it, it's a nice language, it's free, and it's used on our site which servers thousands of requests per day--I just wouldn't use it again unless I saw a new implementation of the same syntax.

For other areas of the system that generate e-mails, I just use the old-fashioned method of replacing $SPECIAL_KEYWORDS$ in a string (that is, a dictionary that maps keywords to values, iterate through it and replace). Not efficient, but works well enough.

Look forward to reading some of the other answers.




回答4:


Although I see you've already accepted an answer, I would encourage you to take a look at the Spark view engine.

Example from the site:

<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:


Thanks for the help, CodeDOM specifically showed me a nice way, now I'm working with this : http://www.stefansarstedt.com/templatemaschine.html

It's not the best and a bit dirty but doing the trick for me. It's LGPL which fits me, and short.

I've looked at the other suggestions but didn't like them, too complicated for what I want (and quite messy -tons of DLLs, dependencies etc.-)




回答6:


John Resig has a great Javascript template end called micro-template. The syntax for a template is:

<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>

The template function will support the use of Javascript, and therefore you get the looping functionality and full access to the DOM, so any jQuery or other frameworks are at your disposal. This is a very flexible approach as it allows you quickly include new features to a web page with very little effort and alteration. It also works well with .Net as shown in this post from Dave Ward.

The template can be an html file that you can retrieve with a $.get() command. You feed the template a JSON object as the data source. Finally, there is also a feature that allows you to pre-compile the template.




回答7:


Here is another Template Engine: UltTemplate Engine

Here is the template code:

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%}

and here is the output:

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

Here is the C# code:

        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:


As i am reading through these answers i can't help but note that all the answers and libraries etc. are pretty complicated for the smaller applications. Hence i would like to suggest T4T Text Templates.

Here is a tutorial for Writing one. It does not need any libraries that aren't included in visual studio. If you don't need overly complex templates or reports it might be worth to take a peek.

Template code example:

    <#@ 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>

In your application code, you can generate the content of your template using a call like this:

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


来源:https://stackoverflow.com/questions/346449/templating-engine-to-generate-simple-reports-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!