水晶报表攻克系列3-如何在程序中自定义纸张

水晶报表攻克系列3-如何在程序中自定义纸张

  大家都知道电脑里会有预定义好的纸张,例如A4。但是最近做发票,快递单时,纸张大小需要自定义。

  例如:

1     ReportDocument doc = new ReportDocument();
2     doc.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.PaperA4;

  CrystalDecisions.Shared.PaperSize查看定义可知,是一个枚举类,里面只有41种预定义的纸张类型。而且,doc.PrintOptions.PaperSize不可以自定义纸张的宽和高。

  

  经过查阅资料,有一种比较好的办法:

  1) 在开始菜单,“打印机和传真”=》文件菜单项,服务器属性中,添加自定义纸张,设置自定义纸张的名称。

  2) 在程序中就可以通过获取该自定义纸张的id,来设置PaperSize,程序如下:

  

1         doc.PrintOptions.PaperSize = (CrystalDecisions.Shared.PaperSize)(GetSelectedPaperSizeId());
 1         /// <summary>
 2         /// 获取用户自定义纸张ID
 3         /// </summary>
 4         public int GetSelectedPaperSizeId()
 5         {
 6             string printer = "";
 7             string printerName = PrinterSetting.PostPrinterName;
 8             string paperName = PrinterSetting.PostPrinterUserPaperSize;
 9             foreach (string printerItem in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
10             {
11                 if (printerItem.Contains(printerName))
12                 {
13                     printer = printerItem;
14                 }
15             }
16             Microsoft.Win32.RegistryKey rk;
17             if (!printer.StartsWith(@"\\"))        //本地打印机
18             {
19                 rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers\\" + printer + "\\DsDriver");
20             }
21             else                                //网络打印机
22             {
23 
24                 string[] p = printer.Remove(0, 2).Split(new char[] { '\\' });
25                 string path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Providers\\LanMan Print Services\\Servers\\" + p[0] + "\\Printers\\" + p[1] + "\\DsDriver";
26                 rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path);
27             }
28 
29             string[] papers = (string[])(rk.GetValue("printMediaSupported"));
30             int index = 0;
31             int paperid = 0;
32             foreach (string paper in papers)
33             {
34                 if (paper == paperName)
35                 {
36                     paperid = index;
37                 }
38                 index++;
39             }
40 
41             int[] sizes = PrinterHelper.Get_PaperSizes(printerName);
42             int paperSizeid = sizes[paperid];
43             return paperSizeid;
44         }

  其中PrinterHelper类如下:

  

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Runtime.InteropServices;
 6 
 7 namespace Gasgoo.Invoice.Common
 8 {
 9     public class PrinterHelper
10     {
11         public static string OutputPort = String.Empty;
12 
13         [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
14         public static extern int DeviceCapabilities(string pDevice, string pPort, short fwCapabilities, IntPtr pOutput, IntPtr pDevMode);
15 
16         public static int[] Get_PaperSizes(string printer)
17         {
18             string text1 = printer;
19             int num1 = FastDeviceCapabilities(0x10, IntPtr.Zero, -1, text1);
20             if (num1 == -1)
21             {
22                 return new int[0];
23             }
24             int num2 = Marshal.SystemDefaultCharSize * 0x40;
25             IntPtr ptr1 = Marshal.AllocCoTaskMem(num2 * num1);
26             FastDeviceCapabilities(0x10, ptr1, -1, text1);
27             IntPtr ptr2 = Marshal.AllocCoTaskMem(2 * num1);
28             FastDeviceCapabilities(2, ptr2, -1, text1);
29             IntPtr ptr3 = Marshal.AllocCoTaskMem(8 * num1);
30             FastDeviceCapabilities(3, ptr3, -1, text1);
31             int[] sizeArray1 = new int[num1];
32             for (int num3 = 0; num3 < num1; num3++)
33             {
34                 string text2 = Marshal.PtrToStringAuto((IntPtr)(((long)ptr1) + (num2 * num3)), 0x40);
35                 int num4 = text2.IndexOf('\0');
36                 if (num4 > -1)
37                 {
38                     text2 = text2.Substring(0, num4);
39                 }
40                 short num5 = Marshal.ReadInt16((IntPtr)(((long)ptr2) + (num3 * 2)));
41                 int num6 = Marshal.ReadInt32((IntPtr)(((long)ptr3) + (num3 * 8)));
42                 int num7 = Marshal.ReadInt32((IntPtr)((((long)ptr3) + (num3 * 8)) + 4));
43                 sizeArray1[num3] = System.Convert.ToInt32(num5);
44             }
45             Marshal.FreeCoTaskMem(ptr1);
46             Marshal.FreeCoTaskMem(ptr2);
47             Marshal.FreeCoTaskMem(ptr3);
48             return sizeArray1;
49         }
50 
51         private static int FastDeviceCapabilities(short capability, IntPtr pointerToBuffer, int defaultValue, string printerName)
52         {
53             int num1 = DeviceCapabilities(printerName, OutputPort, capability, pointerToBuffer, IntPtr.Zero);
54             if (num1 == -1)
55             {
56                 return defaultValue;
57             }
58             return num1;
59         }
60     }
61 }

 

  这样,就可以完整的获取用户自定义的纸张了。

  下一节,会为大家分享如何使用子报表。

posted @ 2012-10-30 17:24  Mark Rao  阅读(488)  评论(1编辑  收藏  举报