如果一台电脑同时连接多个打印机,而且每个打印机使用的纸张大小各不相同(比如:票据打印钱用的小票专用张,办公打印机用的是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. JavaScript Patterns 6.5 Inheritance by Copying Properties

    Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...

  2. u盘安装CENTOS后,启动missing operating system ,只能用U盘才能启动系统

    好久之前就想把家里闲置的那台老的不能再老的笔记本换成linux的,用来学习 从N久之前用光盘安装的时候发现光驱坏掉了之后就没有再装过,最近又想安装于是就试了U盘安装 U盘安装过程也很简单,只需要制作一 ...

  3. Oracle Latch的学习【原创】

    Latch详解 - MaxChou 本文以学习为目的,大部分内容来自网络转载. 什么是Latch 串行化 数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库.多个 ...

  4. 重新认识mapreduce

    写这篇文章,是因为最近遇到了mapreduce的二次排序问题.以前的理解不完全正确.首先看一下mapreduce的过程 相信这张图熟悉MR的人都应该见过,再来一张图 wordcount也不细说了,ha ...

  5. 【转】ETL数据增量抽取——通过触发器方式实现

    在使用Kettle进行数据同步的时候, 共有 1.使用时间戳进行数据增量更新 2.使用数据库日志进行数据增量更新 3.使用触发器+快照表 进行数据增量更新 今天要介绍的是第3中方法. 实验的思路是这样 ...

  6. Oracle not in子连接查询不到值的问题(not in 不能查询null数据)

    前几天在项目中,做数据导入时,发现not in和in 查出来的条数不互补.ATABLE2明明中有些记录在ATABLE3中不存在,但是not in时查不出记录. CREATE TABLE ATABLE2 ...

  7. win8.1 user profile service 服务登录失败

    在Win 8.1 上新建个用户后,不能登录. 出现 user profile service 服务登录失败. 无法加载用户配置文件. 网上大部分相同提示的问题是有关已有账号不能再次登陆的. 解决方式是 ...

  8. Storm系列(一):搭建dotNet开发Storm拓扑的环境

    上篇博客比较了目前流行的计算框架特性,如果你是 Java 开发者,那么根据业务场景选择即可:但是如果你是 .Net 开发者,那么三者都不能拿来即用,至少在这篇文章出现之前是如此.基于上篇文章的比较发现 ...

  9. ELK Nxlog->Kafka->ElasticSearch

    Windows 系统下,log4日志通过kafka发送到elasticsearch; windows 下nxlog没有找到直接发送数据到kafka的插件,所以采用logstash中转下     Nxl ...

  10. 网页缩放对 FLASH的影响

    目前新出的,和升级的浏览器,都加了页面放大功能, 这些功能是对FLASH有影响的,表现在 flash在获取stage.stageWidth时,数值会按相应比例有变化 本人在用flex4.6开发时,自定 ...