打印机设置(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),下次再进入该业务界面时,根据存储的配置信息还原相关的设置,这样用户只要设置一次,以后就不用每次手动切换打印机或纸张类型了。

 

 

时间: 2024-09-13 02:23:59

打印机设置(PrintDialog)、页面设置(PageSetupDialog) 及 RDLC报表如何选择指定打印机的相关文章

ASP.NET MVC应用程序展示RDLC报表

原文:ASP.NET MVC应用程序展示RDLC报表 学习ASP.NET MVC这样久,在学习,练习与应用过程中,觉得很多知识与以前的ASP.NET多有区别,但是实现操作起来,细处又有许多相近的地方. 本篇跟大家一起学习RDLC报表,是在ASP.NET MVC应用程序中实现.在实现过程中,Insus.NET也将把一些常见的问题列举与提供解决方法. 首先我们在数据库准备数据,表,存储过程等,数据应用以前练习的数据,写一个存储过程好了.   在ASP.NET MVC应用程序目录结构下的Entitie

求教,RDLC报表里能否直接设置每张纸打两页(同一面),而不用去打印机里设置?

问题描述 RDLC报表里能否直接设置每张纸打两页(同一面),而不用去打印机里设置? 解决方案 解决方案二:引用楼主fmcsjs9877的回复: RDLC报表里能否直接设置每张纸打两页(同一面),而不用去打印机里设置? 楼主你的rdlc报表在FIREFOX中打印按钮正常显示吗?

NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现(二)

打印|对话框|页面 前篇说了.NET环境下有关打印页面设置.打印机设置.打印预览对话框的实现,现在到了我们应用它们的时候了. 我们需要做下面的一些事情: 1.将上篇中写的程序输出类型改为类库并编译成PrinterPageSetting.dll; 2.建立C#或VB.net项目,并在项目的引用处添加引用,在弹出的对话框的.NET标签中浏览并选择PrinterPageSetting.dll: 3.在默认窗口Form1上增加一个TextBox文本框控件,默认名TextBox1(实际项目中建议采用命名及

微软RDLC报表如何设置文字间距?

问题描述 微软RDLC报表中,文本框中的文字如何设置间距?类似css中的letter-space

VS2010 Rdlc报表打印问题!

问题描述 遇到一个RDLC报表打印的问题,请求大家给予支持目前做了一个报表打印,设置报表-报表属性-布局中的页面宽度:21cm页面高度:9cm报表主体属性中Size18.5cm,5cm打印结果是竖的.可加QQ:4983187 解决方案 解决方案二:顶一个,希望有类似情况的,给个解决方案解决方案三:求给力.求解...........解决方案四:这个能调吧你条准确了就没问题了吧解决方案五: 解决方案六:你是不是想把它打印出来的结果是居中?问题没有描述清楚..解决方案七:你是不是想把它打印出来的结果是

ASP.NET中动态控制RDLC报表

asp.net|动态|控制 在asp.net程序中,可以选择使用水晶报表,功能确实强大.但是web版的水晶报表好像存在版权的问题.如果所作报表不是复杂的一塌糊涂的话,可以使用微软自带的Rdlc报表. Rdlc优点: 1:Rdlc报表设计简单 2:结果存成xml,易于控制 3:导出格式作的很不错 这里所说的动态控制报表所指的是:在一些时候,制作了报表之后希望在运行中可以动态的做一些小修改,比如说列的位置,用户控制显示那些列等等. 控制方法,尝试了这么几种: 1:控制微软提供的报表对象的属性: 2:

OEA 框架中集成的 RDLC 报表介绍

之前 OEA 一直用着一个 Delphi 开发的报表,所以两年来我一直就想在 OEA 中构建一个纯 .NET 的报表模块,但是一想到要开发复杂的报表引擎和设计器就觉得麻烦.所以这事一直拖着.最近开始研究一些成熟的报表引擎,经过对比,还是发现微软的 RLDC 报表已经能满足我大多数需求.其中包括表格.矩阵.图表 等复杂控件,同时同样的报表格式在 B/S 模式下也可以直接使用,最新的 Tablix 控件非常灵活,能实现大多数表格样式.所以我决定不再费时费力去造一个轮子,而是直接把微软的 RDLC 报

&quot;RDLC报表&quot;速成指南

RDLC报表是微软自家的报表,已经集成在vs2010中,相对水晶报表更轻量级,更重要的是:可直接在web项目中使用. 使用步骤: 一.创建DataSet 右击->Add New Item-> DataSet(本例中命名为DS_EMP),会出现以下界面: 然后右击->Add->DataTable,添加一个表,命名为T_EMP,然后添加二个列EMPNO,EMPNAME均为String型,完成后的样子类似下现这样: 注:如果机器上安装了BizTalk,DataSet打开后,可能是下面这样

&quot;RDLC&quot;报表-参数传递及主从报表

今天继续学习RDLC报表的"参数传递"及"主从报表" 一.先创建DataSet,如下图: 二.创建一个报表rptDEPT.rdlc,显示部门T_DPET的数据 三.嵌入Default.aspx中,写在Default.aspx.cs中写些基本代码 using System; using System.Data; using Microsoft.Reporting.WebForms; namespace ReportSample { public partial cla