boyok



打印的时候纸张设置在.net中是蛮麻烦的,并不像msdn上说的那样简单,如果都是A4的纸还好,要是不同的打印机要设置不同的打印纸张那更是令人头疼。最近帮一同学做毕业设计,其中正好涉及到打印操作,在csdn上查了一下,发现很多人都遇到我同样的问题,现在我把我的解决方案与大家共享。


开始在vs2003下,DefaultPageSettings.PageSize 、PrnterSettings.PageSize 无论你怎么设置打印A4以外的纸就是有问题,在网上查了一下竟然有人说是.net的漏洞(当然不信了),百般无赖之下想到了vs2005,或许2005下面会给我一些惊喜。转战到2005下后一运行,期待的惊喜并有出现,打算要放弃了,这时我发现要是先更改打印机的默认纸张设置为A3运行程序打印A3时竟然可以,“可不可以把打印机的PageSettings对象存储起来”? 在2003里面PageSettings对象不能序列化,但在2005里面可以。 复制点soap序列化后的代码:
 <a1:PageSettings id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/System.Drawing.Printing/System.Drawing%2C%20Version%3D2.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db03f5f7f11d50a3a">
  <printerSettings href="#ref-3" />
- <color>
  <value>1</value>
  </color>
  <paperSize href="#ref-4" />
  <paperSource href="#ref-5" />
  <printerResolution href="#ref-6" />
- <landscape>
  <value>1</value>
  </landscape>
  <margins href="#ref-7" />
  </a1:PageSettings>
 
大家看看,<printerSettings href="#ref-3" /> 这是打印机的设置,<paperSize href="#ref-4" />paperSize的设置,还有其他都在里面了。好了,我们先成功存储了PageSettings对象,然后就是反序列化调用对象了。反序列化之前还要都PageSettings对象的xml文件进行一些操作以满足我们的需要。

public void changeSettings(string printerName, string paperName, int paperWidth, int paperHeight)
        {
            XmlDocument xd = new XmlDocument();
            xd.Load(@_filePath);
            XPathNavigator navi = xd.CreateNavigator();
            XmlNamespaceManager nameManager = new XmlNamespaceManager(navi.NameTable);
            nameManager.AddNamespace("SOAP-ENV","http://schemas.xmlsoap.org/soap/envelope/");
            nameManager.AddNamespace("a1", "http://schemas.microsoft.com/clr/nsassem/System.Drawing.Printing/System.Drawing%2C%20Version%3D2.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db03f5f7f11d50a3a");
            XPathNavigator node1 = navi.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/a1:PrinterSettings/printerName", nameManager);
            node1.SetValue(printerName);
            XPathNavigator node2 = navi.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/a1:PaperSize", nameManager);
            node2.SelectSingleNode("name").SetValue(paperName);
            node2.SelectSingleNode("width").SetValue(paperWidth.ToString());
            node2.SelectSingleNode("height").SetValue(paperHeight.ToString());
         //   MemoryStream ms = new MemoryStream();
            xd.Save(@_filePath);
        }
这个函数就是改动 xml文件的(本来想定义一个内存流,修改后的xml文件直接保存在其中再反序列化,但总不成功,希望网友们研究一下),按我们的要求该好后就可以反序列化了:
SoapFormatter sf = new SoapFormatter();//创建soap序列化对象
                SoapFile xmlFile = new SoapFile(@_xmlFilePath);//创建 soapFile 对象
                xmlFile.changeSettings(this._printerName, this._paperSize.PaperName, this._paperSize.Width, this._paperSize.Height);
                FileStream fs = new FileStream(@_xmlFilePath, FileMode.Open, FileAccess.Read);
                PageSettings ps = (PageSettings)sf.Deserialize(fs);// 反序列化修改后的流为pageSetting对象
                pd.DefaultPageSettings = ps;
                fs.Close();

这样就可以打印我们想要的纸张类型了,当然,运行程序前要先生成对应的打印机的PageSettings对象的xml文件,我也为此写了一个小程序。
总的来说,这样有点麻烦,但基本可以实现功能(网上看到过一篇用API实现的,看了感觉就是两个字“头晕”),如果大家有什么其它好的解决方案请也发上来交流。 ( Email:wade311@126.com )


 

posted on 2006-06-21 00:46  萧笑九州  阅读(1686)  评论(0编辑  收藏  举报

分类:

技术点:

相关文章: