最近做项目打印模块时,遇到了一个让人很头疼的问题.微软提供的打印中的landscape属性设置了没效果.

于是在网上查了一番资料,有些人人说微软的这个System.Drawing.Printing里面提供的是托管代码,是实现不了的,需要用平台调用使用WinAPI

 

后来我又在网上查找到了这样一片文章,从中找到一些解决的头绪.

   可以看其中的(四、横向打印问题)]

 

在里面提到了,当需要横向打印时,需要将PaperSize的高宽互换一下.

 

后来基于这个想法,我就用用打印机测试了好几遍.发现这样一个规律:

 

就是说当我们把pdoc.DefaultPageSettings.Landscape 设置为 true时,仅仅是把打印的文字和图像转向了.[在没有将PaperSize的高宽互换的前提下].

 

然后我在在打印前加了个判断,如果Landscape是true,就将PaperSize的高宽互换.结果就实现了横向打印.

 

所以我总结一句就是pdoc.DefaultPageSettings.Landscape 设置为true仅仅是将打印的内容旋转了,纸张跟着并没有旋转,需要在将纸张的高宽也跟着旋转,这样才真正实现了横向打印.

 

另外还有一个有趣的地方,在设置pdoc.DefaultPageSettings.Margins 的时候,如果设置了横向打印,那么必须把Margins 设置放在纸张旋转的前面执行,否则无法实现横向打印.

 

这里说的可能看起来还不太明白,下面把我实现的代码贴出来:

public void Print(mod_ClinicBills mcb, mod_PrintSettings mps)
        {
            theclientmcb = mcb;
            pdoc.BeginPrint += new PrintEventHandler(pdoc_BeginPrint);
            pdoc.EndPrint += new PrintEventHandler(pdoc_EndPrint);
            pdoc.PrintPage += new PrintPageEventHandler(pdoc_PrintPage);

            //配置打印机.
            pdoc.PrinterSettings.PrinterName = mps.PrinterName;
            if (!pdoc.PrinterSettings.IsValid)
            {
                printlib.ThrowPrintError(null, "门诊单据打印", "设定的不是有效的打印机!");
                return;
            }
            pdoc.PrinterSettings.Copies = mps.Copyes;
            pdoc.DefaultPageSettings.Landscape = mps.Landscape;
            pdoc.DefaultPageSettings.Margins = mps.PageMargins;
            if (mps.Landscape)
            {
                mps.PageSize = new SizeF(mps.PageSize.Height, mps.PageSize.Width);
            }
            pdoc.DefaultPageSettings.PaperSize = printlib.CMToPageSize("aetclicnicbill", mps.PageSize);
            if (mps.IsShowPreview)
            {
                pview.Document = pdoc;
                pview.ShowDialog();
            }
            else
            {
                pdoc.Print();
            }
        }

里面的两个类mod_ClinicBills , mod_PrintSettings 是我自定义的类.一个是需要打印的内容的实体类,一个是打印机和纸张设置的实体类.里面的printlib.CMToPageSize是一个类库里面的厘米转像素的静态方法.

 

我的前台调用的代码如下:

private void btnPrint_Click(object sender, EventArgs e)
        {
            mod_ClinicBills mcb = new mod_ClinicBills();
            mcb.Set_ColWidth = "50|50";
            mcb.Name = lblName.Text;
            mcb.MoneytoChinese = lblMoneytoChinese.Text;
            mcb.Money = lblMoney.Text;
            mcb.Inputer = lblInputer.Text;
            mcb.Indate = lblIndate.Text;
            mcb.Department = lblDepartment.Text;
            mcb.BillNo = lblBillNo.Text;
            mcb.DtData = dt;

            mod_PrintSettings mps=new mod_PrintSettings();
            mps.Copyes = 1;
            mps.IsShowPreview = true;
            mps.Landscape = true;
            mps.PageMargins = new System.Drawing.Printing.Margins(20, 20, 20, 20);
            mps.PageSize =new SizeF(20.16F,9.31F);
            mps.PrinterName = cboPrinterName.GetItemText(cboPrinterName.SelectedItem);
            print_ClinicBills pcb=new print_ClinicBills();
            pcb.Print(mcb,mps);
        }

这个是我自己打印测试成功的代码,希望对那些跟我遇到同样问题的朋友有所帮助!!

 

最后推荐一下我的这个编写打印的思路,我将打印的数据单独封装成一个类,将打印机设置信息单独封装成一个类,这样在前台调用的时候,数据和设置时独立的,在编程的时候就不用同时考虑两方面了.同时将打印机设置封装成类传递给打印类,这样带来一个好处就是,可以再程序中添加一个打印机配置界面,对客户提供打印机设置,和打印页面设置,是程序更加灵活.

我个人觉得这是个很好的方法,也是我在打印编程中,自己体会出来的,难得的编程经验,大家可以借鉴一下..[^-^ 王婆来了 ...]