Example #1
0
 /// <summary>
 /// 输出到指定页面
 /// </summary>
 /// <param name="p_page"></param>
 public void Output(RptPage p_page)
 {
     foreach (RptTextInst item in _children)
     {
         item.OutputHeader(p_page);
     }
 }
Example #2
0
        /// <summary>
        /// 切换页面时在新页重复表头
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnPageBegin(object sender, RptPage e)
        {
            if (_header != null && (_item as RptTable).RepeatHeader)
            {
                int index             = _data.Current;
                RptTblHeaderInst inst = _header.Clone() as RptTblHeaderInst;

                RptRegion region = new RptRegion(
                    e.Rows.Start,
                    _region.Col,
                    inst.Item.RowSpan,
                    inst.Item.ColSpan);
                inst.Region = region;

                double height = _item.Part.GetRowHeight(region.Row + region.RowSpan - e.Rows.Start);
                if (e.Rows.Size.Count > 0 && height != e.Rows.Size[0])
                {
                    e.Rows.Size[0] = height;
                }
                inst.Output();
                _data.Current = index;

                // 顺次下移
                if (_curPart != null)
                {
                    _curPart.Region.Row = region.Row + region.RowSpan;
                }
            }
        }
Example #3
0
        /// <summary>
        /// 创建输出页面
        /// </summary>
        /// <param name="p_x"></param>
        /// <param name="p_y"></param>
        /// <returns></returns>
        RptPage CreatePage(int p_x, int p_y)
        {
            if (p_x >= PageCols)
            {
                PageCols = p_x + 1;
            }
            RptPage page = new RptPage(p_x, p_y, this);

            Pages.Add(page);

            if (p_x > 0)
            {
                HorPageBegin?.Invoke(this, page);
            }

            if (p_y > 0)
            {
                VerPageBegin?.Invoke(this, page);
            }

            // 输出新页面时重复页眉页脚
            if (Header != null)
            {
                Header.Clone().Output(page);
            }

            if (Footer != null)
            {
                Footer.Clone().Output(page);
            }
            return(page);
        }
Example #4
0
        /// <summary>
        /// 输出报表项
        /// </summary>
        /// <param name="p_item">报表项</param>
        public void OutputItem(RptOutputInst p_item)
        {
            PrepareItem(p_item);

            // 报表项所在页位置
            int     pageX = GetPageIndex(Cols, p_item.Region.Col);
            int     pageY = GetPageIndex(Rows, p_item.Region.Row);
            RptPage page  = GetPage(pageX, pageY);

            if (page == null)
            {
                page = CreatePage(pageX, pageY);
            }

            if (p_item.Parent is RptTblRowInst && p_item.Region.Row != p_item.Parent.Region.Row)
            {
                p_item.Region.Row = p_item.Parent.Region.Row;
            }

            page.AddItem(p_item);
        }
Example #5
0
        /// <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);
                    }
                }
            }
        }
Example #6
0
        /// <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);
                    }
                }
            }
        }
Example #7
0
 /// <summary>
 /// 输出到指定页的页脚
 /// </summary>
 /// <param name="p_page"></param>
 public void OutputFooter(RptPage p_page)
 {
     _page = p_page;
     p_page.FooterItems.Add(this);
     ParseValue();
 }
Example #8
0
        /// <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);
            }
        }