动态RDLC报表类DynamicReport:数据表节点数据填充
数据表部分是最麻烦的,可以添加多个数据表,可以设置多维表头,可以设置多字段的统计行,不同的列可以采用不同的样式。在传入数据表前需要先传入列样式、多维表头,数据表和统计列是同一时间传入的,页眉和页脚则需要在数据表后传入。
在这里最多可以设置三行表头,从上到下依次是hearderTop、hearderMerge和数据表中的列。表头的样式包含如下几部分:
public string ColoumName { get; set; } //列名
public float ColoumWidth { get; set; } //列宽
public TextAlign TextAlign { get; set; } //对齐
public ConsoleColor ConsoleColor { get; set; } //颜色
public Boolean IsShortDate { get; set; } //显示短日期格式
多维表头的数据表结构是:
DataTable hearderMerge = new DataTable();
hearderMerge.Columns.Add("CellNumber", Type.GetType("System.Int32"));
hearderMerge.Columns.Add("CellValue", Type.GetType("System.String"));
CellNumber代表占用多少列宽度,1为一列,2为合并二列,总列数不能超过或少过数据表的列数;CellValue就是显示的名称。
统计行可以是单列或多列,以string方式传入,不同列用逗号分隔,如“列名1,列名3”,可以是任意列,可以相邻或间隔,但必须是数据表中存在的列并且值可以相加。当只有一列统计时在此列的前面显示“统计:”,如果是第一列则不显示。
数据表会生成DataSets节点和Tablix节点。
private List<ReportColoumStyle> _coloumStyle = new List<ReportColoumStyle>();
internal const float ColoumWidth = 1.6F; //列宽
private float tabelTopPosition = 0.0F;
private DataTable hearderName = new DataTable();
private DataTable hearderMerge = new DataTable();
private DataTable hearderTop = new DataTable();
public void SetColoumStyle(List<ReportColoumStyle> coloumStyle)
{
this._coloumStyle = coloumStyle;
}
public void AddData(DataTable dataTable, string totalColumn)
{
if (dataTable != null && dataTable.Rows.Count > 0)
{
var coloumNames = new List<string>();
foreach (DataColumn dataColumn in dataTable.Columns)
{
var protertyName = dataColumn.ColumnName;
coloumNames.Add(protertyName);
}
AddReportItemPattern(coloumNames.ToArray(), dataTable, totalColumn);
}
}
protected void AddReportItemPattern(string[] coloumNames, dynamic data, string totalColumn = "")
{
StringBuilder fields = new StringBuilder();
StringBuilder coloums = new StringBuilder();
StringBuilder tablixHearders = new StringBuilder();
StringBuilder tablixCells = new StringBuilder();
StringBuilder tablixMembers = new StringBuilder();
float currentNamePrefix = _reportItemPatterns.Count + _reportHeadPatterns.Count + 1;
float tableWidth = 0F;
float dataRows = ((DataTable)data).Rows.Count; //数据行数
int totalNumber = 0;
string totalWidth = "";
string totalCellPattern = "";
string totalMemberPattern = "";
string mergeMemberPattern = "";
Boolean isHearderMerge = true;
float hearderHeight = 0.0F;
foreach (var coloumName in coloumNames)
{
var coloumWidth = ColoumWidth;
var textAlign = TextAlign.Right;
var consoleColor = ConsoleColor.Black;
var isShortDate = false;
var reportColoumStyle = _coloumStyle.FirstOrDefault(r => r.ColoumName == coloumName);
if (reportColoumStyle != null)
{
textAlign = reportColoumStyle.TextAlign;
coloumWidth = reportColoumStyle.ColoumWidth;
consoleColor = reportColoumStyle.ConsoleColor;
isShortDate = reportColoumStyle.IsShortDate;
}
tableWidth += coloumWidth;
if (totalColumn != "")
{
if (totalColumn.Split(',').Length > 1)
{
for (int i = 0; i < totalColumn.Split(',').Length; i++)
{
if (totalColumn.Split(',')[i] == coloumName)
{
if (totalWidth == "")
{
totalWidth = totalNumber.ToString();
}
else
{
totalWidth += "," + totalNumber.ToString();
}
}
}
}
else
{
if (totalColumn == coloumName)
{
totalWidth = totalNumber.ToString();
}
}
}
totalNumber += 1;
var bottomBorder = string.Empty; //每个单元格底部border
if (dataRows == 0)
{
bottomBorder = "<BottomBorder><Style>None</Style></BottomBorder>";
}
var coloumValue = coloumName;
if (hearderName.Rows.Count > 0)
{
foreach (DataColumn dc in hearderName.Columns)
{
if (dc.ColumnName == coloumName)
{
if (hearderName.Rows[0][coloumName].ToString().Trim() != "") coloumValue = hearderName.Rows[0][coloumName].ToString();
}
}
}
//例外,如果coloumName包含Coloum之类的字段,则将value设成空
if (coloumName.IndexOf("Column", System.StringComparison.Ordinal) > -1)
{
coloumValue = " ";
}
fields.AppendFormat(
"<Field Name=\"{0}\"><DataField>{0}</DataField><rd:TypeName>System.String</rd:TypeName></Field>",
coloumName);
coloums.AppendFormat("<TablixColumn><Width>{0}cm</Width></TablixColumn>", coloumWidth);
if (hearderMerge.Rows.Count > 0)
{
if (isHearderMerge)
{
hearderHeight += 0.5F;
mergeMemberPattern = "<TablixMember><KeepWithGroup>After</KeepWithGroup><RepeatOnNewPage>true</RepeatOnNewPage></TablixMember>";
if (hearderTop.Rows.Count > 0)
{
hearderHeight += 0.5F;
mergeMemberPattern += "<TablixMember><KeepWithGroup