网页WEB打印控件制作(2)

using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.DrawingD; using System.IO; namespace E_Print { /// <summary> /// 报表绘制 /// </summary> public class ReportDraw { #region 私有成员 /// <summary> /// 当前页码 /// </summary> private int _curPageNum; /// <summary> /// 总共页数 /// </summary> private int _allPageNum; /// <summary> /// 表格矩形 /// </summary> private RectangleF _reptRect; /// <summary> /// 报表全部行集 /// </summary> private List<Row> _rowsList; /// <summary> /// 分页页面数组 /// </summary> private List<PagingItem> _pageList; /// <summary> /// 是否每页打印标题 /// </summary> private bool _isAllPrintTitle; /// <summary> /// 是否每页打印表头 /// </summary> private bool _isAllPrintHead; /// <summary> /// 是否每页打印表尾 /// </summary> private bool _isAllPrintFoot; /// <summary> /// 是否末页自动补行 /// </summary> private bool _isAutoFillRow; /// <summary> /// 缩小比例 /// </summary> private float _zoom; /// <summary> /// 字符溢出处理方式 /// </summary> private bool _isOverFlow; /// <summary> /// 每页打印的标题+表头的高度 /// </summary> private float _headPix; /// <summary> /// 每页打印的表尾高度 /// </summary> private float _footPix; #endregion #region 构造方法 /// <summary> /// 构造函数 /// </summary> public ReportDraw() { _curPageNum = ; _allPageNum = ; _reptRect = new RectangleF(); _rowsList = new List<Row>(); _pageList = new List<PagingItem>(); _isAllPrintTitle = false; _isAllPrintHead = false; _isAllPrintFoot = false; _isAutoFillRow = false; _zoom = ; _isOverFlow = false; _headPix = ; _footPix = ; } /// <summary> /// 构造函数 /// </summary> /// <param>每页打印标题</param> /// <param>每页打印表头</param> /// <param>每页打印表位</param> /// <param>自动补全空行</param> /// <param>报表尺寸矩形</param> /// <param>字符溢出处理</param> public ReportDraw(bool printTitle, bool printHead, bool printFoot, bool fillRows, RectangleF tableRect, bool overFlow) { _reptRect = tableRect; _isAllPrintTitle = printTitle; _isAllPrintHead = printHead; _isAllPrintFoot = printFoot; _isAutoFillRow = fillRows; _isOverFlow = overFlow; _curPageNum = ; _allPageNum = ; _zoom = ; _rowsList = new List<Row>(); _pageList = new List<PagingItem>(); _headPix = ; _footPix = ; } #endregion #region 属性方法 /// <summary> /// 获取--设置--当前页码 /// </summary> public int CurPageNum { get { return _curPageNum; } set { _curPageNum = value; } } /// <summary> /// 获取--设置--总共页数 /// </summary> public int AllPageNum { get { return _allPageNum; } set { _allPageNum = value; } } /// <summary> /// 获取--设置--表格矩形 /// </summary> public RectangleF ReptRect { get { return _reptRect; } set { _reptRect = value; } } /// <summary> /// 获取--设置--报表全部行集 /// </summary> public List<Row> RowsList { get { return _rowsList; } set { _rowsList = value; } } /// <summary> /// 获取--设置--分页页面数组 /// </summary> public List<PagingItem> PageList { get { return _pageList; } set { _pageList = value; } } /// <summary> /// 获取--设置--是否每页打印标题 /// </summary> public bool IsAllPrintTitle { get { return _isAllPrintTitle; } set { _isAllPrintTitle = value; } } /// <summary> /// 获取--设置--是否每页打印表头 /// </summary> public bool IsAllPrintHead { get { return _isAllPrintHead; } set { _isAllPrintHead = value; } } /// <summary> /// 获取--设置--是否每页打印表尾 /// </summary> public bool IsAllPrintFoot { get { return _isAllPrintFoot; } set { _isAllPrintFoot = value; } } /// <summary> /// 获取--设置--末页是否自动补行 /// </summary> public bool IsAutoFillRow { get { return _isAutoFillRow; } set { _isAutoFillRow = value; } } /// <summary> /// 获取--设置--缩小比例 /// </summary> public float Zoom { get { return _zoom; } set { _zoom = value; } } /// <summary> /// 获取--设置--字符溢出处理方式 /// </summary> public bool IsOverFlow { get { return _isOverFlow; } set { _isOverFlow = value; } } /// <summary> /// 获取--设置--每页打印的标题+表头高度 /// </summary> public float HeadPix { get { return _headPix; } set { _headPix = value; } } /// <summary> /// 获取--设置--每页打印的表尾高度 /// </summary> public float FootPix { get { return _footPix; } set { _footPix = value; } } #endregion #region 计算分页 /// <summary> /// 计算分页 /// </summary> public void CalcPaging() { // 分页实例 PagingCalc insCalc = new PagingCalc(); insCalc.TableRect = this.ReptRect; insCalc.RowsList = this.RowsList; insCalc.IsAllPrintTitle = this.IsAllPrintTitle; insCalc.IsAllPrintHead = this.IsAllPrintHead; insCalc.IsAllPrintFoot = this.IsAllPrintFoot; // 分页计算 _pageList = insCalc.CalcPages(); this._allPageNum = _pageList.Count; this._curPageNum = ; this._headPix = insCalc.MyHeadPix; this._footPix = insCalc.MyFootPix; } #endregion #region 绘制方法 /// <summary> /// 绘制报表 /// </summary> /// <param></param> /// <returns>返回是否结束</returns> public bool DrawReport(Graphics g) { bool isMorePage = false; float offsetX = _reptRect.X; // X 偏移量 float offsetY = _reptRect.Y; // Y 偏移量 bool isCanFillRow = false; // 是否需要补行 bool isFillFlag = false; // 是否已经补过 int isFillRowNum = ; // 需要补充几行 PagingItem nowPage = GetPageItem(CurPageNum); // 当前页 if (nowPage != null) { #region 判定高度不足是否自动补行 // 判定补行条件 报表设置了末页不足自动补行、同时 为最后一页 if (_isAutoFillRow == true && CurPageNum == AllPageNum) { // 判定页面高度 与 数据高度 float N_PageHeith = ReptRect.Height; // 当前页面高度 float N_DataHeith = GetThisPageDataRowsHeight(); // 当前数据高度 // 补行行高 while ((N_DataHeith + (isFillRowNum + ) * * Zoom) < N_PageHeith) { isFillRowNum++; } if (isFillRowNum > ) isCanFillRow = true; } #endregion #region 首先绘制上一页补充单元格 if (CurPageNum > ) { PagingItem prePage = GetPageItem(CurPageNum - ); // 上一页 if (prePage != null) { foreach (PagingMakeUp tmMk in prePage.MakeupList) { // 绘制补充单元格(上页中未绘制完成的单元格) DrawTD(g, tmMk.MakeupCell, offsetX, offsetY, true, tmMk.MakeupHeight, false); } } } #endregion #region 其次绘制当前页面的单元格 // 其次绘制当前页的单元格 for (int ii = ; ii < nowPage.IndexList.Count; ii++) { // 先绘制 TD CELL 单元格 Row rowTR = GetRow(nowPage.IndexList[ii]); #region 执行补行 if (isCanFillRow == true && rowTR.RowType.ToLower().Trim() == "f") // 需要补行 行标志为F 表尾前进行补充空行 { Row fillRow = new Row(); if (ii == ) fillRow = rowTR; else fillRow = GetRow(nowPage.IndexList[ii - ]); if (fillRow != null) // 绘制自动补充的空行单元格 { // 开始补充空行 for (int fi = ; fi <= isFillRowNum; fi++) { bool bcFlag = true; // 绘制单元格 foreach (Cell fillTdCell in fillRow.RowCells) { if (bcFlag) { // 绘制边框线(合并单元格的情况才用到) if (fillTdCell.RectX > ) { DrawLine(g, offsetX, offsetY, offsetX, offsetY + .F * Zoom); // 最左边竖线 DrawLine(g, offsetX, offsetY + .F * Zoom, offsetX + fillTdCell.RectX, offsetY + .F * Zoom); } bcFlag = false; } DrawTD(g, fillTdCell, offsetX, offsetY, false, , true); } // 再将偏移量+行号 补充的行高全部为px offsetY += * Zoom; } } isFillFlag = true; } #endregion #region 正常绘制 foreach (Cell td in rowTR.RowCells) { DrawTD(g, td, offsetX, offsetY, false, , false); } // 再将偏移量+行号 offsetY += rowTR.RowHeight; #endregion } // 判定是否补过;没有补充过,则在最后进行补充空行 if ((isCanFillRow == true) && (isFillFlag == false) && (nowPage.IndexList.Count > )) { Row fillRow = GetRow(nowPage.IndexList[nowPage.IndexList.Count - ]); if (fillRow != null) // 绘制自动补充的空行单元格 { // 开始补充空行 for (int fi = ; fi <= isFillRowNum; fi++) { bool newFlag = true; foreach (Cell fillTdCell in fillRow.RowCells) { if (newFlag) { // 绘制边框线(合并单元格的情况才用到) if (fillTdCell.RectX > ) { DrawLine(g, offsetX, offsetY, offsetX, offsetY + .F * Zoom); // 最左边竖线 DrawLine(g, offsetX, offsetY + .F * Zoom, offsetX + fillTdCell.RectX, offsetY + .F * Zoom); } newFlag = false; } DrawTD(g, fillTdCell, offsetX, offsetY, false, , true); } offsetY += * Zoom; // 再将偏移量+行号 补充的行高全部为px } } } #endregion if (CurPageNum < AllPageNum) { isMorePage = true; // 还有下页 CurPageNum++; // 页码增加 } } return isMorePage; } /// <summary> /// 绘制单元格 /// </summary> /// <param>绘图对象</param> /// <param>单元格</param> /// <param>X偏移量</param> /// <param>Y坐标值</param> /// <param>是否补充单元格</param> /// <param>补充单元格高度</param> /// <param>自动补行的单元格</param> private void DrawTD(Graphics g, Cell tdCell, float setX, float setY, bool isMakeup, float mkH, bool fillCell) { #region 参数变量 Pen pen; Brush brush; // 获取单元格绘制坐标矩形信息 float tdX = tdCell.RectX + setX; float tdY = setY; float tdW = tdCell.RectW; float tdH = ; if (fillCell) { tdH = * Zoom; // 自动补行的单元格的高度固定为px } else { if (isMakeup) // 补充单元格 { tdH = mkH; tdY = tdY + HeadPix; // 如果是补充单元格,则此单元格的Y坐标:如果每页打印标题或表头,则Y坐标 需要下移 HeadPix } else // 实际单元格 { tdH = tdCell.RectH; } if (tdCell.RowSpan > ) // 判定单元格高度是否超过底线 { tdH = Calc_CellOverHeight(tdCell, tdY, tdH); } } #endregion #region 绘制背景 // 填充颜色 brush = new SolidBrush(tdCell.BackColor); g.FillRectangle(brush, tdX + .f * Zoom, tdY + .f * Zoom, tdW - .f * Zoom, tdH - .f * Zoom); #endregion #region 绘制边框 // 左边框线 if (tdCell.LeftBorder.LineWidth > ) { pen = new Pen(tdCell.LeftBorder.LineColor); pen.DashStyle = tdCell.LeftBorder.LineDash; pen.Width = tdCell.LeftBorder.LineWidth; g.DrawLine(pen, tdX, tdY, tdX, tdY + tdH); } // 上边框线 if (tdCell.TopBorder.LineWidth > ) { pen = new Pen(tdCell.TopBorder.LineColor); pen.DashStyle = tdCell.TopBorder.LineDash; pen.Width = tdCell.TopBorder.LineWidth; g.DrawLine(pen, tdX, tdY, tdX + tdW, tdY); } // 右边框线 if (tdCell.RightBorder.LineWidth > ) { pen = new Pen(tdCell.RightBorder.LineColor); pen.DashStyle = tdCell.RightBorder.LineDash; pen.Width = tdCell.RightBorder.LineWidth; g.DrawLine(pen, tdX + tdW, tdY, tdX + tdW, tdY + tdH); } // 下边框线 if (tdCell.BottomBorder.LineWidth > ) { pen = new Pen(tdCell.BottomBorder.LineColor); pen.DashStyle = tdCell.BottomBorder.LineDash; pen.Width = tdCell.BottomBorder.LineWidth; g.DrawLine(pen, tdX, tdY + tdH, tdX + tdW, tdY + tdH); } #endregion #region 绘制文字 if (!fillCell) { RectangleF rect = new RectangleF(tdX, tdY, tdW, tdH); if (tdCell.IsImage) { this.DrawImg(g, rect, tdCell.ImageUrl); } else { brush = new SolidBrush(tdCell.FontColor); this.DrawStr(g, rect, brush, tdCell.CellFont, tdCell.strFormat, tdCell.Value); } } #endregion } /// <summary> /// 绘制字符串 /// 溢出时,换行缩小字符 /// 字体缩小到的最小值不得小于 /// </summary> /// <param>绘图对象</param> /// <param>文本区域</param> /// <param>文本笔画</param> /// <param>文本字体</param> /// <param>文本格式</param> /// <param>文本字符</param> /// <returns></returns> private void DrawStr(Graphics g, RectangleF strRect, Brush strBrush, Font strFont, StringFormat strFormat, string strValue) { // 报表设置:字符溢出不做处理 if (!this.IsOverFlow) { g.DrawString(strValue, strFont, strBrush, strRect, strFormat); } else // 需要处理 { // 测量字体的宽度和高度 会发现误差很大,如果一个一个的测量,误差就实在太大,所以这里就用简单的方式来进行处理 SizeF sf = g.MeasureString(strValue, strFont); // 此种方式测量误差很大,如果 if (strRect.Width > sf.Width) { g.DrawString(strValue, strFont, strBrush, strRect, strFormat); } else { // 计算换行后字符的全部高度是否满足 int maxLines = ; // 计算当前字符当前字体最大打印的行数 maxLines = (int)Math.Ceiling((double)sf.Width / (double)strRect.Width); if (strRect.Height >= maxLines * sf.Height) { g.DrawString(strValue, strFont, strBrush, strRect, strFormat); } else { float tmScale = strRect.Height / (maxLines * sf.Height); Font tmNewFont = new Font(strFont.Name, strFont.Size * tmScale, strFont.Style, GraphicsUnit.Point); g.DrawString(strValue, tmNewFont, strBrush, strRect, strFormat); } } } } /// <summary> /// 绘制图片 /// 将Base图片流字符串转换成图片并进行绘制 /// </summary> /// <param></param> /// <param></param> /// <param></param> private void DrawImg(Graphics g, RectangleF strRect, string baseImg) { if (baseImg.Trim() == "") return; string imgStr = baseImg.Replace("data:image/gif;base,", "").Trim(); if (imgStr == "") return; // 生成图片 try { MemoryStream stream = new MemoryStream(Convert.FromBaseString(imgStr)); Bitmap picImg = new Bitmap(stream); RectangleF imgRectF = new RectangleF(f, f, (float)picImg.Width, (float)picImg.Height); // 原始图片矩形 RectangleF newRectF = new RectangleF(strRect.X + f, strRect.Y + f, (float)strRect.Width - f, (float)strRect.Height - f); // 绘制图片矩形 g.DrawImage(picImg, newRectF, imgRectF, GraphicsUnit.Pixel); // 绘制缩放图片 stream.Close(); } catch { return; } } /// <summary> /// 绘制线条 /// </summary> /// <param>绘图对象</param> /// <param>开始X</param> /// <param>开始Y</param> /// <param>结束X</param> /// <param>结束Y</param> private void DrawLine(Graphics g, float start_X, float start_Y, float end_X, float end_Y) { Pen linePen = new Pen(Color.Black, .f); linePen.DashStyle = DashStyle.Solid; g.DrawLine(linePen, start_X, start_Y, end_X, end_Y); } private float ChangeUnit(float vSize) { return (vSize * f / f * f / f); } /// <summary> /// 获取行对象 /// </summary> /// <param></param> /// <returns></returns> private Row GetRow(int rowIndex) { foreach (Row retRow in _rowsList) { if (retRow.RowIndex == rowIndex) return retRow; } return null; } /// <summary> /// 获取分页页面 /// </summary> /// <param>页码</param> /// <returns></returns> private PagingItem GetPageItem(int pNo) { foreach (PagingItem retPItem in PageList) { if (retPItem.PageNum == pNo) return retPItem; } return null; } /// <summary> /// 计算绘制高度 /// 判定并且计算单元格高度是否超过当前页面所有行高度的底线 /// </summary> /// <param>单元格</param> /// <param>Y 轴坐标值</param> /// <param>H 当前高度</param> /// <returns></returns> private float Calc_CellOverHeight(Cell mCell, float mY, float mH) { float returnHeight = ; // 返回高度 float tm_AllTrHeight = GetThisPageDataRowsHeight(); // 当前页面内所有数据行的高度 float tm_RealY = ; // 相对最大Y值 float tm_AbsY = ; // 实际最大Y值 float tm_OverPlus = ; // 单元格剩余高度 tm_RealY = mY + mH; // 实际最大Y值 if (IsAllPrintFoot) // 每页打印表尾 tm_AbsY = ReptRect.Y + (tm_AllTrHeight - FootPix); // 需要减去表尾高度 else tm_AbsY = tm_AllTrHeight + ReptRect.Y; if (tm_RealY > tm_AbsY) { returnHeight = tm_AbsY - mY; // 当前页面实际最大高度-单元格的当前Y坐标值 = 返回单元格在本页内需要绘制的高度 tm_OverPlus = mH - returnHeight; // 当前高度-单元格当前页面需要绘制的高度=下页需要绘制的补充高度 // 将当前单元格添加到后页需要补充绘制数组中去 PagingItem nPageItem = GetPageItem(CurPageNum); PagingMakeUp nMakeUp = new PagingMakeUp(); nMakeUp.MakeupCell = mCell; nMakeUp.MakeupHeight = tm_OverPlus; nPageItem.MakeupList.Add(nMakeUp); } else { returnHeight = mH; } return returnHeight; } /// <summary> /// 获取本页内所有数据行的高度 /// </summary> /// <returns></returns> private float GetThisPageDataRowsHeight() { float retHeight = ; PagingItem oThisPage = GetPageItem(CurPageNum); // 当前页 foreach (int oRowIndex in oThisPage.IndexList) { Row oThisRow = GetRow(oRowIndex); retHeight += oThisRow.RowHeight; } return retHeight; } /// <summary> /// 获取页内某一项所属行的高度 /// </summary> /// <param>页面对象</param> /// <param>本页行数组中的某一项的序号</param> /// <returns></returns> private float GetThisPageOneRowHeight(PagingItem itemPage, int itemIndex) { float retHeight = ; if (itemIndex < itemPage.IndexList.Count && itemIndex >= ) { Row oThisRow = GetRow(itemPage.IndexList[itemIndex]); retHeight = oThisRow.RowHeight; } return retHeight; } #endregion } } 3、PagingCalc 分页计算类 using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace E_Print { /// <summary> /// 分页计算 /// </summary> public class PagingCalc { #region 私有变量 /// <summary> /// 表格区域 /// </summary> private RectangleF _tableRect; /// <summary> /// 报表行集 /// </summary> private List<Row> _rowsList; /// <summary> /// 是否每页打印标题 /// </summary> private bool _isAllPrintTitle; /// <summary> /// 是否每页打印表头 /// </summary> private bool _isAllPrintHead; /// <summary> /// 是否每页打印表尾 /// </summary> private bool _isAllPrintFoot; /// <summary> /// 标题行集 /// </summary> private List<Row> TitleList; /// <summary> /// 表头前行集 /// </summary> private List<Row> HForeList; /// <summary> /// 表头行集 /// </summary> private List<Row> HeadList; /// <summary> /// 数据行集 /// </summary> private List<Row> DataList; /// <summary> /// 表尾行集 /// </summary> private List<Row> FootList; /// <summary> /// 每页打印标题+表头高度 /// </summary> private float _myHeadPix; /// <summary> /// 每页打印表尾高度 /// </summary> private float _myFootPix; #endregion #region 构造方法 /// <summary> /// 构造函数 /// </summary> public PagingCalc() { _tableRect = new RectangleF(); _rowsList = new List<Row>(); _isAllPrintTitle = false; _isAllPrintHead = false; _isAllPrintFoot = false; TitleList = new List<Row>(); HForeList = new List<Row>(); HeadList = new List<Row>(); DataList = new List<Row>(); FootList = new List<Row>(); _myHeadPix = ; _myFootPix = ; } #endregion #region 属性方法 /// <summary> /// 获取--设置--表格区域 /// </summary> public RectangleF TableRect { get { return _tableRect; } set { _tableRect = value; } } /// <summary> /// 获取--设置--表格行集 /// </summary> public List<Row> RowsList { get { return _rowsList; } set { _rowsList = value; } } /// <summary> /// 获取--设置--是否每页打印标题 /// </summary> public bool IsAllPrintTitle { get { return _isAllPrintTitle; } set { _isAllPrintTitle = value; } } /// <summary> /// 获取--设置--是否每页打印表头 /// </summary> public bool IsAllPrintHead { get { return _isAllPrintHead; } set { _isAllPrintHead = value; } } /// <summary> /// 获取--设置--是否每页打印表尾 /// </summary> public bool IsAllPrintFoot { get { return _isAllPrintFoot; } set { _isAllPrintFoot = value; } } /// <summary> /// 获取--设置--每页打印标题+表头高度 /// </summary> public float MyHeadPix { get { return _myHeadPix; } set { _myHeadPix = value; } } /// <summary> /// 获取--设置--每页打印表尾巴高度 /// </summary> public float MyFootPix { get { return _myFootPix; } set { _myFootPix = value; } } #endregion #region 计算方法 /// <summary> /// 分页计算 /// </summary> /// <returns></returns> public List<PagingItem> CalcPages() { List<PagingItem> retPages = new List<PagingItem>(); // 无需分页 if (Get_TableAllHeight() <= TableRect.Height) { PagingItem tmItem = new PagingItem(); tmItem.PageNum = ; for (int y = ; y < RowsList.Count; y++) { tmItem.IndexList.Add(y); } retPages.Add(tmItem); } else // 需要分页 { // 有设置了 每页打印标题、表头、表位 其中的任意一个 if (Get_IsCusSet_THDF()) // 则执行每页相对分页 { Paging_Relative(, ref retPages); // 计算每页打印头尾高度 MyHeadPix = ; if (IsAllPrintTitle) { MyHeadPix += Get_TableTileHeight(); } if (IsAllPrintHead) { MyHeadPix += Get_TableHeadHeight(); } if (IsAllPrintFoot) { MyFootPix = Get_TableFootHeight(); } } else // 执行直接数据分页 { Paging_Direct(, ref retPages); } } return retPages; } /// <summary> /// 直接分页 /// </summary> /// <param>开始行号</param> /// <param>页面数组</param> private void Paging_Direct(int startR, ref List<PagingItem> pages) { float p_Height = TableRect.Height; PagingItem p_Item = new PagingItem(); p_Item.PageNum = pages.Count + ; for (int t = startR; t < RowsList.Count; t++) { // 检查行内单元格是否不允许分页两种情况:条形码,图片 if (Paging_CheckCell(RowsList[t], p_Height)) { startR = t; pages.Add(p_Item); Paging_Direct(startR, ref pages); break; } else { p_Height -= RowsList[t].RowHeight; if (p_Height <= ) { startR = t; pages.Add(p_Item); Paging_Direct(startR, ref pages); break; } else { p_Item.IndexList.Add(t); if (t == RowsList.Count - ) { pages.Add(p_Item); } } } } } /// <summary> /// 相对分页 /// </summary> /// <param>开始序号</param> /// <param>页面数组</param> private void Paging_Relative(int startR, ref List<PagingItem> pages) { SplitReportArea(); // 拆分表行 float p_Height = TableRect.Height; // 页面总高 PagingItem p_Item = new PagingItem(); // 分页页面 p_Item.PageNum = pages.Count + ; // 分页页码 bool runNext = false; // 继续分页 #region 每页打印标题 // 每页打印标题 if (IsAllPrintTitle) { p_Height -= Get_TableTileHeight(); foreach (Row p_Row in TitleList) p_Item.IndexList.Add(p_Row.RowIndex); } else { if (p_Item.PageNum == ) // 第一页特殊处理 { p_Height -= Get_TableTileHeight(); foreach (Row p_Row in TitleList) p_Item.IndexList.Add(p_Row.RowIndex); } } #endregion #region 每页打印表头 // 每页打印表头 if (IsAllPrintHead) { if (p_Item.PageNum == ) // 第一页特殊处理 { // 计算表头前的行高 p_Height -= Get_TableHForHeight(); foreach (Row p_Row in HForeList) p_Item.IndexList.Add(p_Row.RowIndex); } // 计算表头行的高度 p_Height -= Get_TableHeadHeight(); foreach (Row p_Row in HeadList) p_Item.IndexList.Add(p_Row.RowIndex); } else { if (p_Item.PageNum == ) // 第一页特殊处理 { // 计算表头前的行高 p_Height -= Get_TableHForHeight(); foreach (Row p_Row in HForeList) p_Item.IndexList.Add(p_Row.RowIndex); // 计算表头行的高度 p_Height -= Get_TableHeadHeight(); foreach (Row p_Row in HeadList) p_Item.IndexList.Add(p_Row.RowIndex); } } #endregion #region 每页数据区域 // 每页数据划分 if (IsAllPrintFoot) { p_Height -= Get_TableFootHeight(); // 表格高度 先减去表尾的高度 } for (int t = startR; t < DataList.Count; t++) { // 检查行内单元格是否不允许分页两种情况:条形码,图片 if (Paging_CheckCell(DataList[t], p_Height)) // 此情况下,单元格不能分割,并且高度超过页面剩余高度,所以要启动新的一页 { startR = t; runNext = true; break; } else { p_Height -= DataList[t].RowHeight; if (p_Height <= ) { startR = t; runNext = true; break; } else { p_Item.IndexList.Add(DataList[t].RowIndex); } } } #endregion #region 每页打印表尾 // 每页打印表尾 if (IsAllPrintFoot) { foreach (Row p_Row in FootList) p_Item.IndexList.Add(p_Row.RowIndex); } #endregion #region 添加分页页面 pages.Add(p_Item); if (runNext) { Paging_Relative(startR, ref pages); } #endregion } /// <summary> /// 检查行内单元格如果是图片 /// 并且合并行数大于 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> private bool Paging_CheckCell(Row cRow, float cHeight) { foreach (Cell cCell in cRow.RowCells) { if (cCell.IsImage == true) { if (cCell.RectH > cHeight) return true; } } return false; } #endregion #region 辅助方法 /// <summary> /// 获取--报表全部高度 /// </summary> /// <returns></returns> private float Get_TableAllHeight() { float retHight = ; for (int k = ; k < RowsList.Count; k++) { Row t_Row = RowsList[k]; retHight += t_Row.RowHeight; } return retHight; } /// <summary> /// 获取是否设置了标题、表头、表尾 中的任意一个 /// </summary> /// <returns></returns> private bool Get_IsCusSet_THDF() { string tmType = ""; foreach (Row cusRow in this.RowsList) { tmType = cusRow.RowType.ToLower().Trim(); if (tmType == "t" || tmType == "h" || tmType == "f") return true; } return false; } /// <summary> /// 获取--报表标题高度 /// </summary> /// <returns></returns> private float Get_TableTileHeight() { float retHight = ; for (int k = ; k < TitleList.Count; k++) retHight += TitleList[k].RowHeight; return retHight; } /// <summary> /// 获取--报表表头前高度 /// </summary> /// <returns></returns> private float Get_TableHForHeight() { float retHight = ; for (int k = ; k < HForeList.Count; k++) retHight += HForeList[k].RowHeight; return retHight; } /// <summary> /// 获取--报表表头高度 /// </summary> /// <returns></returns> private float Get_TableHeadHeight() { float retHight = ; for (int k = ; k < HeadList.Count; k++) retHight += HeadList[k].RowHeight; return retHight; } /// <summary> /// 获取--报表表尾高度 /// </summary> /// <returns></returns> private float Get_TableFootHeight() { float retHight = ; for (int k = ; k < FootList.Count; k++) retHight += FootList[k].RowHeight; return retHight; } /// <summary> /// 拆分报表区域 /// </summary> public void SplitReportArea() { TitleList = new List<Row>(); HForeList = new List<Row>(); HeadList = new List<Row>(); DataList = new List<Row>(); FootList = new List<Row>(); for (int m = ; m < RowsList.Count; m++) { Row mmRow = RowsList[m]; switch (mmRow.RowType.ToLower()) { case "t": // 标题 TitleList.Add(mmRow); break; case "h": // 表头 HeadList.Add(mmRow); break; case "f": // 表尾 FootList.Add(mmRow); break; case "d": // 数据 default: DataList.Add(mmRow); break; } } // 设置表头前行集 if (TitleList.Count == && HeadList.Count > ) { List<Row> tmpList = new List<Row>(); for (int n = ; n < DataList.Count; n++) { if (DataList[n].RowIndex < HeadList[].RowIndex) { HForeList.Add(DataList[n]); tmpList.Add(DataList[n]); } } for (int n = ; n < tmpList.Count; n++) { DataList.Remove(tmpList[n]); } tmpList.Clear(); } // 重设表尾 不是每页打印表尾情况下,那么表位就去掉 if (!IsAllPrintFoot) { foreach (Row tRow in FootList) DataList.Add(tRow); FootList.Clear(); } } #endregion } }

4、PagingMakeUp 分页补充绘制类

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjypwg.html