Example #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="p_def"></param>
 /// <param name="p_index"></param>
 /// <returns></returns>
 int GetPageIndex(List <PageDefine> p_def, int p_index)
 {
     for (int i = 0; i < p_def.Count; i++)
     {
         PageDefine def = p_def[i];
         if (p_index >= def.Start && p_index < def.Start + def.Count)
         {
             return(i);
         }
     }
     throw new Exception("给定位置不在页面中!");
 }
Example #2
0
        /// <summary>
        /// 垂直分页
        /// </summary>
        /// <param name="p_rowPage"></param>
        /// <param name="p_topHeight"></param>
        /// <param name="p_inItem"></param>
        void VerPageBreak(ref PageDefine p_rowPage, ref double p_topHeight, bool p_inItem = true)
        {
            // 上页结束
            if (p_inItem && VerPageEnd != null)
            {
                _pageEnding = true;
                VerPageEnd(this, p_rowPage);
                _pageEnding = false;
            }

            PageDefine next = new PageDefine();

            next.Start = p_rowPage.Start + p_rowPage.Count;
            Rows.Add(next);
            p_topHeight = 0;
            p_rowPage   = next;
        }
Example #3
0
        /// <summary>
        /// 水平分页
        /// </summary>
        /// <param name="p_colPage"></param>
        /// <param name="p_leftWidth"></param>
        /// <param name="p_inItem"></param>
        void HorPageBreak(ref PageDefine p_colPage, ref double p_leftWidth, bool p_inItem = true)
        {
            //上页结束
            if (p_inItem && HorPageEnd != null)
            {
                _pageEnding = true;
                HorPageEnd(this, p_colPage);
                _pageEnding = false;
            }

            PageDefine next = new PageDefine();

            next.Start = p_colPage.Start + p_colPage.Count;
            Cols.Add(next);
            p_leftWidth = 0;
            p_colPage   = next;
        }
Example #4
0
        /// <summary>
        /// 切换页面时在旧页重复表尾
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnPageEnd(object sender, PageDefine e)
        {
            if (_footer != null && (_item as RptTable).RepeatFooter)
            {
                int index               = _data.Current;
                RptTblFooterInst inst   = _footer.Clone() as RptTblFooterInst;
                RptRegion        region = new RptRegion(
                    e.Start + e.Count,
                    _region.Col,
                    inst.Item.RowSpan,
                    inst.Item.ColSpan);
                inst.Region = region;
                inst.Output();
                _data.Current = index;

                // 顺次下移
                if (_curPart != null)
                {
                    _curPart.Region.Row = region.Row + region.RowSpan;
                }
            }
        }
Example #5
0
        /// <summary>
        /// 是否需要垂直分页
        /// </summary>
        /// <param name="p_item"></param>
        /// <returns></returns>
        public bool TestPageBreak(RptItemInst p_item)
        {
            RptRegion   region    = p_item.Region;
            PageDefine  rowPage   = Rows[Rows.Count - 1];
            int         lastRow   = rowPage.Start + rowPage.Count;
            int         deltaRow  = region.Row + region.RowSpan - lastRow;
            RptItemBase item      = p_item.Item;
            double      topHeight = 0;

            if (deltaRow > 0)
            {
                topHeight = rowPage.Size.Sum();
            }
            else
            {
                for (int i = 0; i < region.Row - rowPage.Start; i++)
                {
                    topHeight += rowPage.Size[i];
                }
            }
            return(topHeight + item.Height > BodyHeight - TblFooterHeight);
        }
