如果一台电脑同时连接多个打印机,而且每个打印机使用的纸张大小各不相同(比如:票据打印钱用的小票专用张,办公打印机用的是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),下次再进入该业务界面时,根据存储的配置信息还原相关的设置,这样用户只要设置一次,以后就不用每次手动切换打印机或纸张类型了。

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

  1. RDLC报表问题:尚未指定报表“Report1”的报表定义

    原文:尚未指定报表“Report1”的报表定义 在做RDLC项目中遇到这样的错误 本地报表处理期间出错. 尚未指定报表“Report1”的报表定义 未将对象引用设置到对象的实例. 解决方案: 打开re ...

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

    原文:ASP.NET MVC应用程序展示RDLC报表 学习ASP.NET MVC这样久,在学习,练习与应用过程中,觉得很多知识与以前的ASP.NET多有区别,但是实现操作起来,细处又有许多相近的地方. ...

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

    原文:.NET环境下有关打印页面设置.打印机设置.打印预览对话框的实现 我个人认为,开发MIS,首先就得解决网格的问题,而开发工具为我们提供了如DataGrid.MSHFlexGrid的控件.其次,是 ...

  4. 在RDLC报表中对纸张的设置

    RDLC报表是存放成XML文件格式的,这一点你可以直接打开RDLC报表文件看一下,而且在使用时,通过ReportViewer来读取报表并与数据源进行合成,也就是说RDLC是定义了一个格式,那就不能通过 ...

  5. C# RDLC报表不出现预览窗体直接输出到打印机

    #region 直接打印区域 /// <summary> /// 直接打印到打印机 /// </summary> /// <param name="report ...

  6. rdlc报表大小设置

    参考:http://stackoverflow.com/questions/427730/how-to-limit-rdlc-report-for-one-page-in-a-pdf 主要设置为:报表 ...

  7. (转)打印相关_C#(PrintDocument、PrintDialog、PageSetupDialog、PrintPreviewDialog)

    原文地址:http://www.cnblogs.com/smallsoftfox/archive/2012/06/25/2562718.html 参考文章:http://www.cnblogs.com ...

  8. C# WinForm RDLC报表不预览直接连续打印

    用微软的RDLC报表直接打印不预览 直接上代码. //打印清单 System.Data.DataTable dt = print_QD(dr); ReportViewer rvDoc = new Re ...

  9. 动态生成RDLC报表

    前段时间,做了RDLC报表,主要是三块功能: 1.从DataGrid提取(包括最新的增删改)的数据,自动生成对应的RDLC报表文件(以流的形式驻存在内存中),用ReportViewer类来展示.打印. ...

随机推荐

  1. Comparable接口与Comparator接口的区别

    1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的, 什么是自定义class: 如 public class Pe ...

  2. MongoDB-集群搭建

    前言 搭建一个MongoDB的集群,这个环境只是内网的一个测试环境,分片没有使用副本集,配置并分配好端口后,开启集群的身份验证功能,在开启集群权限时,有些注意事项,在搭建过程中会着重标出. 一.集群规 ...

  3. javascript-抽象工厂模式

    抽象工厂模式笔记   1.抽象工厂模式创建多个抽象类,创建出的结果是一个类簇(这里是抽象类的集合)   2.抽象工厂中传入的父类是否是抽象工厂方法创建的抽象类进行判断,不是则抛出错误   3.子类通过 ...

  4. sed实例精解--例说sed完整版

    原文地址:sed实例精解--例说sed完整版 作者:xiaozhenggang 最近在学习shell,怕学了后面忘了前面的就把学习和实验的过程记录下来了.这里是关于sed的,前面有三四篇分开的,现在都 ...

  5. 解决内网主机ping不通网关能ping内网

    有一台笔记本电脑可以自动获取IP,可以和内网其他主机互相PING通,就是PING 不通网关,只能上内网,不能上外网,IP换到其他主机上也可以上外网,说明路由器上没什么限制.路由器也查了,电脑也重装了, ...

  6. 六轴加速度传感器MPU6050官方DMP库到瑞萨RL78/G13的移植

    2015年的电赛已经结束了.赛前接到器件清单的时候,看到带防护圈的多旋翼飞行器赫然在列,又给了一个瑞萨RL78/G13的MCU,于是自然联想到13年的电赛,觉得多半是拿RL78/G13做四旋翼的主控, ...

  7. Linux 下从头再走 GTK+-3.0 (二)

    仅仅创建一个空白窗口是不够的,下面我们为创建的窗口添加一个按钮. 以 Hello,World!为例. 首先创建一个源文件:example2.c 内容如下. #include <gtk/gtk.h ...

  8. 【HTML5】标记文字

    1.用基本的文字元素标记内容 先看显示效果: 对应HTML代码: <!DOCTYPE html> <html lang="en"> <head> ...

  9. AppStore ipa (苹果内购)笔记

    内购示意图 准备条件 苹果的开发者证书,已经为应用启用App内购,并在Xcode更新配置文件 itunes store设置 itunes中创建App及其它设置 参考:iOS应用程序内购/内付费(一)  ...

  10. Win7虚拟机无法打开内核设备:\\Global\\vmx86

    Win7虚拟机无法打开内核设备:\\Global\\vmx86 听语音 | 浏览:16844 | 更新:2014-07-21 11:21 | 标签:虚拟机 1 2 3 4 5 6 7 分步阅读 一键约 ...