水晶报表

因为水晶报表的PaperSize是enum类型,但有时客户用的纸张不在其定义范围内,虽然在设计报表时可以选择目的打印机和纸型,但如果重新配置过该 打印机则报表默认纸型不再有效,报表将按A4进行预览且会失真。

//获取本机所有打印机将其名称填充到comboBoxPrinters中:包含本地和网络打印机

foreach ( string printer in System . Drawing . Printing . PrinterSettings . InstalledPrinters)
{
    this . comboBoxPrinters. Items. Add( printer) ;
}


//当从comboBoxPrinters中选择打印机时获取其支持的纸张大小将其填充到listBoxPapers

this . listBoxPapers. Items. Clear( ) ;
string printer = this . comboBoxPrinters. Text ;
this . m_printer = printer;
Microsoft . Win32 . RegistryKey rk;
if ( ! this . comboBoxPrinters. Text . StartsWith( @ "//" ) )         
//本地打印机

     rk = Microsoft . Win32 . Registry . LocalMachine. OpenSubKey( "SOFTWARE//Microsoft//Windows NT//CurrentVersion//Print//Printers//" + this . comboBoxPrinters. Text + "//DsDriver" ) ;
else                                 
//网络打印机

{
                
    string [ ] p = printer. Remove( 0, 2) . Split( new char [ ] { '//' } ) ;
    string path = "SOFTWARE//Microsoft//Windows NT//CurrentVersion//Print//Providers//LanMan Print Services//Servers//" + p[ 0] + "//Printers//" + p[ 1] + "//DsDriver" ;
     rk = Microsoft . Win32 . Registry . LocalMachine. OpenSubKey( path ) ;
}

string [ ] papers = ( string [ ] ) ( rk. GetValue( "printMediaSupported" ) ) ;
for ( int i= 0; i< papers. Length; i+ + )
{
    this . listBoxPapers. Items. Add( papers[ i] ) ;
}

//根据纸张名称获取其所在本地机上的PaperSize:调用的是PaperSizeGetter.Get_PaperSizes静态方法 (是从水晶报表中reflect精简出来的,版权归原作者所有)

    public class PaperSizeGetter
    {
        public static string OutputPort = String . Empty;

        [ DllImport( "winspool.drv" , CharSet = CharSet . Auto, SetLastError= true ) ]
        public static extern int DeviceCapabilities( string pDevice, string pPort, short fwCapabilities, IntPtr pOutput, IntPtr pDevMode) ;

        public static int [ ] Get_PaperSizes( string printer)
        {
            string text1 = printer;
            int num1 = FastDeviceCapabilities( 0x10, IntPtr . Zero, - 1, text1) ;
            if ( num1 = = - 1)
            {
                return new int [ 0] ;
            }
            int num2 = Marshal . SystemDefaultCharSize * 0x40;
            IntPtr ptr1 = Marshal . AllocCoTaskMem( num2 * num1) ;
             FastDeviceCapabilities( 0x10, ptr1, - 1, text1) ;
            IntPtr ptr2 = Marshal . AllocCoTaskMem( 2 * num1) ;
             FastDeviceCapabilities( 2, ptr2, - 1, text1) ;
            IntPtr ptr3 = Marshal . AllocCoTaskMem( 8 * num1) ;
             FastDeviceCapabilities( 3, ptr3, - 1, text1) ;
            int [ ] sizeArray1 = new int [ num1] ;
            for ( int num3 = 0; num3 < num1; num3+ + )
            {
                string text2 = Marshal . PtrToStringAuto( ( IntPtr ) ( ( ( long ) ptr1) + ( num2 * num3) ) , 0x40) ;
                int num4 = text2. IndexOf( '/0' ) ;
                if ( num4 > - 1)
                {
                     text2 = text2. Substring( 0, num4) ;
                }
                short num5 = Marshal . ReadInt16( ( IntPtr ) ( ( ( long ) ptr2) + ( num3 * 2) ) ) ;
                int num6 = Marshal . ReadInt32( ( IntPtr ) ( ( ( long ) ptr3) + ( num3 * 8) ) ) ;
                int num7 = Marshal . ReadInt32( ( IntPtr ) ( ( ( ( long ) ptr3) + ( num3 * 8) ) + 4) ) ;
                 sizeArray1[ num3] = System . Convert . ToInt32( num5) ;
            }
            Marshal . FreeCoTaskMem( ptr1) ;
            Marshal . FreeCoTaskMem( ptr2) ;
            Marshal . FreeCoTaskMem( ptr3) ;
            return sizeArray1;
        }

        private static int FastDeviceCapabilities( short capability, IntPtr pointerToBuffer, int defaultValue, string printerName)
        {
            int num1 = DeviceCapabilities( printerName, OutputPort, capability, pointerToBuffer, IntPtr . Zero) ;
            if ( num1 = = - 1)
            {
                return defaultValue;
            }
            return num1;
        }
    }

//根据纸型名称在其名称列表中的索引,获取该索引在调用Get_PaperSizes后的size数组中的对应值

int [ ] sizes = PaperSizeGetter. Get_PaperSizes( printerName) ;
int paperSizeid = sizes[ this . listBoxPapers. SelectedIndex] ;

//将该size赋值给报表对象

report. PrintOptions. PaperSize = ( CrystalDecisions. Shared. PaperSize ) ( paperSizeid)
;



本地机的每种纸型在每个支持的打印机上都对应了个id值,不同的配置顺序,不同的客户机相同纸型名称对都会导致不同的id,怎么获取这个id是关键,例如 本机的
Letter      1
Tabloid     3
Legal       5
A3           8
A4          9
A5          11
B4          119
B5          120
11x17       121
25x25       122 //自定义
PostScript 自定义页面大小 32767

从打印机服务器属性中删除25x25,增加26x26,再增加25x25
Letter      1
Tabloid     3
Legal       5
A3          8
A4          9
A5          11
B4           119
B5          120
11x17       121
26x26      122 //自定义
25x25      123 //自定义
PostScript 自定义页面大小 32767

通过reflect水晶报表的PaperSize属性得知水晶报表通过这个id来设置其纸张大小,所以才想出这么个笨方法暂时解决了客户的要求。
Get_PaperSizes方法,以及这个id真实涵义自己还没弄懂,还请高人指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值