温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

网页WEB打印控件制作-开放源码

发布时间:2020-06-27 13:30:03 来源:网络 阅读:497 作者:szzzzn 栏目:开发技术

 在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
    }
}

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI