/// <summary> /// 复制行(列)头 /// </summary> /// <returns></returns> public RptMtxHeaderInst Clone() { RptMtxHeaderInst inst = new RptMtxHeaderInst(base.Item); inst.Index = Index; inst.Filter = Filter; inst.RptData = RptData; foreach (RptTextInst txtInst in TxtInsts) { inst.TxtInsts.Add(txtInst.Clone()); } return(inst); }
/// <summary> /// 创建小计 /// </summary> /// <param name="totals"></param> /// <param name="p_header"></param> /// <param name="p_matInst"></param> /// <param name="p_curRow"></param> /// <param name="p_data"></param> /// <param name="p_loc"></param> void CreateTotalInst(List <RptMtxSubtotal> totals, RptMtxHeader p_header, RptMatrixInst p_matInst, Row p_curRow, RptData p_data, TotalLocation p_loc) { foreach (RptMtxSubtotal total in totals) { if (total.TotalLoc == p_loc) { if (total.SubTotals.Count > 0) { CreateTotalInst(total.SubTotals, p_header, p_matInst, p_curRow, p_data, p_loc); } else { RptMtxHeaderInst totalInst = new RptMtxHeaderInst(p_header); for (int j = 0; j < p_header.Levels.IndexOf(total.Level); j++) { RptMtxLevel nLevel = p_header.Levels[j]; nLevel.Item.ColSpan = 1; nLevel.Item.RowSpan = 1; RptTextInst txtlevel = new RptTextInst(nLevel.Item); totalInst.TxtInsts.Add(txtlevel); totalInst.Filter.Add(nLevel.Field, p_curRow.Str(nLevel.Field)); } RptItemBase parent = total.Parent; while (parent is RptMtxSubtotal) { RptTextInst parTotal = new RptTextInst((parent as RptMtxSubtotal).Item); totalInst.TxtInsts.Add(parTotal); parent = parent.Parent; } RptTextInst txtTotal = new RptTextInst(total.Item); totalInst.TxtInsts.Add(txtTotal); totalInst.RptData = p_data; totalInst.RptData.Current = p_curRow.Index; totalInst.Index = p_curRow.Index; if (p_header is RptMtxColHeader) { totalInst.MtxRowsCol = total.Col; p_matInst.AddColHeader(totalInst); } else { totalInst.MtxRowsRow = total.Row; p_matInst.AddRowHeader(totalInst); } } } } }
/// <summary> /// 创建标题 /// </summary> /// <param name="p_titles"></param> /// <param name="p_header"></param> /// <param name="p_matInst"></param> /// <param name="p_curRow"></param> /// <param name="p_data"></param> void CreateSubTiltelInst(List <RptMtxSubtitle> p_titles, RptMtxHeader p_header, RptMatrixInst p_matInst, Row p_curRow, RptData p_data) { foreach (RptMtxSubtitle title in p_titles) { if (title.SubTitles.Count > 0) { CreateSubTiltelInst(title.SubTitles, p_header, p_matInst, p_curRow, p_data); } else { RptMtxHeaderInst titleInst = new RptMtxHeaderInst(p_header); for (int j = 0; j <= p_header.Levels.IndexOf(title.Level); j++) { RptMtxLevel nLevel = p_header.Levels[j]; nLevel.Item.ColSpan = 1; nLevel.Item.RowSpan = 1; RptTextInst txtlevel = new RptTextInst(nLevel.Item); titleInst.TxtInsts.Add(txtlevel); titleInst.Filter.Add(nLevel.Field, p_curRow.Str(nLevel.Field)); } RptItemBase parent = title.Parent; while (parent is RptMtxSubtotal) { RptTextInst parTotal = new RptTextInst((parent as RptMtxSubtotal).Item); titleInst.TxtInsts.Add(parTotal); parent = parent.Parent; } RptTextInst txtTotal = new RptTextInst(title.Item); titleInst.TxtInsts.Add(txtTotal); titleInst.RptData = p_data; titleInst.RptData.Current = p_curRow.Index; titleInst.Index = p_curRow.Index; if (p_header is RptMtxColHeader) { titleInst.MtxRowsCol = title.Col; p_matInst.AddColHeader(titleInst); } else { titleInst.MtxRowsRow = title.Row; p_matInst.AddRowHeader(titleInst); } } } }
/// <summary> /// 添加行 /// </summary> /// <param name="p_header"></param> public void AddRowHeader(RptMtxHeaderInst p_header) { p_header.Parent = this; RowHeaderInsts.Add(p_header); }
/// <summary> /// 切换页面时在新页重复行头 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void OnHorPageBegin(object sender, RptPage e) { RptMatrix matrix = base._item as RptMatrix; if (!matrix.HideRowHeader && matrix.RepeatRowHeader) { _isHasHorBreak = true; RptRootInst root = sender as RptRootInst; //不存在定义,取第一页定义添加到当前页定义 //添加的定义应该以矩阵开始行(列)为开始位置 if (!e.IsColHasDefine()) { e.Cols.Size.InsertRange(0, root.Cols[0].Size.GetRange(matrix.Col, matrix.RowHeader.ColSpan)); } else if (!e.IsRowHasDefine()) { e.Rows.Size.InsertRange(0, root.Rows[0].Size.GetRange(matrix.Row, matrix.ColHeader.RowSpan)); } int span = matrix.RowHeader.ColSpan; int start = e.Cols.Start; //外层列号变更 if (_outPutPart == MtxOutPutPart.Cells) { _regCells.Col = start + span; } else { _regColHeader.Col = start + span; } //再次递归调用时确保数据完整 //行头Region RptRegion headerClone = _regRowHeader.Clone(); //数据源记录索引 int index = RptData.Current; //外部输出的行头索引 int rowIndex = _rowIndex; //外部正在输出的部分 RptMtxHeaderInst curPart = _rowPart; if (!matrix.HideColHeader && !matrix.HideRowHeader) { RptTextInst newCorner = CornerInst.Clone(); newCorner.Region = new RptRegion(_regRowHeader.Row - matrix.ColHeader.RowSpan, start, matrix.ColHeader.RowSpan, matrix.RowHeader.ColSpan); newCorner.Output(); } //从已输出的索引处开始输出 for (int i = rowIndex; i < RowHeaderInsts.Count; i++) { RptMtxHeaderInst instClone = RowHeaderInsts[i].Clone(); _rowPart = instClone; instClone.Region = new RptRegion(_regRowHeader.Row, start, instClone.Item.RowSpan, instClone.Item.ColSpan); //输出过程中可能触发分页事件,提前计算新行位置,输出后还原 _regRowHeader.Row += matrix.ColHeader.RowSpan; instClone.Output(); _regRowHeader.Row -= matrix.ColHeader.RowSpan; _regRowHeader.Row += 1; //下次输出位置已经输出过,不再输出 if (_rowUsed.Contains(_regRowHeader.Row) && _colUsed.Contains(start)) { break; } _rowIndex++; } _rowPart = curPart; _rowIndex = rowIndex; RptData.Current = index; _regRowHeader = headerClone.Clone(); //后移 span 个格 if (_outPutPart == MtxOutPutPart.Cells) { _cellPart.Region.Col = start + span; } else { _colPart.TxtInsts[0].Region.Col = start + span; } //将占用列加入到列表 for (int i = 0; i < span; i++) { if (!_colUsed.Contains(start + i)) { _colUsed.Add(start + i); } } } }
/// <summary> /// 切换页面时在新页重复列头 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void OnVerPageBegin(object sender, RptPage e) { RptMatrix matrix = base._item as RptMatrix; if (!matrix.HideColHeader && matrix.RepeatColHeader) { RptRootInst root = sender as RptRootInst; //当不存在水平分页时,加入列头的定义 if (!_isHasHorBreak) { e.Rows.Size.InsertRange(0, root.Rows[0].Size.GetRange(matrix.Row, matrix.ColHeader.RowSpan)); } int span = matrix.ColHeader.RowSpan; int start = e.Rows.Start; //外层列号变更 if (_outPutPart == MtxOutPutPart.Cells) { _regCells.Row = start + span; } else { _regRowHeader.Row = start + span; } //再次递归调用时确保数据完整 //行头Region RptRegion headerClone = _regColHeader.Clone(); //数据源记录索引 int index = RptData.Current; //外部输出的列头索引 int colIndex = _colIndex; //外部正在输出的部分 RptMtxHeaderInst curPart = _colPart; if (!matrix.HideColHeader && !matrix.HideRowHeader) { RptTextInst newCorner = CornerInst.Clone(); newCorner.Region = new RptRegion(start, _regColHeader.Col - matrix.RowHeader.ColSpan, matrix.ColHeader.RowSpan, matrix.RowHeader.ColSpan); newCorner.Output(); } for (int i = _colIndex; i < ColHeaderInsts.Count; i++) { RptMtxHeaderInst instClone = ColHeaderInsts[i].Clone(); _colPart = instClone; instClone.Region = new RptRegion(start, _regColHeader.Col, instClone.Item.RowSpan, instClone.Item.ColSpan); //输出过程中可能触发分页事件,提前计算新列位置,输出后还原 _regColHeader.Col += matrix.RowHeader.ColSpan; instClone.Output(); _regColHeader.Col -= matrix.RowHeader.ColSpan; _regColHeader.Col += 1; //下次输出位置已经输出过,不再输出 if (_colUsed.Contains(_regColHeader.Col) && _rowUsed.Contains(start)) { break; } _colIndex++; } _colPart = curPart; _colIndex = colIndex; RptData.Current = index; _regColHeader = headerClone.Clone(); //后移 span 个格 if (_outPutPart == MtxOutPutPart.Cells) { _cellPart.Region.Row = start + span; } else { _rowPart.TxtInsts[0].Region.Row = start + span; } //将占用行加入到列表 for (int i = 0; i < span; i++) { if (!_rowUsed.Contains(start + i)) { _rowUsed.Add(start + i); } } } }
protected override void DoOutput() { RptRootInst root = Inst; RptMatrix matrix = base._item as RptMatrix; RptRegion regClone = _region.Clone(); _region.RowSpan = 0; _region.ColSpan = 0; //矩阵角 if (!matrix.HideColHeader && !matrix.HideRowHeader) { CornerInst.Region = new RptRegion(_region.Row, _region.Col, matrix.ColHeader.RowSpan, matrix.RowHeader.ColSpan); CornerInst.Output(); _region.RowSpan += matrix.Corner.RowSpan; _region.ColSpan += matrix.Corner.ColSpan; } root.HorPageBegin += OnHorPageBegin; root.VerPageBegin += OnVerPageBegin; _rowIndex = _colIndex = 0; //列头 //可能出现水平分页、垂直分页相互调用,所以行、列Region都定义 _regColHeader = regClone.Clone(); _regRowHeader = regClone.Clone(); if (!matrix.HideRowHeader) { _regColHeader.Col += matrix.RowHeader.ColSpan; } if (!matrix.HideColHeader) { _outPutPart = MtxOutPutPart.ColHeader; _regRowHeader.Row += matrix.ColHeader.RowSpan; foreach (RptMtxHeaderInst inst in ColHeaderInsts) { _colPart = inst; inst.Region = new RptRegion(_regColHeader.Row, _regColHeader.Col, inst.Item.RowSpan, inst.Item.ColSpan); inst.Output(); _regColHeader.Col += 1; _colIndex++; _region.ColSpan++; } } //行头 //可能出现水平分页、垂直分页相互调用,所以行、列Region都定义 _colIndex = 0; _regColHeader = regClone.Clone(); _regRowHeader = regClone.Clone(); if (!matrix.HideColHeader) { _regRowHeader.Row += matrix.ColHeader.RowSpan; } if (!matrix.HideRowHeader) { _outPutPart = MtxOutPutPart.RowHeader; _regColHeader.Col += matrix.RowHeader.ColSpan; foreach (RptMtxHeaderInst inst in RowHeaderInsts) { _rowPart = inst; inst.Region = new RptRegion(_regRowHeader.Row, _regRowHeader.Col, inst.Item.RowSpan, inst.Item.ColSpan); inst.Output(); _regRowHeader.Row += 1; _rowIndex++; _region.RowSpan++; } } //数据 //还原行头、列头为开始状态(用于分页) _rowIndex = _colIndex = 0; _regColHeader = regClone.Clone(); _regRowHeader = regClone.Clone(); _regCells = regClone.Clone(); if (!matrix.HideRowHeader) { _regColHeader.Col += matrix.RowHeader.ColSpan; _regCells.Col += matrix.RowHeader.ColSpan; } if (!matrix.HideColHeader) { _regRowHeader.Row += matrix.ColHeader.RowSpan; _regCells.Row += matrix.ColHeader.RowSpan; } int colindex = 0; int col = _regCells.Col; _outPutPart = MtxOutPutPart.Cells; foreach (RptTextInst inst in _cellInsts) { _cellPart = inst; RptData.Current = GetCurrent(inst.Filter); //换行 if (colindex == ColHeaderInsts.Count) { _regCells.Row += 1; //当前行被占用,下移 while (_rowUsed.Contains(_regCells.Row)) { _regCells.Row++; } _regCells.Col = col; colindex = 0; } if (colindex != 0) { _regCells.Col++; //当前列被占用,下移 while (_colUsed.Contains(_regCells.Col)) { _regCells.Col++; } } inst.Region = new RptRegion(_regCells.Row, _regCells.Col, inst.Item.RowSpan, inst.Item.ColSpan); inst.Output(); colindex++; } root.HorPageBegin -= OnHorPageBegin; root.VerPageBegin -= OnVerPageBegin; }
/// <summary> /// 构造行头或列头 /// </summary> /// <param name="p_rptData"></param> /// <param name="p_header"></param> /// <param name="p_matInst"></param> void BuildHeader(RptData p_rptData, RptMtxHeader p_header, RptMatrixInst p_matInst) { List <string> colNames = p_header.GetFieldNames(); List <Row> allHeaderData = SelectDistinctDataRows(p_rptData.Data, colNames); Row preRow = null; for (int i = 0; i < allHeaderData.Count; i++) { Row curRow = allHeaderData[i]; if (preRow == null || !string.IsNullOrEmpty(CompareTwoRows(preRow, curRow, colNames))) { //前面小计 foreach (RptMtxLevel level in p_header.Levels) { if (level.SubTotals.Count <= 0) { continue; } RptMtxLevel beforLevel = null; if (p_header.Levels.IndexOf(level) - 1 >= 0) { beforLevel = p_header.Levels[p_header.Levels.IndexOf(level) - 1]; } //第一行(列) 或者 前一行(列)层值与当前行层值不同 创建小计 if (preRow == null || (beforLevel != null && preRow.Str(beforLevel.Field) != curRow.Str(beforLevel.Field))) { CreateTotalInst(level.SubTotals, p_header, p_matInst, curRow, p_rptData, TotalLocation.Before); } } //数据 RptMtxHeaderInst headerInst = new RptMtxHeaderInst(p_header); foreach (RptMtxLevel level in p_header.Levels) { if (level.SubTitles.Count > 0) { CreateSubTiltelInst(level.SubTitles, p_header, p_matInst, curRow, p_rptData); } else { //手动置1,因为输出头的时候按一行或一列输出,不需要控件合并 level.Item.ColSpan = 1; level.Item.RowSpan = 1; RptTextInst txtlevel = new RptTextInst(level.Item); headerInst.TxtInsts.Add(txtlevel); } } if (headerInst.TxtInsts.Count > 0) { headerInst.RptData = p_rptData; headerInst.Index = curRow.Index; if (p_header is RptMtxColHeader) { headerInst.MtxRowsCol = p_header.Levels[p_header.Levels.Count - 1].Col; p_matInst.AddColHeader(headerInst); } else { headerInst.MtxRowsRow = p_header.Levels[p_header.Levels.Count - 1].Row; p_matInst.AddRowHeader(headerInst); } //生成条件 foreach (string name in colNames) { headerInst.Filter.Add(name, curRow.Str(name)); } } //后面小计 for (int k = p_header.Levels.Count - 1; k >= 0; k--) { RptMtxLevel level = p_header.Levels[k]; if (level.SubTotals.Count <= 0) { continue; } RptMtxLevel beforLevel = null; if (p_header.Levels.IndexOf(level) - 1 >= 0) { beforLevel = p_header.Levels[p_header.Levels.IndexOf(level) - 1]; } Row nextRow = null; if (i < allHeaderData.Count - 1) { nextRow = allHeaderData[i + 1]; } //最后一行(列) 或者 下一行(列)层值与当前行层值不同 创建小计 if (nextRow == null || (beforLevel != null && curRow.Str(beforLevel.Field) != nextRow.Str(beforLevel.Field))) { foreach (RptMtxSubtotal total in level.SubTotals) { CreateTotalInst(level.SubTotals, p_header, p_matInst, curRow, p_rptData, TotalLocation.After); } } } } preRow = curRow; } }