您好,登錄后才能下訂單哦!
在WEB系統中,打印的確是比較煩人的問題,如果我們能制作一個屬于自己的自定義的打印插件,那么我們在后續自定義打印的時候能隨心所欲的控制打印,這樣的效果對于程序員來說是非常開心的一件事件,本文將自己開發編寫的C# 制作的HTML打印插件分享出來,讓有同樣需求的朋友提供一個參考;此插件是基于Microsoft .NET Framework 2.0 開發的,缺點是每臺客戶端在安裝插件時,必須要安裝Microsoft .NET Framework 2.0 ;本插件能實現 頁眉、頁腳、表頭、標題、表尾的分頁打印;支持紙張類型、自動補充空行等功能;由于技術有限,肯定有很多不足的地方,請批評指正!
由于本打印插件是基于我們開發平臺的報表基礎來開發設計的,所以打印控件的原理:通過JS將頁面表格數據生成固定格式的XML字符串(圖片通過64base圖片格式)傳送給打印插件,有打印插件自主繪圖生成打印頁面。E_Print插件可以在WEB或WinForm中使用:
打印插件完整源碼:E_Print.rar (包含插件源碼、打包程序、winform調試DEMO)
下面貼出源碼:(在源碼中有詳細的注釋說明)
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 = 0; _myFootPix = 0; } #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 tmItem0 = new PagingItem(); tmItem0.PageNum = 1; for (int y = 0; y < RowsList.Count; y++) { tmItem0.IndexList.Add(y); } retPages.Add(tmItem0); } else // 需要分頁 { // 有設置了 每頁打印標題、表頭、表位 其中的任意一個 if (Get_IsCusSet_THDF()) // 則執行每頁相對分頁 { Paging_Relative(0, ref retPages); // 計算每頁打印頭尾高度 MyHeadPix = 0; if (IsAllPrintTitle) { MyHeadPix += Get_TableTileHeight(); } if (IsAllPrintHead) { MyHeadPix += Get_TableHeadHeight(); } if (IsAllPrintFoot) { MyFootPix = Get_TableFootHeight(); } } else // 執行直接數據分頁 { Paging_Direct(0, ref retPages); } } return retPages; } /// <summary> /// 直接分頁 /// </summary> /// <param name="startR">開始行號</param> /// <param name="pages">頁面數組</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++) { // 檢查行內單元格是否不允許分頁兩種情況:條形碼,圖片 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> /// 相對分頁 /// </summary> /// <param name="startR">開始序號</param> /// <param name="pages">頁面數組</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; // 繼續分頁 #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 == 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) // 第一頁特殊處理 { // 計算表頭前的行高 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 == 1) // 第一頁特殊處理 { // 計算表頭前的行高 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 <= 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> /// 檢查行內單元格如果是圖片 /// 并且合并行數大于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> /// 獲取--報表全部高度 /// </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> /// 獲取是否設置了標題、表頭、表尾 中的任意一個 /// </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 = 0; for (int k = 0; k < TitleList.Count; k++) retHight += TitleList[k].RowHeight; return retHight; } /// <summary> /// 獲取--報表表頭前高度 /// </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> /// 獲取--報表表頭高度 /// </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> /// 獲取--報表表尾高度 /// </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> /// 拆分報表區域 /// </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": // 標題 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 == 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(); } // 重設表尾 不是每頁打印表尾情況下,那么表位就去掉 if (!IsAllPrintFoot) { foreach (Row tRow in FootList) DataList.Add(tRow); FootList.Clear(); } } #endregion } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。