1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用RSClientPrint直接打印本地RDLC报表

使用RSClientPrint直接打印本地RDLC报表

时间:2021-10-14 09:30:22

相关推荐

使用RSClientPrint直接打印本地RDLC报表

最近一个项目使用ReportViewer来呈现本地RDLC模块的报表,需要用户点击至少三次才能直正打印,用户感觉易用性很不好,需要我们修改。

经过网上查找相关资料,发现直接使用ACTIVEX控件RSClientPrint直接打印使用SQLSERVER报表服务的资料很多,也说的比较详细,可唯独没打印本地报表的相关内容,看来只能自已摸索了。

经过研究有关打印SQLSERVER报表服务的资料,特别是这篇文章:/KB/reporting-services/RsClientPrint.aspx,决下先写一个简单的HTML文 件测试一下:

代码 <!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="/1999/xhtml">

<head>

<title></title>

</head>

<BODYonload="Print()">

<OBJECTID="RSClientPrint"

classid="CLSID:5554DCB0-700B-498D-9B58-4E40E5814405"CODEBASE="/RSClientPrint-x86.cab"VIEWASTEXT></OBJECT>

<scripttype="text/javascript"language="javascript">

functionPrint(oid,name){

if(typeofRSClientPrint.Print=="undefined"){

alert("Unabletoloadclientprintcontrol.");

return;

}

RSClientPrint.MarginLeft=0;

RSClientPrint.MarginTop=0;

RSClientPrint.MarginRight=0;

RSClientPrint.MarginBottom=0;

RSClientPrint.PageHeight=296.926;

RSClientPrint.PageWidth=210.058;

RSClientPrint.Culture=2052;

RSClientPrint.UICulture=2052;

RSClientPrint.UseSingleRequest=true;

RSClientPrint.UseEmfPlus=true;

RSClientPrint.Print("http://localhost:2940/JDCJY/ReportHandler.ashx","oid="+escape(oid)+"&name="+escape(name),"test");

}

</script>

</BODY>

</html>

然后实现ReportHandler.ashx

代码publicclassReportHandler:IHttpHandler

{

publicvoidProcessRequest(HttpContextcontext)

{

Warning[]warningArray;

HttpResponseresponse=context.Response;

response.StatusCode=200;

MemoryStreamlastMemoryStream=null;

context.Response.BufferOutput=false;

context.Response.ContentType=null;

context.Response.Expires=-1;

vards=newDataSet();

LocalReportlocalReport=newLocalReport();

localReport.ReportEmbeddedResource=string.Format("{0}.rdlc",context.Request.QueryString["name"]);

localReport.DataSources.Add(newMicrosoft.Reporting.WebForms.ReportDataSource("ds",ds));

StringBuilderbuilder=newStringBuilder("<DeviceInfo>");

NameValueCollectionrequestParameters=context.Request.QueryString;

for(inti=0;i<requestParameters.Count;i++)

{

if(requestParameters.Keys[i]!=null)

{

if(requestParameters.Keys[i].StartsWith("rc:",StringComparison.OrdinalIgnoreCase))

{

builder.AppendFormat("<{0}>{1}</{0}>",XmlConvert.EncodeName(requestParameters.Keys[i].Substring(3)),HttpUtility.HtmlEncode(requestParameters[i]));

}

}

}

builder.Append("</DeviceInfo>");

localReport.Render("IMAGE",builder.ToString(),delegate(stringname,stringextension,Encodingencoding,stringmimeType,boolwillSeek)

{

if(!HttpContext.Current.Response.IsClientConnected)

{

thrownewHttpException("Clientdisconnected");

}

if(lastMemoryStream!=null)

{

this.SendPrintStream(lastMemoryStream,response);

lastMemoryStream.Dispose();

lastMemoryStream=null;

}

lastMemoryStream=newMemoryStream();

returnlastMemoryStream;

},outwarningArray);

this.SendPrintStream(lastMemoryStream,response);

lastMemoryStream.Dispose();

this.SendPrintStream(null,response);

if(!response.BufferOutput)

{

stringa=context.Request.ServerVariables["SERVER_PROTOCOL"];

if(string.Equals(a,"HTTP/1.0",StringComparison.OrdinalIgnoreCase))

{

context.Response.Close();

}

}

}

privatevoidSendPrintStream(Streamstream,HttpResponseresponse)

{

intlength=0;

if(stream!=null)

{

length=(int)stream.Length;

}

foreach(bytenum2inBitConverter.GetBytes(length))

{

response.OutputStream.WriteByte(num2);

}

if(stream!=null)

{

stream.Position=0L;

StreamToResponse(stream,response);

response.Flush();

}

}

internalstaticvoidStreamToResponse(Streamdata,HttpResponseresponse)

{

intcount=0;

byte[]buffer=newbyte[0x14000];

while((count=data.Read(buffer,0,0x14000))>0)

{

response.OutputStream.Write(buffer,0,count);

}

}

publicboolIsReusable

{

get

{

returntrue;

}

}

}

再后经测试,直接加载上面的HTML页面就会提示直接打印。整个过程花了不少时间,有几个地方需要注意:

1.在服务器端生成DEVICEINFO时一定要使用上面所示的方法,我在测试过程中为了图简单,直接使用我原来在WINFORM写的一个代码,固定的DEVICEINFO信息,结果打印出来时始终会重复,不知道是怎么回事,经过使用Reflector反编译Microsoft.ReportViewer.WebForms,仔细这里面实现的报表相关服务,发现这点实现的区别,才最终搞定问题

2.服务器代码生成EMF流如果有问题,客户端会报一个错误代码,这时你很可能会以为是客户端的错误,我开始就是,因为报错误的速度太快了。我上网对对应问题代码的资料也没有明确结果,最后看还是直接跟踪代码试试,发现是服务器端代码有些问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。