• C#.NET 打印连续纸高度动态变化(基于长江支流的金质打印通)


    问题是这样的,打印机使用的是卷筒的连续纸,要打印的内容因为数据行数不同,高度会有变化。这时如果能在打印时动态改变纸张大小(其实只改变高度即可)当然是最好的选择。

    我使用了网上久负盛名的[长江支流]的“金质打印通”做为打印控件,挺好用的。不过并不支持动态设置纸张。每次打印都使用对话框让用户进行设置肯定是不行的。

    所有的代码,都是围绕“金质打印通”的CS版的OpenedCodes下的MisGoldPrinter类的构造函数展开的。下面是原始代码,供参考。

    public MisGoldPrinter(bool p_IsLandscape)
    {
    PrinterSingleton.Reset();
    mCurrentPageIndex = 1;
    mCurrentRowIndex = 0;

    //单一模式,全部打印对象使用下面相同的对象,提高打印速度效率
    mPrintDocument = PrinterSingleton.PrintDocument;
    mPrintDocument.DefaultPageSettings.Landscape = p_IsLandscape;
    mPrinterMargins = PrinterSingleton.PrinterMargins;

    mPrintDocument.DocumentName = "MIS金质打印通,欢迎使用!";

    _sewing = new Sewing(30,SewingDirectionFlag.Left);

    mPrinter = new Printer();
    _body = new Body(); //主要对象,所以实例化
    }

    纸是400*无限大的,页边距是20,20,40,40(Left,Right,Top,Bottom)相当于5cm,5cm,10cm,10cm

    先尝试了改变纸的高度:
    //根据行数算高度
    int h = 200 + 21 * rows + 40;
    PrinterSingleton.PrintDocument.DefaultPageSettings.PaperSize.Height = h;

    结果告诉我纸张大小不能修改,除非Kind是Custom。可是Kind明明就是Custom,我用控制面板在打印机那边已经设置了使用自定义纸张,单步调试时也看过了Kind属性确实是Custom,不过微软说不能改那就是不能改。

    那我就new一个PaperSize,在构造时设置高度总行了吧
    改成:
    int h = 200 + 21 * rows + 40;
    PrinterSingleton.PrintDocument.DefaultPageSettings.PaperSize = new PaperSize("name",400,h); //我的纸宽度是定值

    单步调试时看了,Kind也是Custom,也打印出来东西了,不过很怪的是内容全都缩在纸中间的一小块地方,周围好大的空白,再使用金质打印通里的PageSetup重新设置页边距都不行。
    于是我又加了这么一句:
    PrinterSingleton.PrinterMargins = new PrinterMargins(20,20,40,40,360,160 + 21 * rows);
    问题还是一样。
    再次单步时发现自定义的PaperSize和正常的比少点东西,它有个RawKind成员,应该说是隐藏的属性吧,自定义的对象的RawKind成员值是 Custom,而正常的则是一个数字,比如285。再结合网上的一些意见,我想这打印机是肯定不认识自定义的PaperSize了。

    逼到这个份上,只要能解决问题,怎么干都行。于是我选择了一种比较土的方法:204在 打印机上设置10几20种纸张类型,差100(合2.5cm)一个,打印时去选择最接近的。纸的名字,分别叫300,400,500...2000,方便 编程。可是怎么选纸呢?金质打印通的代码里有个自定义的PrinterPageSetting对象,可能在这里面有,不过没有公开代码(有个开源学习版也 许公开了,我没有看过,总之最后我找到答案了)
    找来找去终于找的是这一句:PrinterSingleton.PrintDocument.PrinterSettings.PaperSizes,注意有s是个数组

    因为我每次打印都要改变纸的高度,所以要传参数:数据行数。所以选纸的这部分代码不能再放到构造函数里了,增加了一个SetRows函数,修改后的代码如下:

    public MisGoldPrinter() //p_IsLandscape参数放到SetRows里。这会导致另外一个构造函数不能要了
    {
    PrinterSingleton.Reset();
    mCurrentPageIndex = 1;
    mCurrentRowIndex = 0;

    _sewing = new Sewing(30,SewingDirectionFlag.Left);

    mPrinter = new Printer();
    _body = new Body(); //主要对象,所以实例化
    }

    public void SetRows(int rows,bool p_IsLandscape)
    {
    //得到页高度
    int h = 40 + 160 + 21 * rows + 40; //每行数据大约高21,160是我的页面的Header和MultiHeader的高度,是试出来的值,呵呵
    //得到下一个接近的100的倍数
    h = Convert.ToInt16(Math.Ceiling(h / 100f) * 100);

    //用ps引用一下,减少代码长度
    Print

    移动计算的未来十年与超越

    erSettings ps = PrinterSingleton.PrintDocument.PrinterSettings;
    //选择合适的纸张
    for(int i=0;i<ps.PaperSizes.Count;i++){
    if(ps.PaperSizes[i].PaperName.Equals(Convert.ToString(h)))
    {
    PrinterSingleton.PrintDocument.DefaultPageSettings.PaperSize = ps.PaperSizes[i];
    break;
    }
    }

    mPrintDocument = PrinterSingleton.PrintDocument;
    //设置每页有多少行
    this.RowsPerPage = rows;

    mPrintDocument.DefaultPageSettings.Landscape = p_IsLandscape;
    //设置PrinterMargin
    PrinterSingleton.PrinterMargins = new PrinterMargins(20,20,40,40,360,160 + 21 * rows);
    mPrinterMargins = PrinterSingleton.PrinterMargins;

    mPrintDocument.DocumentName = "MIS金质打印通,欢迎使用www.nitoxy.com,昱昱炎炎!";
    }

    行了。虽然最多还是可能会浪费99也就是将近2.475cm的纸,不过已经可以令人满意了

  • 相关阅读:
    站点防攻击之禁止国外ip
    docker 安装rabbitMQ
    【转】浅析支付系统的整体架构
    【转】MQ详解及四大MQ比较
    SQL server 中的dbo、guest
    网站加载速度的优化(1):优化前端页面
    【转】Apache ab压力测试
    Asp.Net Core 部署发布后EFCore数据库断连和Google浏览器无法存储Cookie
    C# 使用nuget.exe发布类库及更新类库
    .net core 读取Excal文件数据及注意事项
  • 原文地址:https://www.cnblogs.com/zeroone/p/3306240.html
Copyright © 2020-2023  润新知