史上最贱的word报表生成解决方案

注:未成年人请在父母陪同下观看此贴,有心脏病者勿入,有洁癖者勿入,看帖过程中如有觉得头晕、恶心者请立即关闭浏览器,到阳台呼吸一下新鲜空气

最近手头一个项目要生成周报、月报,要求是word文档类型,时间只有3天,今天花了一天时间找各种方案,有VSTO,有OpenXML,看了半天以后发现,如果从头开始熟悉这些东西,3天时间出报表程序根本来不及,因为如果用替换书签的方法,一个周报几百个书签的空,一天下来也填不了几个空,如果用手动生成,基本代码没问题,但是设置样式让人蛋疼得很,于是上网找其他的方案,最后找到一个史上最贱的方案,一解燃眉之急,以后再慢慢学习VSTO和OpenXML,今天就把这个方案介绍给大家,众所周知,doc格式文件是可以识别htm格式的,说到这里大家应该都明白了,大致思路就是先根据内容生成htm格式的string数据,然后直接保存成.doc文件格式就行了。至于样式的话,html样式比openxml样式简单太多了,也是我们所熟悉的东西。我把生成html脚本的过程封装成了一个dll,暂时先封装需要的标签,以后用的话再加就行了,闲话少说,看代码

1、Html类,这个类保存的是所有的周报数据,可以自己设置Title,body体内容通过AppendToBody(string content)方法添加

View Code
 1 using System.Text;
 2 
 3 namespace HtmlEncapsulation
 4 {
 5     /// <summary>
 6     /// html脚本类
 7     /// </summary>
 8     public class Html
 9     {
10         /// <summary>
11         /// 标题
12         /// </summary>
13         public string Title { get; set; }
14 
15         /// <summary>
16         /// 内容
17         /// </summary>
18         private StringBuilder _body;
19 
20 
21         public Html()
22         {
23             this._body = new StringBuilder();
24         }
25 
26         /// <summary>
27         /// 生成html
28         /// </summary>
29         /// <returns></returns>
30         public string GenerateHtml()
31         {
32             StringBuilder sb = new StringBuilder();
33             sb.AppendFormat("<html><title>{0}</title><body>{1}</body></html>", Title, _body);
34             return sb.ToString();
35         }
36 
37         /// <summary>
38         /// 添加到html页的body内
39         /// </summary>
40         /// <param name="content"></param>
41         public void AppendToBody(string content)
42         {
43             _body.Append(content);
44         }
45     }
46 }

2、HtmlEncap,这个类就是封装了生成html脚本过程的类,目前就用到生成标题(一共4级标题)、生成正文内容、表格、换行、空格、图片这些

