zoukankan      html  css  js  c++  java
  • 打印机设置(PrintDialog)、页面设置(PageSetupDialog) 及 RDLC报表如何选择指定打印机

    如果一台电脑同时连接多个打印机,而且每个打印机使用的纸张大小各不相同(比如:票据打印钱用的小票专用张,办公打印机用的是A4标准纸),在处理打印类的需求时,如果不用代码干预,用户必须每次打印时,都必须在弹出窗口里,手动选择打印机(还有可能需要设置纸张类型),这样用起来会比较烦。

    幸好,.Net提供了“二”个很有用的类:PrintDialog(打印机设置对话框)、PageSetupDialog(页面设置对话框) (注:之所以给“二”加引号,是因为"打印机设置"其实已经完全包含了“页面设置”的所有功能,而且“ PageSetupDialog”类在实际使用中发现还有一个容易误导的地方)

    一、打印机设置(PrintDialog)

    示例代码:

    using System;
    using System.Drawing.Printing;
    using System.Windows.Forms;
    
    namespace PrintDemo
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();            
            }       
    
            private void btnPrintSet_Click(object sender, EventArgs e)
            {
                PrintDialog dlg = new PrintDialog();
                if (dlg.ShowDialog() == DialogResult.OK) {               
                    ShowInfo(dlg.PrinterSettings);
                }
            }
    
            private void ShowInfo(PrinterSettings printSettings) { 
    
                var pageSettings = printSettings.DefaultPageSettings;
                var pageSize = pageSettings.PaperSize;
    
                label1.Text = string.Format("打印机:{1}{0}纸张类型:{2}{0}纸张大小:{3}cm * {4}cm{0}纸张布局:{5}",
                    Environment.NewLine + Environment.NewLine,
                    printSettings.PrinterName,
                    pageSize.PaperName,
                    InchToCm(pageSize.Width / 100.0M).ToString("F2"),
               InchToCm(pageSize.Height / 100.0M).ToString("F2"),
               pageSettings.Landscape ? "横向" : "纵向");
            
            }
    
            const decimal K = 2.54M;
    
            private decimal InchToCm(decimal inch)
            {
                return inch * K;
            }
    
            private decimal CmToInch(decimal cm) 
            {
                return cm / K;
            }
        }
    }
    

     "打印机设置"对话框的截图如下:

    "打印机设置"对话框调用完成后,可以取回一些有用的信息,下面是一些关键信息的展示截图:

    可以看到,打印机设置界面里,已经包含了关于纸张尺寸、纸张布局(纵向、横向)的设置,所以在我看来,系统没有必要再单独提供"页面设置(PageSetupDialog)"

    二、页面设置(PageSetupDialog)
    示例代码:(在刚才的代码基础上加点东西)

    using System;
    using System.Drawing.Printing;
    using System.Windows.Forms;
    
    namespace PrintDemo
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();            
            }       
    
            /// <summary>
            /// 打印机设置
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnPrintSet_Click(object sender, EventArgs e)
            {
                PrintDialog dlg = new PrintDialog();
                if (dlg.ShowDialog() == DialogResult.OK) {               
                    ShowInfo(dlg.PrinterSettings);
                }
            }
    
            /// <summary>
            /// 页面设置
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnPageSet_Click(object sender, EventArgs e)
            {
                PageSetupDialog dlg = new PageSetupDialog();
                dlg.PageSettings = new PageSettings();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    ShowInfo(dlg.PageSettings);
                }
            }
    
            private void ShowInfo(PrinterSettings printSettings) { 
    
                var pageSettings = printSettings.DefaultPageSettings;
                var pageSize = pageSettings.PaperSize;
    
                label1.Text = string.Format("打印机:{1}{0}纸张类型:{2}{0}纸张大小:{3}cm * {4}cm{0}纸张布局:{5}",
                    Environment.NewLine + Environment.NewLine,
                    printSettings.PrinterName,
                    pageSize.PaperName,
                    HundredthsInchToCM(pageSize.Width).ToString("F1"),
               HundredthsInchToCM(pageSize.Height).ToString("F1"),
               pageSettings.Landscape ? "横向" : "纵向");
            
            }
    
            private void ShowInfo(PageSettings pageSettings)
            {
                var pageSize = pageSettings.PaperSize;
                label1.Text = string.Format("纸张类型:{1}{0}纸张大小:{2}cm * {3}cm{0}纸张布局:{4}{0}页边距:{5}",
                    Environment.NewLine + Environment.NewLine,
                    pageSize.PaperName,
                    HundredthsInchToCM(pageSize.Width).ToString("F1"),
               HundredthsInchToCM(pageSize.Height).ToString("F1"),
               pageSettings.Landscape ? "横向" : "纵向",
               MarginToString(pageSettings.Margins));
            }
    
            private string MarginToString(Margins margins) {
                return string.Format("左:{0}mm,上:{1}mm,右:{2}mm,下:{3}mm", HundredthsInchToMM(margins.Left), HundredthsInchToMM(margins.Top), HundredthsInchToMM(margins.Right), HundredthsInchToMM(margins.Bottom));                
            }
    
            const decimal K = 2.54M;       
    
            /// <summary>
            /// (百分之一)英寸制,转毫米
            /// </summary>
            /// <returns></returns>
            private int HundredthsInchToMM(decimal d) {
                return  (int)Math.Round((d / 100.00M) * K * 10);
            }
    
            /// <summary>
            /// (百分之一)英寸制,转厘米
            /// </summary>
            private decimal HundredthsInchToCM(decimal d)
            {
                return (d / 100.00M) * K;
            }
    
    
        }
    }
    

     

    这里有一个坑爹的地方,不管你如何选择Pager Size,最后返回的PageSettings里,PageSize 始终是A4纸的大小(如下图),这也是我强烈推荐大家尽量避免使用PageSettings的理由

     还有一个问题,如何在弹出这二个对话框时,默认就选中一些特定的值呢?这个容易,参见下面的代码:

            /// <summary>
            /// 打印机设置
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnPrintSet_Click(object sender, EventArgs e)
            {
                PrintDialog dlg = new PrintDialog();
                dlg.PrinterSettings = new PrinterSettings()
                {
                    PrinterName = "pdfFactory Pro"                
                };
                if (dlg.ShowDialog() == DialogResult.OK) {               
                    ShowInfo(dlg.PrinterSettings);
                }
            }
    

     这样,在弹出打印机设置界面时,就默认选中了"pdfFactory Pro"打印机(当然,这个名字必须确实是你本机安装的打印机之一,如果这个打印机名字不存在,系统仍将选中默认打印机)

            /// <summary>
            /// 页面设置
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnPageSet_Click(object sender, EventArgs e)
            {
                PageSetupDialog dlg = new PageSetupDialog();
                dlg.PageSettings = new PageSettings()
                {
                    PaperSize = new PaperSize()
                    {
                        PaperName = "A5",//其实这里不管设置什么名称,都没啥用
                        //一旦设置初始尺寸大小后,在页面设置对话框里,不管选什么纸张Size,
                        //对话框关闭时,返回值的PageSize里,始终就是这个大小,不会随用户选择而改变
                        Height = 827,
                        Width = 583
                    },
                    Landscape = false,
                    Margins = new Margins() { Left = 10, Top = 20, Bottom = 30, Right = 40 }
                };
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    ShowInfo(dlg.PageSettings);
                }
            }
    

     这样,页面设置对话框弹出时,就默认选中了布局方向为“纵向”,同时设置了边距,而且纸张大小为A5的大小(注意:PageSize的设置,在界面上看不出效果,但是关闭对话框后,返回值的PageSize里会起作用)

    三、RDLC报表用代码指定打印机、纸张大小、打印份数

    rdlc报表的预览控制ReportViewer里,已经对外暴露了PrinterSettings属性

            //
            // Summary:
            //     Gets or sets a System.Drawing.Printing.PrinterSettings object that contains
            //     the settings for the default printer and print options that are used to initialize
            //     the Print dialog and the printer's Preferences dialog.
            //
            // Returns:
            //     A System.Drawing.Printing.PrinterSettings object.
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
            [Browsable(false)]
            public PrinterSettings PrinterSettings { get; set; }
    

     以及PageSettings的set/get方法

            //
            // Summary:
            //     Returns the page settings that are used to print the current report in the
            //     ReportViewer control or display it in print layout mode.
            //
            // Returns:
            //     A System.Drawing.Printing.PageSettings object that contains the page settings
            //     that are used to print the current report in the ReportViewer control or
            //     display it in print layout mode, or null if the ReportViewer control has
            //     not yet processed a report.
            public PageSettings GetPageSettings();
    
            //
            // Summary:
            //     Sets the page settings that are used to print the current report in the ReportViewer
            //     control or display it in print layout mode.
            //
            // Parameters:
            //   pageSettings:
            //     A System.Drawing.Printing.PageSettings object that contains the new page
            //     settings.This parameter must not be null.
            public void SetPageSettings(PageSettings pageSettings);
    

     利用这些信息,就足够控制RDLC的打印机和纸张大小了,比如要指定某台打印机打印,可以这么做:

                this.reportViewer1.PrinterSettings = new PrinterSettings()
                {
                    PrinterName = "pdfFactory Pro"
                };
    

     要指定RDLC打印时,采用特定的纸张大小,可以参考下面的代码:

                var pageSettings = this.reportViewer1.GetPageSettings();
                pageSettings.PaperSize = new PaperSize()
                    {
                        Height = 100,
                        Width = 50
                    };
                pageSettings.Landscape = true;
                this.reportViewer1.SetPageSettings(pageSettings);
    

    打印份数的控制很简单:PrinterSettings类有一个Copies属性,直接给它赋值一个short型数字就行了

    最后再回到本文最开头提出的问题,知道如何用代码影响打印机、纸张大小后,最后可以将PageSettings以及PrinterSettings中的关键信息,持久化存储起来(比如:用xml或DB),下次再进入该业务界面时,根据存储的配置信息还原相关的设置,这样用户只要设置一次,以后就不用每次手动切换打印机或纸张类型了。

  • 相关阅读:
    第二章 图像的显示
    c++ 使用PI
    c++函数写的都对,还是说incompatible或者not found的解决办法
    我理解的直方图均衡化
    解决360WiFi有时候手机连接不上
    c# 16进制byte转成int
    VS2010 代码突然改变字体 解决办法
    荣耀手机恢复那些“不再提示”的设置
    mfc视类中错误:IntelliSense: declaration is incompatible with。。。解决方案
    [原] Android 自定义View步骤
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/3186398.html
Copyright © 2011-2022 走看看