您好,登錄后才能下訂單哦!
在WEB系統(tǒng)中,打印的確是比較煩人的問題,如果我們能制作一個(gè)屬于自己的自定義的打印插件,那么我們?cè)诤罄m(xù)自定義打印的時(shí)候能隨心所欲的控制打印,這樣的效果對(duì)于程序員來說是非常開心的一件事件,本文將自己開發(fā)編寫的C# 制作的HTML打印插件分享出來,讓有同樣需求的朋友提供一個(gè)參考;此插件是基于Microsoft .NET Framework 2.0 開發(fā)的,缺點(diǎn)是每臺(tái)客戶端在安裝插件時(shí),必須要安裝Microsoft .NET Framework 2.0 ;本插件能實(shí)現(xiàn) 頁眉、頁腳、表頭、標(biāo)題、表尾的分頁打??;支持紙張類型、自動(dòng)補(bǔ)充空行等功能;由于技術(shù)有限,肯定有很多不足的地方,請(qǐng)批評(píng)指正!
由于本打印插件是基于我們開發(fā)平臺(tái)的報(bào)表基礎(chǔ)來開發(fā)設(shè)計(jì)的,所以打印控件的原理:通過JS將頁面表格數(shù)據(jù)生成固定格式的XML字符串(圖片通過64base圖片格式)傳送給打印插件,有打印插件自主繪圖生成打印頁面。E_Print插件可以在WEB或WinForm中使用:
打印插件完整源碼:E_Print.rar (包含插件源碼、打包程序、winform調(diào)試DEMO)
下面貼出源碼:(在源碼中有詳細(xì)的注釋說明)
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace E_Print { /// <summary> /// 分頁計(jì)算 /// </summary> public class PagingCalc { #region 私有變量 /// <summary> /// 表格區(qū)域 /// </summary> private RectangleF _tableRect; /// <summary> /// 報(bào)表行集 /// </summary> private List<Row> _rowsList; /// <summary> /// 是否每頁打印標(biāo)題 /// </summary> private bool _isAllPrintTitle; /// <summary> /// 是否每頁打印表頭 /// </summary> private bool _isAllPrintHead; /// <summary> /// 是否每頁打印表尾 /// </summary> private bool _isAllPrintFoot; /// <summary> /// 標(biāo)題行集 /// </summary> private List<Row> TitleList; /// <summary> /// 表頭前行集 /// </summary> private List<Row> HForeList; /// <summary> /// 表頭行集 /// </summary> private List<Row> HeadList; /// <summary> /// 數(shù)據(jù)行集 /// </summary> private List<Row> DataList; /// <summary> /// 表尾行集 /// </summary> private List<Row> FootList; /// <summary> /// 每頁打印標(biāo)題+表頭高度 /// </summary> private float _myHeadPix; /// <summary> /// 每頁打印表尾高度 /// </summary> private float _myFootPix; #endregion #region 構(gòu)造方法 /// <summary> /// 構(gòu)造函數(shù) /// </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 = 0; _myFootPix = 0; } #endregion #region 屬性方法 /// <summary> /// 獲取--設(shè)置--表格區(qū)域 /// </summary> public RectangleF TableRect { get { return _tableRect; } set { _tableRect = value; } } /// <summary> /// 獲取--設(shè)置--表格行集 /// </summary> public List<Row> RowsList { get { return _rowsList; } set { _rowsList = value; } } /// <summary> /// 獲取--設(shè)置--是否每頁打印標(biāo)題 /// </summary> public bool IsAllPrintTitle { get { return _isAllPrintTitle; } set { _isAllPrintTitle = value; } } /// <summary> /// 獲取--設(shè)置--是否每頁打印表頭 /// </summary> public bool IsAllPrintHead { get { return _isAllPrintHead; } set { _isAllPrintHead = value; } } /// <summary> /// 獲取--設(shè)置--是否每頁打印表尾 /// </summary> public bool IsAllPrintFoot { get { return _isAllPrintFoot; } set { _isAllPrintFoot = value; } } /// <summary> /// 獲取--設(shè)置--每頁打印標(biāo)題+表頭高度 /// </summary> public float MyHeadPix { get { return _myHeadPix; } set { _myHeadPix = value; } } /// <summary> /// 獲取--設(shè)置--每頁打印表尾巴高度 /// </summary> public float MyFootPix { get { return _myFootPix; } set { _myFootPix = value; } } #endregion #region 計(jì)算方法 /// <summary> /// 分頁計(jì)算 /// </summary> /// <returns></returns> public List<PagingItem> CalcPages() { List<PagingItem> retPages = new List<PagingItem>(); // 無需分頁 if (Get_TableAllHeight() <= TableRect.Height) { PagingItem tmItem0 = new PagingItem(); tmItem0.PageNum = 1; for (int y = 0; y < RowsList.Count; y++) { tmItem0.IndexList.Add(y); } retPages.Add(tmItem0); } else // 需要分頁 { // 有設(shè)置了 每頁打印標(biāo)題、表頭、表位 其中的任意一個(gè) if (Get_IsCusSet_THDF()) // 則執(zhí)行每頁相對(duì)分頁 { Paging_Relative(0, ref retPages); // 計(jì)算每頁打印頭尾高度 MyHeadPix = 0; if (IsAllPrintTitle) { MyHeadPix += Get_TableTileHeight(); } if (IsAllPrintHead) { MyHeadPix += Get_TableHeadHeight(); } if (IsAllPrintFoot) { MyFootPix = Get_TableFootHeight(); } } else // 執(zhí)行直接數(shù)據(jù)分頁 { Paging_Direct(0, ref retPages); } } return retPages; } /// <summary> /// 直接分頁 /// </summary> /// <param name="startR">開始行號(hào)</param> /// <param name="pages">頁面數(shù)組</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 + 1; for (int t = startR; t < RowsList.Count; t++) { // 檢查行內(nèi)單元格是否不允許分頁兩種情況:條形碼,圖片 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 <= 0) { startR = t; pages.Add(p_Item); Paging_Direct(startR, ref pages); break; } else { p_Item.IndexList.Add(t); if (t == RowsList.Count - 1) { pages.Add(p_Item); } } } } } /// <summary> /// 相對(duì)分頁 /// </summary> /// <param name="startR">開始序號(hào)</param> /// <param name="pages">頁面數(shù)組</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 + 1; // 分頁頁碼 bool runNext = false; // 繼續(xù)分頁 #region 每頁打印標(biāo)題 // 每頁打印標(biāo)題 if (IsAllPrintTitle) { p_Height -= Get_TableTileHeight(); foreach (Row p_Row in TitleList) p_Item.IndexList.Add(p_Row.RowIndex); } else { if (p_Item.PageNum == 1) // 第一頁特殊處理 { 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 == 1) // 第一頁特殊處理 { // 計(jì)算表頭前的行高 p_Height -= Get_TableHForHeight(); foreach (Row p_Row in HForeList) p_Item.IndexList.Add(p_Row.RowIndex); } // 計(jì)算表頭行的高度 p_Height -= Get_TableHeadHeight(); foreach (Row p_Row in HeadList) p_Item.IndexList.Add(p_Row.RowIndex); } else { if (p_Item.PageNum == 1) // 第一頁特殊處理 { // 計(jì)算表頭前的行高 p_Height -= Get_TableHForHeight(); foreach (Row p_Row in HForeList) p_Item.IndexList.Add(p_Row.RowIndex); // 計(jì)算表頭行的高度 p_Height -= Get_TableHeadHeight(); foreach (Row p_Row in HeadList) p_Item.IndexList.Add(p_Row.RowIndex); } } #endregion #region 每頁數(shù)據(jù)區(qū)域 // 每頁數(shù)據(jù)劃分 if (IsAllPrintFoot) { p_Height -= Get_TableFootHeight(); // 表格高度 先減去表尾的高度 } for (int t = startR; t < DataList.Count; t++) { // 檢查行內(nèi)單元格是否不允許分頁兩種情況:條形碼,圖片 if (Paging_CheckCell(DataList[t], p_Height)) // 此情況下,單元格不能分割,并且高度超過頁面剩余高度,所以要啟動(dòng)新的一頁 { startR = t; runNext = true; break; } else { p_Height -= DataList[t].RowHeight; if (p_Height <= 0) { 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> /// 檢查行內(nèi)單元格如果是圖片 /// 并且合并行數(shù)大于1 /// </summary> /// <param name="cRow"></param> /// <param name="cHeight"></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> /// 獲取--報(bào)表全部高度 /// </summary> /// <returns></returns> private float Get_TableAllHeight() { float retHight = 0; for (int k = 0; k < RowsList.Count; k++) { Row t_Row = RowsList[k]; retHight += t_Row.RowHeight; } return retHight; } /// <summary> /// 獲取是否設(shè)置了標(biāo)題、表頭、表尾 中的任意一個(gè) /// </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> /// 獲取--報(bào)表標(biāo)題高度 /// </summary> /// <returns></returns> private float Get_TableTileHeight() { float retHight = 0; for (int k = 0; k < TitleList.Count; k++) retHight += TitleList[k].RowHeight; return retHight; } /// <summary> /// 獲取--報(bào)表表頭前高度 /// </summary> /// <returns></returns> private float Get_TableHForHeight() { float retHight = 0; for (int k = 0; k < HForeList.Count; k++) retHight += HForeList[k].RowHeight; return retHight; } /// <summary> /// 獲取--報(bào)表表頭高度 /// </summary> /// <returns></returns> private float Get_TableHeadHeight() { float retHight = 0; for (int k = 0; k < HeadList.Count; k++) retHight += HeadList[k].RowHeight; return retHight; } /// <summary> /// 獲取--報(bào)表表尾高度 /// </summary> /// <returns></returns> private float Get_TableFootHeight() { float retHight = 0; for (int k = 0; k < FootList.Count; k++) retHight += FootList[k].RowHeight; return retHight; } /// <summary> /// 拆分報(bào)表區(qū)域 /// </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 = 0; m < RowsList.Count; m++) { Row mmRow = RowsList[m]; switch (mmRow.RowType.ToLower()) { case "t": // 標(biāo)題 TitleList.Add(mmRow); break; case "h": // 表頭 HeadList.Add(mmRow); break; case "f": // 表尾 FootList.Add(mmRow); break; case "d": // 數(shù)據(jù) default: DataList.Add(mmRow); break; } } // 設(shè)置表頭前行集 if (TitleList.Count == 0 && HeadList.Count > 0) { List<Row> tmpList = new List<Row>(); for (int n = 0; n < DataList.Count; n++) { if (DataList[n].RowIndex < HeadList[0].RowIndex) { HForeList.Add(DataList[n]); tmpList.Add(DataList[n]); } } for (int n = 0; n < tmpList.Count; n++) { DataList.Remove(tmpList[n]); } tmpList.Clear(); } // 重設(shè)表尾 不是每頁打印表尾情況下,那么表位就去掉 if (!IsAllPrintFoot) { foreach (Row tRow in FootList) DataList.Add(tRow); FootList.Clear(); } } #endregion } }
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。