1.1.1. 简介
报表是数据汇总统计的主要展示形式之一,在所有项目中,作为重要的输出结果,报表能很好的展现业务的状态,用户可根据报表展示的结果进行相关的分析与决策。在我们的项目开发过程中,主要使用HtmlTable进行报表的绘制,针对报表量大的情况,提出了报表动态配置的功能,使我们能快速的开发出用户所需的报表。
1.1.2. 实施方案
报表的动态配置采用HtmlTable进行报表的绘制,以XML文件存储配置信息。XML格式的定义如下:
<?xml version="1.0" encoding="utf-8"?>
<table style="border-collapse:collapse;border:none;width:100%;" cellspacing="0" cellpadding="0">
<tr>
<td style="border:none;font-size:15px;text-align:center;height:30" rowspan="1" colspan="11">处室综合计划执行信息反馈表</td>
</tr>
<tr>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">序号</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">项目名称</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">项目阶段</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">工作内容</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">责任处室</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">计划开始时间</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">实际开始时间</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">计划完成时间</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">实际完成时间</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">滞后原因</td>
</tr>
<foreach>
<tr>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#RowNumber#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#o_projectname#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#JieDuan#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#WorkNM#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#FN_DEP_NAME#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#StartDate#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#EndDate#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#RealStartDate#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#RealEndDate#</td>
<td style="height:25px;width:10%;border:solid 1px black;text-align:center;vertical-align:middle;" colspan="1" rowspan="1">#Notes#</td>
</tr>
</foreach>
</table>
其中table标签的第一tr标签为报表的标题,第二个标签到foreach标签之前的内容为报表的表头,foreach标签之间定义的为相应的列与具体数据源列之间的绑定关系。我们像单纯的Html里的table去设置我们报表的样式。
核心的代码:
① 解析XML构造HtmlTable标题及表头方法
// 构造HtmlTable方法
public HtmlTable CreateHtmtlTableModelFromXml()
{
XmlNode xmldocSelect = xmlmodel.SelectSingleNode("table");
HtmlTable mytable = CreateHtmlTable(xmldocSelect);
foreach (XmlNode trnode in xmldocSelect.SelectNodes("tr"))
{
HtmlTableRow newrow = CreateHtmlTableRow(trnode);
foreach (XmlNode tdnode in trnode.ChildNodes)
{
HtmlTableCell mycell = new HtmlTableCell();
mycell = CreateHtmlTableCell(tdnode);
newrow.Cells.Add(mycell);
}
mytable.Rows.Add(newrow);
}
return mytable;
}
// 根据XML节点创建行HtmlTableRow
private HtmlTableRow CreateHtmlTableRow(XmlNode trmynode)
{
HtmlTableRow newrow = new HtmlTableRow();
foreach (XmlAttribute dd in trmynode.Attributes)
{
newrow.Attributes.Add(dd.Name, dd.Value);
}
return newrow;
}
// 根据XML节点创建单元格HtmlTableCell
private HtmlTableCell CreateHtmlTableCell(XmlNode tdmynode)
{
HtmlTableCell newcell = new HtmlTableCell();
foreach (XmlAttribute dd in tdmynode.Attributes)
{
newcell.Attributes.Add(dd.Name, dd.Value);
}
newcell.InnerHtml = tdmynode.InnerXml;
return newcell;
}
② 根据数据源构造表体
public HtmlTable CreateHtmlDataTable(HtmlTable mytable,DataTable dt)
{
XmlNode xmldocSelect = xmlmodel.SelectSingleNode("table");
foreach (DataRow dr in dt.Rows)
{
XmlNodeList mynode = xmldocSelect.SelectNodes("foreach");
if (mynode.Count > 0)
{
foreach (XmlNode trnode in mynode[0])
{
HtmlTableRow newrow = CreateHtmlTableRow(trnode);
foreach (XmlNode tdnode in trnode.ChildNodes)
{
HtmlTableCell mycell = new HtmlTableCell();
mycell = CreateHtmlTableDataCell(tdnode, dt, dr);
newrow.Cells.Add(mycell);
}
mytable.Rows.Add(newrow);
}
}
}
return mytable;
}
//根据数据源构造表体单元格HtmlTableCell
private HtmlTableCell CreateHtmlTableDataCell(XmlNode tdmynode, DataTable dt, DataRow dr)
{
HtmlTableCell newcell = new HtmlTableCell();
foreach (XmlAttribute dd in tdmynode.Attributes)
{
newcell.Attributes.Add(dd.Name, dd.Value);
}
string xmlcelltext = tdmynode.InnerText;
string columname = string.Empty;
string columnvalue = string.Empty; System.Text.RegularExpressions.Regex regex = new Regex("(#([^#]+)#)", RegexOptions.IgnoreCase); MatchCollection mc = regex.Matches(xmlcelltext);
if (mc.Count > 0)
{
columname = xmlcelltext.Substring(1, xmlcelltext.Length - 2);
columnvalue = dr[columname].ToString();
}
else
{
columnvalue = xmlcelltext;
}
newcell.InnerHtml = columnvalue;
return newcell;
}
在开发报表的时候,我们只要把报表样式配置到相应的XML文件,然后再编写返回报表数据源的方法,最后调用以上方法即可完成报表的开发工作。
1.1.3. 存在问题及改进
对于表体数据存在跨行的报表,此方案不能直接应用,需要进行二次开发。