摘要:打印是很多Web應(yīng)用系統(tǒng)不可或缺的功能,而且是一項(xiàng)比較復(fù)雜的技術(shù),針對(duì)ASP.NET中的Web打印問題提出了五種解決方法,并指出每種方法的優(yōu)缺點(diǎn),在開發(fā)過程中可以根據(jù)用戶的需求作相應(yīng)選擇。
關(guān)鍵詞:打印;ASP.NET;Web應(yīng)用系統(tǒng);水晶報(bào)表
中圖分類號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)11-2pppp-0c
Research on the ASP.NET-based Web Printing Technology
WU Guan-fu
(Dongguan Science Technology School,Dongguan 523106,China)
Abstract:Printing is an important and complex technology of Web application system. The article bring forwards five methods on how to solve the problem which may arise during the ASP.NET-based Web printing, and points out the advantage and disadvantage of each methods, which can be selected by different customers based on their own requirement in the process of developing.
Key words:Printing;ASP.NET;Web application system;Crystal Report
打印是很多Web應(yīng)用系統(tǒng)必不可少的功能,也是開發(fā)人員所面臨的一個(gè)共同難題。相對(duì)于Windows桌面應(yīng)用程序來講,Web應(yīng)用程序的打印有種種限制,技術(shù)人員在項(xiàng)目開發(fā)過程中經(jīng)常會(huì)遇到用戶這樣或那樣的需求。在開發(fā)基于ASP.NET的Web應(yīng)用系統(tǒng)時(shí),由于只能采用瀏覽器作為用戶界面進(jìn)行交互,所以不能精確地控制客戶端的打印機(jī)。因此,針對(duì)如何在客戶端實(shí)現(xiàn)ASP.NET下的Web打印這一問題,本文提出五種解決方法:
(1)利用IE直接實(shí)現(xiàn)Web打印;
(2)利用.NET組件實(shí)現(xiàn)Web打印;
(3)利用第三方控件實(shí)現(xiàn)Web打印;
(4)導(dǎo)出到Excel中實(shí)現(xiàn)Web打印;
(5)利用水晶報(bào)表實(shí)現(xiàn)Web打印
1 利用IE直接實(shí)現(xiàn)Web打印
1.1 調(diào)用window.print()方法實(shí)現(xiàn)打印
在頁(yè)面上添加“打印”按鈕,然后增加如下代碼:
這段代碼很簡(jiǎn)單,是通過Javascript腳本語言調(diào)用window.print()方法來實(shí)現(xiàn)打印。但是,如果采用這種方式來打印頁(yè)面,頁(yè)面上不需要的對(duì)象也會(huì)被打印處理。為了不打印某個(gè)對(duì)象,可以通過在樣式表CSS中設(shè)置打印或顯示樣式來隱藏這些對(duì)象,代碼如下:
該樣式表將media的屬性設(shè)置為print來控制打印輸出樣式,如果在“打印”按鈕的屬性中加上class=\"Noprn\",這樣按鈕就不會(huì)被打印出來。
1.2 調(diào)用IE內(nèi)置的WebBrowser控件實(shí)現(xiàn)打印
使用Window.Print()有一個(gè)不足之處,就是不能進(jìn)行打印預(yù)覽和頁(yè)面設(shè)置。使用WebBrowser控件可以很方便的解決這個(gè)問題。WebBrowser是IE內(nèi)置的瀏覽器控件,無需用戶下載,可以通過調(diào)用WebBrowser控件的ExecWB方法實(shí)現(xiàn)打印,加入ID為WebBrowser1的WebBrowser控件,代碼如下:
定義對(duì)象以后,可以使用這個(gè)對(duì)象完成打印設(shè)置、預(yù)覽及打印功能,代碼如下:
function doPageSet()
{//打印設(shè)置
WebBrowser1.ExecWB(8,1)
}
function doPagePreview()
{//打印預(yù)覽
WebBrowser1.ExecWB(7,1)}
function doPagePrint()
{//打印
WebBrowser1.ExecWB(6,1)}
調(diào)用上面的Javascript函數(shù)可以實(shí)現(xiàn)打印設(shè)置、打印預(yù)覽和打印功能。客戶端獨(dú)立完成打印目標(biāo)文檔的生成,減輕了服務(wù)器端的負(fù)荷。
2 利用.NET組件實(shí)現(xiàn)Web打印
如果要求精確控制打印效果,并且出于安全性考慮,不能直接連接數(shù)據(jù)庫(kù)時(shí),可以采用.NET編寫的受控組件實(shí)現(xiàn)Web打印,該方式在.NET Common Language Runtime的控制之下運(yùn)行,不需要進(jìn)行客戶端注冊(cè),比ActiveX安全性高,代碼編寫方便,直接支持XML技術(shù),具有很強(qiáng)的打印控制功能并且與IE兼容性高。其原理是通過XML強(qiáng)大的自定義功能,自定義出所有需要的格式控制標(biāo)簽,在服務(wù)器端進(jìn)行動(dòng)態(tài)編碼后通過Web服務(wù)器傳到客戶端,然后在客戶端進(jìn)行格式解析,根據(jù)服務(wù)器端定義的打印格式從客戶端直接控制打印機(jī)實(shí)現(xiàn)Web打印。
由于不允許直接連接到數(shù)據(jù)庫(kù),因此,只能采用XML文件進(jìn)行中間數(shù)據(jù)交換格式。.NET內(nèi)部已經(jīng)集成了XML解析器,直接就可以通過使用.NET類庫(kù)調(diào)用。既可以做成桌面應(yīng)用程序形式,通過遠(yuǎn)程調(diào)用;也可以嵌入到IE瀏覽器中,直接在網(wǎng)頁(yè)中運(yùn)行。
使用XSL(擴(kuò)展樣式表語言)將XML轉(zhuǎn)換成其他的文本格式,XSL轉(zhuǎn)換包括發(fā)現(xiàn)或者選擇一個(gè)模式匹配,通過使用XPath選擇一個(gè)結(jié)果集,然后對(duì)結(jié)果集中的每一項(xiàng),為這些匹配定義結(jié)果輸出。XSL是一個(gè)功能強(qiáng)大的工具,可以把XML轉(zhuǎn)換成任何想要的格式。代碼如下:
//創(chuàng)建新的XslTransform對(duì)象
XslTransform xslt=new XslTransform();
//從XSL文件中導(dǎo)入樣式表
xslt.Load(Server.MapPath(\"WorkersToHTML.xsl\"));
//創(chuàng)建新的XPathDocument對(duì)象,并導(dǎo)入XML文件
XPathDocument XDoc = new XPathDocument(Server.MapPath(\"Workers.XML\"));
//創(chuàng)建新的XmlTextWriter對(duì)象用于導(dǎo)出HTML格式文件
XmlWriter writer = new XmlTextWriter(Server.MapPath(\"Workers.html\"), System.Text.Encoding.UTF8);
//進(jìn)行實(shí)際的XSLT轉(zhuǎn)換操作
xslt.Transform(XDoc, 1, writer);
//操作完成后關(guān)閉XmlTextWriter對(duì)象
writer.Close();
采用服務(wù)器腳本動(dòng)態(tài)生成XML文檔時(shí),發(fā)送內(nèi)容類型應(yīng)該設(shè)置為text/xml(普通html頁(yè)面為text/html),字符編碼應(yīng)該為UTF-8,否則會(huì)出現(xiàn)編碼錯(cuò)誤問題。這種打印方式適合于格式變化大,數(shù)據(jù)量小的應(yīng)用,但是客戶端需要安裝.NET Framework組件,對(duì)于數(shù)據(jù)量大的XML文件,解析速度不是很理想,頁(yè)面首次加載時(shí)會(huì)有明顯的延時(shí)。
3 利用第三方控件實(shí)現(xiàn)Web打印
采用第三方控件是開發(fā)Web應(yīng)用系統(tǒng)比較好的選擇,由于第三方控件的易操作性,可以讓程序員完全從繁雜的打印編程中解放出來,在較短的時(shí)間內(nèi)做出做秀的報(bào)表打印系統(tǒng),進(jìn)一步提高開發(fā)效率。但第三方控件一般不是免費(fèi)的,下面以ScriptX.cab控件為例。
下載ScriptX.cab控件,修改codebase的值,默認(rèn)下面的設(shè)置也可以,加載控件代碼如下:
使用控件代碼如下:
function PrintSet()
{
factory.printing.SetMarginMeasure(2)
factory.SetPageRange(1,l,3)//設(shè)置指定打印的頁(yè)面
factory.printing.printer=\"HP DeskJet 870C\"
factory.printing.copies=2
factory.printing.collate=true
factory.printing.papersize=\"A4\"
factory.printing.paperSource=\"Manual feed\"
factory.printing.header=\"This is MeadCo\"
factory.printing.footer=\"Advanced Printing by ScriptX\"
factory.printing.portrait=1
factory.printing.leftMargin=1.0
factory.printing.topMargin=1.0
factory.printing.rightMargin=1.0
factory.printing.bottomMargin=l.0
factory.printing.Print(1)//直接打印
factory.Printing.PageSetup()//打印設(shè)置
factory.printing.Preview()//打印預(yù)覽
}
4 導(dǎo)出到Excel中實(shí)現(xiàn)Web打印
這種方式將Web打印問題轉(zhuǎn)化成數(shù)據(jù)導(dǎo)出問題,開發(fā)過程簡(jiǎn)單易行。導(dǎo)出到Excel有兩種方法可以實(shí)現(xiàn):一種通過瀏覽器直接導(dǎo)出;另外一種通過COM接口來實(shí)現(xiàn)。本文采用第一種方式,這種方式不僅靈活,而且代碼也很容易實(shí)現(xiàn),具體代碼如下:
Response.ContentType=\"application/vnd.ms-excel\";
Response.AddHeader(\"Content-Disposition\",\"inline,filename=\"+HttpUtility.UrlEncode(labTitle.Text+\".xls\",Encoding.UTF8));
//AddHeader方法用指定的值添加HTML標(biāo)題
StringBuilder MyBuilder=new StringBuilder();
StringWriter MyWriter=new StringWriter(MyBuilder);
HtmlTextWriter MyHtml = new HtmlTextWriter(MyWriter);
MyBuilder.Append(\"
\");dtgSanitation.RenderControl(MyHtml);
MyBuilder.Append(\"\");
Response.Write(MyBuilder.ToString());
Response.End();
該方式需要注意兩個(gè)問題:第一,導(dǎo)出DataGrid時(shí),其各列應(yīng)該為數(shù)據(jù)綁定列,按鈕列導(dǎo)出時(shí)會(huì)出現(xiàn)不需要的結(jié)果,如果有類似于按鈕列等非數(shù)據(jù)綁定列,應(yīng)該在DataGrid對(duì)象的RenderControl之前,將它隱藏再導(dǎo)出。第二,DataGrid存在分頁(yè)問題,因?yàn)镽enderControl方法只處理當(dāng)前頁(yè)的數(shù)據(jù),所以在此方法之前,應(yīng)去掉DataGrid分頁(yè),將數(shù)據(jù)放到一頁(yè)內(nèi)再導(dǎo)出。
導(dǎo)出到Excel后用戶可以自定義打印的內(nèi)容和格式,具有良好的靈活性,適應(yīng)性和控制性。但是此方法有一個(gè)限制
就是要保證安裝有Excel軟件,在客戶端使用時(shí)要求客戶端在IE的安全設(shè)置上有一定的要求。
5 利用水晶報(bào)表實(shí)現(xiàn)Web打印
利用水晶報(bào)表來處理打印問題,其優(yōu)點(diǎn)是打印非常靈活、方便;打印的內(nèi)容豐富多彩;有強(qiáng)大的內(nèi)容創(chuàng)建、集成功能和高效的報(bào)表技術(shù)。其取得數(shù)據(jù)有兩種方法來實(shí)現(xiàn)。
(1)Pull模式,即被請(qǐng)求時(shí),水晶報(bào)表直接工具指定的驅(qū)動(dòng)連接數(shù)據(jù)庫(kù),然后組裝這些數(shù)據(jù)。
(2)Push模式,此時(shí)開發(fā)人員必須自己編寫代碼連接數(shù)據(jù)并組裝到DataSet,同時(shí)將它傳送到報(bào)表。在Push模式下,通過使用連接共享,以及限制記錄集合的大小,可以使報(bào)表性能最大化,所以我們使用Push模式來解決問題,其主要步驟為:
①添加數(shù)據(jù)集文件,創(chuàng)建相應(yīng)的數(shù)據(jù)集表(即創(chuàng)建一個(gè)類型化數(shù)據(jù)集)。
②使用水晶報(bào)表專家生成報(bào)表。
③添加報(bào)表查看器控件,設(shè)置好控件的屬性。
④編寫相關(guān)代碼。
實(shí)現(xiàn)代碼如下:// 聲明一個(gè)報(bào)表對(duì)象
Reports ReportDoc=new Reports();
SqlConnection MyConn;
private void Page_Load(object sender,System.EventArgs e)
{ string strProvider=\"Server=(local);DataBase=test;UID=sa;PWD=\";
MyConn=new SqlConnection(strProvider);
}
//點(diǎn)擊查看按鈕,得到動(dòng)態(tài)統(tǒng)計(jì)圖
private void IgbFind_Click(object sender,System.Web.UI.ImageClickEventArgs e)
{//調(diào)用SQL存儲(chǔ)過程
string strSel = \"sp_StatDeptWeekSani'\"+DdlContext.SelectedValue+\"','\"+DdlYear.SelmtedValue+\"'\";
SqlDataAdapter MyAdapter=new SqlDataAdapter(strSel,MyConn);
DataSet dsl=new DataSet();
MyAdapter.Fill(dsl,\"tblTongji\");
ReportDoc.SetDataSource(dsl);
Crv.ReportSource= ReportDoc; //報(bào)表查看器對(duì)象Crv顯示該報(bào)表
}
//點(diǎn)擊打印按鈕,打印出該統(tǒng)計(jì)圖
private void IgbPrint_Click(object sender,System.Web.UI.ImageClickEventArgs e)
{//設(shè)置打印頁(yè)邊距
PageMargins MyMargins=ReportDoc.Printoptions.PageMargins;
MyMargins.bottomMargin = 250;
MyMargins.leftMargin = 350;
MyMargins.rightMargin = 350;
MyMargins.topMargin = 450;
ReportDoc.Printoptions.ApplyPageMargins(MyMargins);
ReportDoc.Printoptions.PrinterName = @\"HPLaserJet 4000 Series PS\";
ReportDoc.PrintToPrinter(1,1,0,0); //參數(shù)設(shè)置為0表示打印所有頁(yè)。
}
水晶報(bào)表有很多優(yōu)點(diǎn),適合于開發(fā)大型的報(bào)表系統(tǒng),使用這種方式進(jìn)行打印非常靈活,但是也存在客戶端需要安
裝和部署不方便的缺點(diǎn)。在.NET 2003框架中,由于水晶報(bào)表屬于第三方控件,需要注冊(cè)才能夠使用。
6 結(jié)束語
基于ASP.NET的Web打印問題是我們?cè)陂_發(fā)Web應(yīng)用系統(tǒng)所面臨的實(shí)際問題,具體采用何種方式進(jìn)行Web打印,這涉及到方案的適用性問題。一方面是由打印內(nèi)容、打印方式和其它用戶打印需求決定;另一方面還要考慮系統(tǒng)的實(shí)際運(yùn)行效率和系統(tǒng)的安全性。為了進(jìn)一步提高系統(tǒng)的安全性,可以直接采用SSL安全套接字等已經(jīng)成熟的WEB加密技術(shù)。
參考文獻(xiàn):
[1]唐偉.ASP.NET環(huán)境下查詢式Web動(dòng)態(tài)報(bào)表的實(shí)現(xiàn)[J].計(jì)算機(jī)與現(xiàn)代化,2006(9):123-126.
[2]徐海賢.ASP.NET之Web打印初探[J].信息技術(shù),2006(1):95-117.
[3]Visual Studio Magazine2002-2003中文精華合集[M].北京:電子工業(yè)出版杜,2OO4.
[4]Mickey Williams.Visual c#.NET技術(shù)內(nèi)幕[M].北京:清華大學(xué)出版社,2004.
收稿日期:2008-01-26
作者簡(jiǎn)介:吳觀福(1975-),男,華中科技大學(xué)碩士研究生,東莞理工學(xué)校講師,軟件設(shè)計(jì)師,研究方向:數(shù)據(jù)庫(kù)技術(shù)、軟件開發(fā)技術(shù)。