Example #6
0
        /// <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);
                        }
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// 补充报表项及左上的行列定义,处理分页
        /// </summary>
        /// <param name="p_item"></param>
        void PrepareItem(RptItemInst p_item)
        {
            RptRegion   region   = p_item.Region;
            RptItemBase item     = p_item.Item;
            PageDefine  rowPage  = Rows[Rows.Count - 1];
            PageDefine  colPage  = Cols[Cols.Count - 1];
            int         lastRow  = rowPage.Start + rowPage.Count;
            int         lastCol  = colPage.Start + colPage.Count;
            int         deltaRow = region.Row + region.RowSpan - lastRow;
            int         deltaCol = region.Col + region.ColSpan - lastCol;

            //已经垂直分页
            if (region.Row < rowPage.Start && region.Row + region.RowSpan > rowPage.Start)
            {
                deltaRow   = region.RowSpan - rowPage.Count;
                region.Row = rowPage.Start;
            }
            //已经水平分页
            if (region.Col < colPage.Start && region.Col + region.ColSpan > colPage.Start)
            {
                deltaCol   = region.ColSpan - colPage.Count;
                region.Col = colPage.Start;
            }

            // 无需补充
            if (deltaRow <= 0 && deltaCol <= 0)
            {
                return;
            }

            // 补充行定义
            if (deltaRow > 0)
            {
                // 页面已有的总高
                double topHeight = rowPage.Size.Sum();
                int    blankRow  = deltaRow - region.RowSpan;
                double heights   = 0;
                if (blankRow < 0)
                {
                    for (int i = 0; i < deltaRow; i++)
                    {
                        heights += item.Part.GetRowHeight(item.Row + item.RowSpan - deltaRow + i);
                    }

                    //需要分页
                    if (!_pageEnding && topHeight + heights > (BodyHeight - TblFooterHeight) && region.Row != rowPage.Start)
                    {
                        VerPageBreak(ref rowPage, ref topHeight);

                        //从元素的起始位置开始分页
                        for (int j = 0; j < region.RowSpan; j++)
                        {
                            double height = item.Part.GetRowHeight(item.Row + j);
                            rowPage.Size.Add(height);
                            topHeight += height;
                        }
                    }
                    else
                    {
                        //不需要分页
                        for (int i = 0; i < deltaRow; i++)
                        {
                            double height = item.Part.GetRowHeight(item.Row + item.RowSpan - deltaRow + i);
                            if (topHeight + height > (BodyHeight - TblFooterHeight))//元素高度大于页面高度,截断
                            {
                                height = (BodyHeight - TblFooterHeight - topHeight) < 0 ? 0 : BodyHeight - TblFooterHeight - topHeight;
                            }
                            rowPage.Size.Add(height);
                            topHeight += height;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < deltaRow; i++)
                    {
                        double height = item.Part.GetRowHeight(item.Row + item.RowSpan - deltaRow + i);
                        if (i == blankRow)
                        {
                            for (int j = i; j < deltaRow; j++)
                            {
                                heights += item.Part.GetRowHeight(item.Row + item.RowSpan - deltaRow + j);
                            }
                        }

                        // 在报表项上
                        bool inItem = lastRow + i >= region.Row;
                        if (height > BodyHeight - TblFooterHeight)
                        {
                            height = BodyHeight - TblFooterHeight;
                        }
                        if (i == blankRow && heights > BodyHeight - TblFooterHeight)
                        {
                            heights = BodyHeight - TblFooterHeight;
                        }

                        // 需要垂直分页
                        bool verBreak = (i == blankRow) ? (topHeight + heights > BodyHeight - TblFooterHeight)
                            : (topHeight + height > BodyHeight - TblFooterHeight);
                        if (!_pageEnding && verBreak)
                        {
                            VerPageBreak(ref rowPage, ref topHeight, inItem);
                        }
                        rowPage.Size.Add(height);
                        topHeight += height;
                    }
                }

                // 重新计算行位置
                region.Row = rowPage.Start + rowPage.Count - region.RowSpan;
            }

            //补充列定义
            if (deltaCol > 0)
            {
                // 页面已有的宽度
                double leftWidth = colPage.Size.Sum();
                int    blankCol  = deltaCol - region.ColSpan;
                double widths    = 0;

                //不需要补充空行
                if (blankCol < 0)
                {
                    for (int i = 0; i < deltaCol; i++)
                    {
                        widths += Info.Root.Cols[item.Col + item.ColSpan - deltaCol + i];
                    }

                    //需要分页
                    if (!_pageEnding && leftWidth + widths > BodyWidth && region.Col != colPage.Start)
                    {
                        HorPageBreak(ref colPage, ref leftWidth);

                        //从元素的起始位置开始分页
                        for (int j = 0; j < region.ColSpan; j++)
                        {
                            double width = Info.Root.Cols[item.Col + j];
                            colPage.Size.Add(width);
                            leftWidth += width;
                        }
                    }
                    else
                    {
                        //不需要分页
                        for (int i = 0; i < deltaCol; i++)
                        {
                            double width = Info.Root.Cols[item.Col + item.ColSpan - deltaCol + i];
                            if (leftWidth + width > BodyWidth)//元素宽度大于页面宽度,截断
                            {
                                width = (BodyWidth - leftWidth) < 0 ? 0 : BodyWidth - leftWidth;
                            }
                            colPage.Size.Add(width);
                            leftWidth += width;
                        }
                    }
                }
                else
                {
                    //需要空行补充
                    for (int i = 0; i < deltaCol; i++)
                    {
                        double width = Info.Root.Cols[item.Col + item.ColSpan - deltaCol + i];
                        if (i == blankCol)
                        {
                            for (int j = i; j < deltaCol; j++)
                            {
                                widths += Info.Root.Cols[item.Col + item.ColSpan - deltaCol + j];
                            }
                        }

                        // 在报表项上
                        bool inItem = lastCol + i >= region.Col;
                        // 需要水平分页
                        bool horBreak = (i == blankCol) ? (leftWidth + widths > BodyWidth) : (leftWidth + width > BodyWidth);
                        if (!_pageEnding && horBreak)
                        {
                            HorPageBreak(ref colPage, ref leftWidth, inItem);
                        }
                        colPage.Size.Add(width);
                        leftWidth += width;
                    }
                }

                // 重新计算列位置
                region.Col = colPage.Start + colPage.Count - region.ColSpan;
            }
        }
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);
            }
        }