View Code
  1 using System.Text;
  2 using System.Data;
  3 
  4 namespace HtmlEncapsulation
  5 {
  6     public static class HtmlEncap
  7     {
  8         /// <summary>
  9         /// 设置标题,默认居中
 10         /// </summary>
 11         /// <param name="content">要设置为标题的内容</param>
 12         /// <param name="header">字号,有4级字号</param>
 13         /// <returns></returns>
 14         public static string GetHeader(string content, Header header, bool isLeft = false)
 15         {
 16             StringBuilder sb = new StringBuilder();
 17             string size = string.Empty;
 18             switch (header)
 19             {
 20                 case Header.Header1:
 21                     size = "50";
 22                     break;
 23                 case Header.Header2:
 24                     size = "40";
 25                     break;
 26                 case Header.Header4:
 27                     size = "20";
 28                     break;
 29                 default:
 30                     size = "30";
 31                     break;
 32             }
 33             sb.AppendFormat("<p style='font-size:{0}px; text-align:{1}'><strong>{2}<strong></p>", size, isLeft == false ? "center" : "left", content);
 34             return content = sb.ToString();
 35         }
 36 
 37         /// <summary>
 38         /// 设置为正文内容
 39         /// </summary>
 40         /// <param name="content"></param>
 41         /// <returns></returns>
 42         public static string GetContent(string content)
 43         {
 44             return "<p>" + content + "</p>";
 45         }
 46 
 47         /// <summary>
 48         /// 生成html表格
 49         /// </summary>
 50         /// <param name="table"></param>
 51         /// <returns></returns>
 52         public static string GetTable(DataTable table)
 53         {
 54             StringBuilder sb = new StringBuilder();
 55 
 56             sb.Append("<div style='text-align:center'><table  border='1' cellspacing='0' bordercolor='#000000' width = '80%' style='border-collapse:collapse;'>");
 57 
 58             //增加表头
 59             sb.Append("<tr>");
 60             for (int i = 0; i < table.Columns.Count; i++)
 61             {
 62                 sb.AppendFormat("<th style='background-color:Silver'>{0}</th>", table.Columns[i].ColumnName);
 63             }
 64             sb.Append("</tr>");
 65 
 66             //增加数据
 67             for (int i = 0; i < table.Rows.Count; i++)
 68             {
 69                 sb.Append("<tr>");//增加一行
 70                 for (int j = 0; j < table.Columns.Count; j++)
 71                 {
 72                     sb.AppendFormat("<td>{0}</td>", table.Rows[i][j].ToString());//增加一列
 73                 }
 74                 sb.Append("</tr>");
 75             }
 76             sb.Append("</table></div>");
 77             return sb.ToString();
 78         }
 79 
 80         /// <summary>
 81         /// 换行或者空格
 82         /// </summary>
 83         /// <param name="count">换行或者空格数量</param>
 84         /// <param name="space">br为换行,nbsp为空格</param>
 85         /// <returns></returns>
 86         public static string GetSpace(int count, Space space)
 87         {
 88             StringBuilder sb = new StringBuilder();
 89             string content = space == Space.Br ? "<br/>" : "&nbsp;";
 90             for (int i = 0; i < count; i++)
 91             {
 92                 sb.Append(content);
 93             }
 94             return sb.ToString();
 95         }
 96 
 97         /// <summary>
 98         /// 获取图片
 99         /// </summary>
100         /// <param name="path">图片路径</param>
101         /// <param name="width">宽度</param>
102         /// <param name="height">高度</param>
103         /// <param name="isCenter">是否居中显示,默认为居中</param>
104         /// <returns></returns>
105         public static string GetImage(string path, int width, int height, bool isCenter = true)
106         {
107             string content = string.Format("<img src='{0}' width='{1}px' height='{2}px'></img>", path, width, height);
108 
109             content = isCenter == true ? "<div style='text-align:center'>" + content + "</div>" : content;
110 
111             return content;
112         }
113     }
114 }

3、还有一个通用枚举类,这个简单,不做解释

View Code
 1 namespace HtmlEncapsulation
 2 {
 3     /// <summary>
 4     /// 标题字号
 5     /// </summary>
 6     public enum Header
 7     {
 8         Header1,
 9         Header2,
10         Header3,
11         Header4
12     }
13 
14     /// <summary>
15     /// Br 换行,Space 空格
16     /// </summary>
17     public enum Space
18     {
19         Br,
20         Space
21     }
22 }

使用方法:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Data;
 6 using System.IO;
 7 using HtmlEncapsulation;
 8 
 9 namespace HtmlEncaps
10 {
11     class Program
12     {
13         static void Main(string[] args)
14         {
15             Html html = new Html();
16             html.Title = "周报";
17 
18             //加载标题
19             html.AppendToBody(HtmlEncap.GetHeader("NorthWind报表样例", Header.Header2));
20             html.AppendToBody(HtmlEncap.GetHeader("2013年3月6日周报", Header.Header3));
21             html.AppendToBody(HtmlEncap.GetSpace(3, Space.Br));
22 
23             //加载客户信息表
24             html.AppendToBody(HtmlEncap.GetHeader("1、客户信息", Header.Header4, true));
25             string sql = "select * from Customers";
26             DataTable table = new DbHelper().GetTable(sql);
27             html.AppendToBody(HtmlEncap.GetTable(table));
28 
29             //加载员工信息表
30             html.AppendToBody(HtmlEncap.GetHeader("2、员工信息", Header.Header4, true));
31             sql = "select * from Employees";
32             DataTable table2 = new DbHelper().GetTable(sql);
33             html.AppendToBody(HtmlEncap.GetTable(table2));
34 
35             //加载图片
36             html.AppendToBody(HtmlEncap.GetImage(@"http://www.cnblogs.com/img/logo.png", 300, 300));
37 
38             File.WriteAllText("周报.doc", html.GenerateHtml());
39 
40             Console.WriteLine("OK");
41         }
42     }
43 }

效果:

显示表格数据

显示图片

这个封装的dll比较草率,以后再加入保存为真正的doc功能

posted on 2013-03-06 23:31  【無語】  阅读(364)  评论(0编辑  收藏  举报

导航