/// <summary> /// 输出图片 /// </summary> /// <param name="p_img"></param> /// <param name="p_row"></param> /// <param name="p_col"></param> void RenderImage(RptTextInst p_img, int p_row, int p_col) { RptText item = p_img.Item as RptText; Kit.RunSync(() => { Rect rc = _ws.GetRangeLocation(new CellRange(p_row, p_col, item.RowSpan, item.ColSpan)); _ws.AddPicture(_ws.Pictures.Count.ToString(), new Uri(item.Val), rc.Left, rc.Top, rc.Width, rc.Height); }); }
public override async Task Build() { RptRootInst inst = _part.Inst; if (string.IsNullOrEmpty(Tbl)) { return; } // 使用时再加载 var rptData = await inst.Info.GetData(Tbl); if (rptData == null) { return; } RptMatrixInst matrixInst = new RptMatrixInst(this); matrixInst.RptData = rptData; ReBuildData(matrixInst.RptData.Data); inst.Body.AddChild(matrixInst); if (!HideRowHeader && !HideColHeader) { RptTextInst corner = new RptTextInst(Corner.Item); matrixInst.CornerInst = corner; } //列头 BuildHeader(rptData, ColHeader, matrixInst); //行头 BuildHeader(rptData, RowHeader, matrixInst); //数据 foreach (RptMtxHeaderInst rowHeaderInst in matrixInst.RowHeaderInsts) { foreach (RptMtxHeaderInst colHeaderInst in matrixInst.ColHeaderInsts) { RptText cell = GetCellByRowCol(rowHeaderInst.MtxRowsRow, colHeaderInst.MtxRowsCol); if (cell != null) { RptTextInst txtInst = new RptTextInst(cell); Dictionary <string, string> filter = new Dictionary <string, string>(); foreach (string key in rowHeaderInst.Filter.Keys) { filter.Add(key, rowHeaderInst.Filter[key]); } foreach (string key in colHeaderInst.Filter.Keys) { filter.Add(key, colHeaderInst.Filter[key]); } txtInst.Filter = filter; matrixInst.AddCell(txtInst); } } } }
/// <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_txt"></param> /// <param name="p_row"></param> /// <param name="p_col"></param> Cells.Data.Cell RenderText(RptTextInst p_txt, int p_row, int p_col) { var cell = _ws[p_row, p_col]; var item = p_txt.Item as RptText; cell.ColumnSpan = item.ColSpan; cell.RowSpan = item.RowSpan; cell.Tag = p_txt; item.ApplyStyle(cell); if (item.IsScriptRender && _info.ScriptObj != null) { // 脚本绘制 _info.ScriptObj.RenderCell(cell, new RptCellArgs(p_txt)); } else { cell.Value = p_txt.GetText(); } return(cell); }
/// <summary> /// 构造报表项实例 /// </summary> public override Task Build() { RptRootInst inst = _part.Inst; RptTextInst txt = new RptTextInst(this); if (_parent != null) { inst.CurrentParent.AddChild(txt); } else if (_part.PartType == RptPartType.Header) { inst.Header.AddChild(txt); } else if (_part.PartType == RptPartType.Footer) { inst.Footer.AddChild(txt); } else { inst.Body.AddChild(txt); } return(Task.CompletedTask); }
protected override void DoOutput() { RptData.Current = Index; int index = 0; RptTextInst beforeTxt = null; foreach (RptTextInst txt in TxtInsts) { txt.Region = beforeTxt == null?_region.Clone() : beforeTxt.Region.Clone(); if (HeaderType == RptMtxHeaderType.Col) { txt.Region.Row += index++; } else { txt.Region.Col += index++; } txt.Region.RowSpan = txt.Item.RowSpan; txt.Region.ColSpan = txt.Item.ColSpan; txt.Output(); beforeTxt = txt; } }
/// <summary> /// 添加子项 /// </summary> /// <param name="p_item"></param> public void AddChild(RptTextInst p_item) { _children.Add(p_item); }
/// <summary> /// 渲染输出 /// </summary> public void Render() { int start; RptRootInst inst = _info.Inst; List <double> rows = new List <double>(); // 填充空行空列,统计所有行高列宽 foreach (PageDefine page in inst.Rows) { // 页面之间的缝隙,为避免打印时分页边框不正常! rows.Add(RptRootInst.PageGap); // 记录页面开始行索引 start = rows.Count; page.Offset = start; // 页眉行 if (inst.HeaderHeight > 0) { rows.Add(inst.HeaderHeight); } // 内容行 double total = 0; foreach (double height in page.Size) { rows.Add(height); total += height; } // 填充空行 if (total < inst.BodyHeight) { rows.Add(inst.BodyHeight - total); } // 页脚行 if (inst.FooterHeight > 0) { rows.Add(inst.FooterHeight); } page.Total = rows.Count - start; } List <double> cols = new List <double>(); foreach (PageDefine page in inst.Cols) { // 页面之间的左侧间隔缝隙 cols.Add(RptRootInst.PageGap); // 记录页面开始列索引 start = cols.Count; page.Offset = start; double total = 0.0; foreach (double width in page.Size) { cols.Add(width); total += width; } // 填充空列 if (total < inst.BodyWidth) { cols.Add(inst.BodyWidth - total); } page.Total = cols.Count - start; } // 创建Worksheet _ws = new Worksheet(rows.Count, cols.Count); // 不显示选择区黑框和触摸时的两圈,改用 Excel.ShowSelection 控制 //_ws.SelectionBorderColor = Colors.Transparent; //_ws.TouchSelectionGripperBackgroundColor = Colors.Transparent; // 单元格不可编辑,图表可拖动 _ws.LockCell = true; // Wp始终不可编辑 if (Kit.IsPhoneUI) { _ws.Protect = true; } _info.Sheet = _ws; // 初始化行高列宽 for (int i = 0; i < rows.Count; i++) { _ws.Rows[i].Height = rows[i]; } for (int i = 0; i < cols.Count; i++) { _ws.Columns[i].Width = cols[i]; } // 输出所有项 foreach (RptPage page in _info.Inst.Pages) { PageDefine define = page.Rows; int startRow = define.Start; int offsetRow = define.Offset; int rowTotal = define.Total; int offsetBody = offsetRow + (page.HeaderItems.Count > 0 ? 1 : 0); define = page.Cols; int startCol = define.Start; int offsetCol = define.Offset; page.UpdatePageNum(); // 页眉 if (page.HeaderItems.Count > 0) { foreach (RptTextInst item in page.HeaderItems) { // 不渲染超出的列 int tempCol = offsetCol + item.Item.Col; if (tempCol < cols.Count) { RenderText(item, offsetRow, tempCol); } } } // 内容 foreach (RptOutputInst item in page.Items) { RptChartInst chart; int row = item.Region.Row - startRow + offsetBody; int col = item.Region.Col - startCol + offsetCol; RptTextInst txt = item as RptTextInst; if (txt != null) { Cells.Data.Cell tmpCell; CellRange range; RptText text = txt.Item as RptText; var dataRow = (txt.Item as RptText).Data; var renderCell = RenderText(txt, row, col); if (row > startRow && dataRow.Bool("hidetopdup")) { tmpCell = _ws[row - 1, col]; if (tmpCell.Tag != null && txt.Item.Data.Bool("hidetopdup") && tmpCell.Text == renderCell.Text) { range = _ws.GetSpanCell(row - 1, col); if (range != null) { tmpCell = _ws[range.Row, range.Column]; } if (tmpCell.ColumnSpan == renderCell.ColumnSpan) { tmpCell.RowSpan += renderCell.RowSpan; } } } if (col > startCol && dataRow.Bool("hideleftdup")) { tmpCell = _ws[row, col - 1]; if (tmpCell.Tag != null && txt.Item.Data.Bool("hidetopdup") && tmpCell.Text == renderCell.Text) { range = _ws.GetSpanCell(row, col - 1); if (range != null) { tmpCell = _ws[range.Row, range.Column]; } if (tmpCell.RowSpan == renderCell.RowSpan) { tmpCell.ColumnSpan += renderCell.ColumnSpan; } } } } else if ((chart = (item as RptChartInst)) != null) { ((RptChart)chart.Item).Render(_ws, row, col); } } // 页脚 if (page.FooterItems.Count > 0) { foreach (RptTextInst item in page.FooterItems) { // 不渲染超出的列 int tempCol = offsetCol + item.Item.Col; if (tempCol < cols.Count) { RenderText(item, offsetRow + rowTotal - 1, tempCol); } } } } }
/// <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_cell"></param> public void AddCell(RptTextInst p_cell) { p_cell.Parent = this; _cellInsts.Add(p_cell); }
/// <summary> /// 自动行高时重置行高,前提: /// 1. AutoHeight为true /// 2. 只占一行 /// 3. 当前输出位置在页的末尾 /// 4. 测量高度大于原高度 /// </summary> /// <param name="p_item"></param> /// <param name="p_height"></param> public void SyncRowHeight(RptTextInst p_item, double p_height) { PageDefine rows = p_item.Page.Rows; RptRegion region = p_item.Region; // 只支持当前输出位置在页的末尾,非末尾情况效率太低! if (region.Row != rows.Start + rows.Count - 1) { return; } // 无需调整 int index = rows.Count - 1; if (p_height <= rows.Size[index] || _pageEnding) { return; } // 上部高度 double topHeight = 0; for (int i = 0; i < index; i++) { topHeight += rows.Size[i]; } // 当前页能放下 if (topHeight + p_height <= BodyHeight - TblFooterHeight) { rows.Size[index] = p_height; return; } // 需要垂直分页 // 记录同行项 RptPage prePage = p_item.Page; var sameRowItems = (from item in prePage.Items where item.Region.Row == region.Row select item).ToList(); rows.Size.RemoveAt(index); if (VerPageEnd != null) { _pageEnding = true; VerPageEnd(this, rows); _pageEnding = false; } PageDefine next = new PageDefine(); next.Start = rows.Start + rows.Count; Rows.Add(next); // 重新计算行位置 int newIndex = next.Start + next.Count; double validHeight = BodyHeight - TblFooterHeight - next.Size.Sum(); if (p_height > validHeight) { p_height = validHeight; } next.Size.Add(p_height); // 处理同行项 RptPage page = CreatePage(prePage.X, prePage.Y + 1); foreach (var item in sameRowItems) { item.Region.Row = newIndex; prePage.Items.Remove(item); page.AddItem(item); } }
/// <summary> /// 添加子项 /// </summary> /// <param name="p_item"></param> public void AddChild(RptTextInst p_item) { _children.Add(p_item); p_item.Parent = this; p_item.Filter = Filter; }
/// <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; } }