银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
  268 随笔 :: 2 文章 :: 2606 评论 :: 48 引用

源程序代码

我们的 C# 程序中经常会产生一些数据,这些数据可以使用 Html 表格进行展现。现在让我们开始写相关的 C# 程序吧。下面就是 HtmlMaker.cs:

01:  using System;
02:  using System.IO;
03:  using System.Net;
04:  using System.Data;
05:  using System.Drawing;
06:  using System.Collections.Generic;
07:  
08:  namespace Skyiv
09:  {
10:    public sealed class HtmlMaker
11:    {
12:      public bool TitleVisible { get; set; }
13:  
14:      string title;
15:      DataView view;
16:      IEnumerable<Tuple<string, string>> info;
17:  
18:      public HtmlMaker(string title, IEnumerable<Tuple<string, string>> info, DataView view)
19:      {
20:        this.title = title;
21:        this.info = info;
22:        this.view = view;
23:        this.TitleVisible = true;
24:      }
25:  
26:      public void Save(string htmlFileName)
27:      {
28:        using (var writer = new StreamWriter(htmlFileName))
29:        {
30:          WriteHead(writer);
31:          WriteTitle(writer);
32:          WriteInfo(writer);
33:          new HtmlTable(view).Write(writer);
34:          WriteTail(writer);
35:        }
36:      }
37:  
38:      void WriteTitle(TextWriter writer)
39:      {
40:        if (!TitleVisible) return;
41:        writer.Write("  <h1>");
42:        WebUtility.HtmlEncode(title, writer);
43:        writer.WriteLine("</h1>");
44:      }
45:  
46:      void WriteInfo(TextWriter writer)
47:      {
48:        if (info == null) return;
49:        var dt = new DataTable();
50:        dt.Columns.Add("Key", typeof(string));
51:        dt.Columns.Add("Value", typeof(string));
52:        foreach (var row in info)
53:        {
54:          var dr = dt.NewRow();
55:          dr[0] = row.Item1;
56:          dr[1] = row.Item2;
57:          dt.Rows.Add(dr);
58:        }
59:        var htmlTable = new HtmlTable(dt.DefaultView);
60:        htmlTable.ColumnHeadersVisible = false;
61:        htmlTable.Write(writer);
62:      }
63:  
64:      void WriteHead(TextWriter writer)
65:      {
66:        writer.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" ");
67:        writer.WriteLine("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
68:        writer.WriteLine("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
69:        writer.WriteLine("<head>");
70:        writer.WriteLine("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");
71:        writer.Write("  <title>");
72:        WebUtility.HtmlEncode(title, writer);
73:        writer.WriteLine("</title>");
74:        writer.WriteLine("</head>");
75:        writer.WriteLine("<body>");
76:      }
77:  
78:      void WriteTail(TextWriter writer)
79:      {
80:        writer.WriteLine("</body>");
81:        writer.WriteLine("</html>");
82:      }
83:    }
84:  }

 

注意上述程序第 70 行表明我们生成的 Html 文件是使用 UTF-8 编码,这应该成为一个共识。而在第 28 行使用的 StreamWriter 类默认情况也是使用 UTF8Encoding 。还有要注意第 42 行和第 72 行,在写入 Html 文件时要使用 WebUtility 类的静态方法 HtmlEncode 对数据进行编码。在第 33 行和第 59 行使用的 HtmlTable 类的源程序 HtmlTable.cs 如下所示:

01:  using System;
02:  using System.IO;
03:  using System.Net;
04:  using System.Data;
05:  using System.Drawing;
06:  
07:  namespace Skyiv
08:  {
09:    sealed class HtmlTable
10:    {
11:      public int Level { get; set; }
12:      public bool ColumnHeadersVisible { get; set; }
13:      public Color ColumnHeadersBackgroundColor { get; set; }
14:      public Color BackgroundColor { get; set; }
15:      public Color AlternatingRowsBackgroundColor { get; set; }
16:  
17:      DataView view;
18:  
19:      public HtmlTable(DataView view)
20:      {
21:        this.view = view;
22:        Level = 1;
23:        ColumnHeadersVisible = true;
24:        ColumnHeadersBackgroundColor = Color.Cyan;
25:        BackgroundColor = Color.Azure;
26:        AlternatingRowsBackgroundColor = Color.LightYellow;
27:      }
28:  
29:      public void Write(TextWriter writer)
30:      {
31:        if (writer == null) return;
32:        if (view == null) return;
33:        var blank = "".PadLeft(Level * 2);
34:        writer.Write(blank);
35:        writer.Write("<table border=\"1\" cellspacing=\"2\" cellpadding=\"2\">");
36:        writer.Write("<tbody");
37:        WriteBackgroundColor(writer, BackgroundColor);
38:        writer.WriteLine(">");
39:        if (ColumnHeadersVisible) WriteTableHead(writer);
40:        var rowIndex = 0;
41:        foreach (DataRowView row in view) WriteTableRow(writer, row, rowIndex++);
42:        writer.Write(blank);
43:        writer.WriteLine("</tbody></table>");
44:      }
45:  
46:      private void WriteBackgroundColor(TextWriter writer, Color color)
47:      {
48:        if (color == Color.Empty) return;
49:        writer.Write(" style=\"background-color: ");
50:        writer.Write(color.ToHtmlCode());
51:        writer.Write("\"");
52:      }
53:  
54:      void WriteTableHead(TextWriter writer)
55:      {
56:        var blank2 = "".PadLeft((Level + 1) * 2);
57:        var blank3 = "".PadLeft((Level + 2) * 2);
58:        writer.Write(blank2);
59:        writer.Write("<tr");
60:        WriteBackgroundColor(writer, ColumnHeadersBackgroundColor);
61:        writer.WriteLine(">");
62:        foreach (DataColumn column in view.Table.Columns)
63:        {
64:          writer.Write(blank3);
65:          writer.Write("<th>");
66:          WebUtility.HtmlEncode(column.Caption, writer);
67:          writer.WriteLine("</th>");
68:        }
69:        writer.Write(blank2);
70:        writer.WriteLine("</tr>");
71:      }
72:  
73:      void WriteTableRow(TextWriter writer, DataRowView view, int rowIndex)
74:      {
75:        var blank2 = "".PadLeft((Level + 1) * 2);
76:        var blank3 = "".PadLeft((Level + 2) * 2);
77:        writer.Write(blank2);
78:        writer.Write("<tr");
79:        if (rowIndex % 2 != 0) WriteBackgroundColor(writer, AlternatingRowsBackgroundColor);
80:        writer.WriteLine(">");
81:        foreach (var field in view.Row.ItemArray)
82:        {
83:          writer.Write(blank3);
84:          writer.Write("<td>");
85:          WebUtility.HtmlEncode(field.ToString(), writer);
86:          writer.WriteLine("</td>");
87:        }
88:        writer.Write(blank2);
89:        writer.WriteLine("</tr>");
90:      }
91:    }
92:  }

 

几点说明:

  1. 第 11 行的 Level 字段表示这个 <table> 元素在 Html 文件中缩进层次,每缩进一层增加两个空格。
  2. 第 12 行的 ColumnHeadersVisible 字段表示是否要显示该表格的标题行。
  3. 第 13 行的 ColumnHeadersBackgroundColor 字段表示该表格标题行的背景色,默认值是青色(Cyan)。
  4. 第 14 行的 BackgroundColor 字段表示该表格的背景色,默认值是天蓝色(Azure)。
  5. 第 15 行的 AlternatingRowsBackgroundColor 字段表示该表格偶数行的背景色,默认值是浅黄色(LightYellow)。
  6. 以上三个字段的值都可以设为 Color.Empty,表示继承上一级的背景色。
  7. 第 50 行的 ToHtmlCode 方法是一个扩展方法,定义于 Skyiv.ExtensionMethods 静态类中。

下面就是 ExtensionMethods.cs:

01:  using System.Drawing;
02:  
03:  namespace Skyiv
04:  {
05:    public static class ExtensionMethods
06:    {
07:      public static string ToHtmlCode(this Color color)
08:      {
09:        return string.Format("#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
10:      }
11:    }
12:  }

 

使用示例

这让我们来看一个例子吧,下面就是 EnumTester.cs:

01:  using System;
02:  using System.Data;
03:  using System.Collections.Generic;
04:  
05:  namespace Skyiv.Tester
06:  {
07:    sealed class EnumTester
08:    {
09:      static void Main()
10:      {
11:        try
12:        {
13:          var type = typeof(System.IO.FileAttributes);
14:          var html = new HtmlMaker("枚举测试者", GetInfo(type), GetTable(type).DefaultView);
15:          html.TitleVisible = false;
16:          html.Save("enum.html");
17:        }
18:        catch (Exception ex)
19:        {
20:          Console.Error.WriteLine(ex);
21:        }
22:      }
23:  
24:      static List<Tuple<string, string>> GetInfo(Type type)
25:      {
26:        var info = new List<Tuple<string, string>>();
27:        info.Add(Tuple.Create("枚举类型名称", type.ToString()));
28:        info.Add(Tuple.Create("枚举成员数量", Enum.GetValues(type).Length.ToString()));
29:        return info;
30:      }
31:  
32:      static DataTable GetTable(Type type)
33:      {
34:        var table = new DataTable();
35:        table.Columns.Add("十进制", typeof(string));
36:        table.Columns.Add("十六进制", typeof(string));
37:        table.Columns.Add("名称", typeof(string));
38:        foreach (var v in Enum.GetValues(type))
39:        {
40:          var dr = table.NewRow();
41:          dr[0] = Enum.Format(type, v, "D");
42:          dr[1] = Enum.Format(type, v, "X");
43:          dr[2] = Enum.Format(type, v, "G");
44:          table.Rows.Add(dr);
45:        }
46:        return table;
47:      }
48:    }
49:  }

 

在 Windows Vista 操作系统的 .NET Fraemwork 4 环境中编译和运行:

E:\work> csc EnumTester.cs HtmlMaker.cs HtmlTable.cs ExtensionMethods.cs
Microsoft(R) Visual C# 2010 编译器 4.0.30319.1 版
版权所有(C) Microsoft Corporation。保留所有权利。

E:\work> EnumTester
E:\work>

 

这个 EnumTester.exe 运行后生成 enum.html 文件,在谷歌浏览器中的显示效果如下图所示:

HtmlMaker01

 

这个 Html 文件的源代码如下所示:

01:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
02:  <html xmlns="http://www.w3.org/1999/xhtml">
03:  <head>
04:    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
05:    <title>枚举测试者</title>
06:  </head>
07:  <body>
08:    <table border="1" cellspacing="2" cellpadding="2"><tbody style="background-color: #F0FFFF">
09:      <tr>
10:        <td>枚举类型名称</td>
11:        <td>System.IO.FileAttributes</td>
12:      </tr>
13:      <tr style="background-color: #FFFFE0">
14:        <td>枚举成员数量</td>
15:        <td>14</td>
16:      </tr>
17:    </tbody></table>
18:    <table border="1" cellspacing="2" cellpadding="2"><tbody style="background-color: #F0FFFF">
19:      <tr style="background-color: #00FFFF">
20:        <th>十进制</th>
21:        <th>十六进制</th>
22:        <th>名称</th>
23:      </tr>
24:      <tr>
25:        <td>1</td>
26:        <td>00000001</td>
27:        <td>ReadOnly</td>
28:      </tr>
29:      <tr style="background-color: #FFFFE0">
30:        <td>2</td>
31:        <td>00000002</td>
32:        <td>Hidden</td>
33:      </tr>
34:      <tr>
35:        <td>4</td>
36:        <td>00000004</td>
37:        <td>System</td>
38:      </tr>
39:      <tr style="background-color: #FFFFE0">
40:        <td>16</td>
41:        <td>00000010</td>
42:        <td>Directory</td>
43:      </tr>
44:      <tr>
45:        <td>32</td>
46:        <td>00000020</td>
47:        <td>Archive</td>
48:      </tr>
49:      <tr style="background-color: #FFFFE0">
50:        <td>64</td>
51:        <td>00000040</td>
52:        <td>Device</td>
53:      </tr>
54:      <tr>
55:        <td>128</td>
56:        <td>00000080</td>
57:        <td>Normal</td>
58:      </tr>
59:      <tr style="background-color: #FFFFE0">
60:        <td>256</td>
61:        <td>00000100</td>
62:        <td>Temporary</td>
63:      </tr>
64:      <tr>
65:        <td>512</td>
66:        <td>00000200</td>
67:        <td>SparseFile</td>
68:      </tr>
69:      <tr style="background-color: #FFFFE0">
70:        <td>1024</td>
71:        <td>00000400</td>
72:        <td>ReparsePoint</td>
73:      </tr>
74:      <tr>
75:        <td>2048</td>
76:        <td>00000800</td>
77:        <td>Compressed</td>
78:      </tr>
79:      <tr style="background-color: #FFFFE0">
80:        <td>4096</td>
81:        <td>00001000</td>
82:        <td>Offline</td>
83:      </tr>
84:      <tr>
85:        <td>8192</td>
86:        <td>00002000</td>
87:        <td>NotContentIndexed</td>
88:      </tr>
89:      <tr style="background-color: #FFFFE0">
90:        <td>16384</td>
91:        <td>00004000</td>
92:        <td>Encrypted</td>
93:      </tr>
94:    </tbody></table>
95:  </body>
96:  </html>

 

符合 XHTML 1.0 Strict 规范

这个 Html 文件是符合 W3CXHTML 1.0 Strict 规范的,如下图所示。

HtmlMaker02

HtmlMaker03

 

第二个使用示例

这让我们再看一个使用示例吧,下面就是 FileTester.cs:

01:  using System;
02:  using System.IO;
03:  using System.Data;
04:  using System.Collections.Generic;
05:  
06:  namespace Skyiv.Tester
07:  {
08:    sealed class FileTester
09:    {
10:      static void Main(string[] args)
11:      {
12:        try
13:        {
14:          var dir = new DirectoryInfo(args[0]);
15:          var table = GetTable(dir);
16:          var view = table.DefaultView;
17:          view.Sort = "创建时间";
18:          view.RowFilter = "字节数 < 1024'";
19:          new HtmlMaker("文件测试者", GetInfo(dir, view), view).Save("file.html");
20:        }
21:        catch (Exception ex)
22:        {
23:          Console.Error.WriteLine(ex);
24:        }
25:      }
26:  
27:      static List<Tuple<string, string>> GetInfo(DirectoryInfo dir, DataView view)
28:      {
29:        var info = new List<Tuple<string, string>>();
30:        info.Add(Tuple.Create("目录名称", dir.FullName));
31:        info.Add(Tuple.Create("筛选条件", view.RowFilter));
32:        return info;
33:      }
34:  
35:      static DataTable GetTable(DirectoryInfo dir)
36:      {
37:        var table = new DataTable();
38:        table.Columns.Add("文件名", typeof(string));
39:        table.Columns.Add("特性", typeof(string));
40:        table.Columns.Add("创建时间", typeof(DateTime));
41:        table.Columns.Add("字节数", typeof(long));
42:        foreach (var file in dir.GetFiles())
43:        {
44:          var dr = table.NewRow();
45:          dr[0] = file.Name;
46:          dr[1] = file.Attributes;
47:          dr[2] = file.CreationTime;
48:          dr[3] = file.Length;
49:          table.Rows.Add(dr);
50:        }
51:        return table;
52:      }
53:    }
54:  }

 

几点说明:

  1. 第 17 行使用 DataView 类的 Sort 属性,使展现出来的文件按“创建时间”进行排序。
  2. 第 18 行使用 DataView 类的 RowFilter 属性,筛选出字节数小于 1024 的文件。

在 Windows Vista 操作系统的 .NET Framework 4 环境中编译和运行:

E:\work> csc FileTester.cs HtmlMaker.cs HtmlTable.cs ExtensionMethods.cs
Microsoft(R) Visual C# 2010 编译器 4.0.30319.1 版
版权所有(C) Microsoft Corporation。保留所有权利。

E:\work> FileTester C:\Windows
E:\work>

 

这次运行 FileTester.exe 程序时带命令行参数 C:\Windows ,生成 file.html 文件,在 IE8 浏览器中的显示效果如下图所示:

HtmlMaker04

posted on 2011-01-11 21:12  银河  阅读(...)  评论(...编辑  收藏