您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)B/S打印方案以及代碼控制IE打印設(shè)置是怎樣的,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
B/S打印方案
最初解決WEB打印的出發(fā)點很簡單,即把生成的客戶端HTML按程式代碼所定義的格式打印出來。如自定義頁首尾,報表首尾,頁邊距,紙張,等等。其實這也是在WEB應(yīng)用上最最常用的打印需求,當(dāng)然,這不會很專業(yè),但是可以解決一般的應(yīng)用管理系統(tǒng)需求。通過不斷的調(diào)試以及性能分析比較,大致總結(jié)了各個打印解決方案的優(yōu)劣,以備參考: 一、利用IE內(nèi)部打印組件: 這個方案也許是最簡單的,當(dāng)然不會很“專業(yè)”。我們假設(shè)客戶端是IE6.0版本,因為在IE6.0中才完全體現(xiàn)我們所要應(yīng)用的“打印模板機制”。它在精確控制頁面邊界,文本間隔,以及打印的統(tǒng)一性上,功能更為完備。 至于這種方案的實現(xiàn)也相當(dāng)簡單,它主要只涉及到DEVICERECT,LAYOUTRECT兩種行為方式,分別用來定義整體頁面風(fēng)格及單個頁面內(nèi)容風(fēng)格。而我們所要打印的HTML可以通過LAYOUTRECT的CONTENTSRC屬性來指定??上驳氖羌词刮覀冇?000個頁面要打印,也可以簡單的通過我們的打印模板添加動態(tài)修建HTML功能,實現(xiàn)單模板控制多文件風(fēng)格。(請參考本文所附代碼)。這個方案在有詳細(xì)的介紹,但沒有附示例。示例文件可以在MSDN上下載得到。二、利用外部DLL打印組件: 此類方案實現(xiàn)倒也不很復(fù)雜,只是利用DLL本身內(nèi)部類函數(shù)操作,創(chuàng)建報表、格式并進(jìn)行打印,而無需考慮內(nèi)部實現(xiàn)環(huán)節(jié)。但對于WEB打印來說,似乎不合適。我個人認(rèn)為在WEB上創(chuàng)建報表的HTML,然后利用客戶端IE打印是最好的解決方式。而如果你的C?;騐B不是很好,那么外部DLL的類型解決是一個很讓人頭疼的事情,何況還要應(yīng)用到WEB環(huán)境下。這種方案我用傻兒的打印組件調(diào)試過,但沒成功。 三、利用外部OCX類控件 這類方案和第二種差不多,也是建立在別人的成果的基礎(chǔ)上,但是在ASP.net下,如果沒有這個控件的說明書,我相信你也會和我一樣,不知道該從哪里下手開始設(shè)計。 四、利用XML解析打印 這種解決方案在微軟家園有很詳細(xì)的介紹,其原理就是解析出定義好的XML格式標(biāo)記,解讀出文件中標(biāo)記的參數(shù)定義,最后將這些信息還原成打印機輸出的圖形格式。很簡單的理解,例如你要打印一個簡單的表格,那么我們將表格解析成為文本和表格兩部分,程式設(shè)計時我們遇到文本文本則輸出文本到打印機,遇到表格標(biāo)簽即輸出LINE到打印機。如此你可以自定義一些特殊的標(biāo)簽,如圖片,特殊形狀等。這種方案開發(fā)起來很簡單,而且很“專業(yè)”,不過其缺點:客戶端需要安裝.NET FrameWork.(傻了。。) 五、轉(zhuǎn)化為PDF文件,利用PDF打印 轉(zhuǎn)化為其它類型的文件輸出,是打印方案很常用的一種方式,而PDF文件格式以其優(yōu)異的“品質(zhì)”(打印品質(zhì))和“性能”(應(yīng)用功能)無疑是一種很經(jīng)濟(jì)的方式。而且從WEB向PDF轉(zhuǎn)換不是很困難,資源占用也不是很嚴(yán)重,這是它在同類方案中的優(yōu)點,也是異類方案中的缺點。如此你可以去PDFCHINA上搜尋相關(guān)可用信息。 六、利用外部設(shè)計器設(shè)計報表,內(nèi)部程式碼控制打印 這里我針對思路來講這種方案,并針對VISUAL DESIGNER報表組件。我們預(yù)先得利用設(shè)計器做好報表的格式,爾后在程式碼里面住報表各表單“套值”,就這么簡單。有點像ACCESS里面的報表設(shè)計方式。我所在公司的管理系統(tǒng)就是ACCESS寫的,所以我其實挺喜歡這種方案。至于VISUAL DESIGNER可以在下載到,并有開發(fā)說明書。 七、自己寫專業(yè)報表打印組件 這是*不得已的作法,當(dāng)然更符合自己的要求,但是如果你不是專業(yè)的開發(fā)人員或有其它特殊目的,這些時間就不要花了。很羅索的。如果你有興趣寫,那么我建議你先看看第五種方案的思路和說明文檔。 WEB打印至今還沒有完美的解決方案,我個人期待IE在這一方面再加改進(jìn),以方便我們這一群“勞苦大眾”。
代碼控制IE打印設(shè)置
網(wǎng)頁打印,可以通過瀏覽器的"打印"功能實現(xiàn),但"打印模板"機制,卻是 IE 5.5 /6.0 以及 Netscape 6.0 所獨有的;準(zhǔn)確一點, IE 5.5 只是一個機制雛形,在 IE 6.0 中才得以完全體現(xiàn)。IE 6.0 的打印功能模塊,在精確控制頁面邊界,文本間隔,以及打印的統(tǒng)一性上,功能更為完備。
通過創(chuàng)建打印模板,你可以精確控制:
網(wǎng)頁打印及預(yù)覽時的頁面風(fēng)格與內(nèi)容編排風(fēng)格;
打印屬性,如自動為打印的頁面添加卷標(biāo)或編號;
精確控制打印預(yù)覽界面的各個元素與變量。
通過打印模板,你可以:
自動為所有打印頁面添加固定內(nèi)容,如公司標(biāo)識,版權(quán)申明,或者指定廣告;
自定義頁面標(biāo)頭與尾注等元素,比如頁碼或卷標(biāo);
指定打印歷史與任務(wù);
書本化奇偶分頁映射打印......
打印模板機制是建立在動態(tài) HTML 語言基礎(chǔ)上的,涉及到主要兩個行為:DeviceRect, LayoutRect ,下面我們就這兩個行為深入地探討 IE 6.0 的打印機制。
另外需要說明的是,DHTML (動態(tài)超文本標(biāo)識語言)的行為跟其他語言的"行為"一樣,都是一種應(yīng)用編程接口,初始狀態(tài)下有自己的默認(rèn)屬性,在一定的事件下,由用戶決定調(diào)用其承認(rèn)的功能模塊,從而產(chǎn)生相對應(yīng)的"行為"。而且,"行為"可以自己編寫,不過得以".htc"為其擴展名以供調(diào)用。
一.DeviceRect ,定義打印總體風(fēng)格:
打印總體風(fēng)格,包括為打印頁面添加如公司標(biāo)識的固定內(nèi)容(網(wǎng)頁上不一定有,只體現(xiàn)在打印紙張上或預(yù)覽頁面上,后同);打印頁面的顏色風(fēng)格;打印頁面的邊緣屬性或圖案;等等。
在進(jìn)行 DeviceRect 引用前,先得確定頁面風(fēng)格,方法是用<Style>進(jìn)行設(shè)置。
例一:我們來定制如下的打印模板
8.5 inch 寬
11 inch 高
黃色背景
1 pixel 寬的黑色實心左邊界
1 pixel 寬的黑色實心上邊界
4 pixels 寬的黑色實心右邊界
4 pixels 寬的黑色實心下邊界
所有邊界與紙張邊緣為 10 pixels 的距離
現(xiàn)在我們用 Style 進(jìn)行設(shè)定,假設(shè)這個 Style 名為 Mystyle1:
<STYLE TYPE="text/css">
.Mystyle1
{
width:8.5in;
height:11in;
background:#FFFF99;
border-left:1 solid black;
border-top:1 solid black;
border-right:4 solid black;
border-bottom:4 solid black;
margin:10px;
}
</STYLE>
下面我們給出 DeviceRect 引用的完全頁面代碼,
<HTML XMLNS:IE>
<HEAD>
<?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default">
<STYLE TYPE="text/css">
.Mystyle1
{
width:8.5in;
height:11in;
background:#FFFF99;
border-left:1 solid black;
border-top:1 solid black;
border-right:4 solid black;
border-bottom:4 solid black;
margin:10px;
}
</STYLE>
</HEAD>
<BODY>
<IE:DEVICERECT ID="page1" CLASS="Mystyle1" MEDIA="print">
</IE:DEVICERECT>
<IE:DEVICERECT ID="page2" CLASS="Mystyle1" MEDIA="print">
</IE:DEVICERECT>
</BODY>
</HTML>
在這個頁面中,共進(jìn)行了兩個 DeviceRect 引用。作為一種規(guī)則,每一個單獨的打印頁面,必須有一個相對應(yīng)的 DeviceRect 標(biāo)記,如果有 1000 個頁面,那就得有 1000 個 DeviceRect 標(biāo)記!嚇住了?別擔(dān)心,后面我們會教你一個方法,讓所有的 DeviceRect 標(biāo)記自動完成!
在上面的代碼中,ID 是標(biāo)志屬性,不同的頁面必須有自己不同的標(biāo)識;CLASS 引用了 Style 屬性;MEDIA 屬性則指明了本頁面的最終用途是進(jìn)行打印;<?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default">這句話則是指輸入默認(rèn)的行為,它們分別是 DeviceRect, LayoutRect。
二.LayoutRect ,定義頁面內(nèi)容風(fēng)格:
跟 DeviceRect 一樣,不同的頁面,要進(jìn)行 LayoutRect 引用時都需要添加 LayoutRect 標(biāo)記,其智能添加方法將在后面介紹; LayoutRect 與 DeviceRect 如果在同一個頁面中同時出現(xiàn),則前者需放在后者之內(nèi);另外, LayoutRect 對內(nèi)容風(fēng)格的設(shè)定,也通過 Style 得以實現(xiàn)。
例二:我們來定制如下的內(nèi)容風(fēng)格的打印模板:
5.5 inches 寬
8 inches 高
與打印紙張邊緣,四邊保持 1 inch 的寬度(加上頁面本身的邊緣寬度,為實際的打印邊緣寬度)
白色背景
1 inch 寬的虛線邊界
先定制名為 contentstyle 的風(fēng)格:
<STYLE TYPE="text/css">
.contentstyle
{
width:5.5in;
height:8in;
margin:1in;
background:white;
border:1 dashed gray;
}
</STYLE>
然后下面是進(jìn)行引用的完整網(wǎng)頁代碼:
<HTML>
<HEAD>
<?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default">
<STYLE TYPE="text/css">
.contentstyle
{
width:5.5in;
height:8in;
margin:1in;
background:white;
border:1 dashed gray;
}
</STYLE>
</HEAD>
<BODY>
<IE:LAYOUTRECT ID="layoutrect1" CONTENTSRC="2.html" CLASS="contentstyle" NEXTRECT="layoutrect2"/>
<IE:LAYOUTRECT ID="layoutrect2" CLASS="contentstyle"/>
</BODY>
</HTML>
跟例一中的源代碼相比,例二中只是以 LayoutRect 代替了原來的 DeviceRect 標(biāo)記;DeviceRect 定制的是模板整體風(fēng)格,而 LayoutRect 定制的是具體內(nèi)容的版面風(fēng)格;LayoutRect 的 ID 屬性也具有唯一性; CONTENTSRC 屬性則指明了具體的將起作用網(wǎng)頁文件;CLASS 指明了風(fēng)格的引用對象;跟 DeviceRect 不同,在進(jìn)行 LayoutRect 引用時,必須在每個頁面指定 NEXTREC ,即依次排列的下一個內(nèi)容風(fēng)格,這里的"下一個內(nèi)容"用其頁面的相應(yīng) ID 進(jìn)行標(biāo)識,如本例中的 LayoutRect2 。
三.DeviceRect 與 LayoutRect 的協(xié)同作戰(zhàn):
上面我們分別討論了 DeviceRect 與 LayoutRect 的作用與引用方法,現(xiàn)在我們來看一下,如何在同一個打印模板中進(jìn)行定制與引用。
在每一個打印模板上,必然包含兩方面的內(nèi)容,一個是整體的模板風(fēng)格(DeviceRect),另一個是內(nèi)容風(fēng)格(LayoutRect);第一個打印頁面跟其他頁面是不同的,因為第一個頁面中必須指明 CONTENTSRC 屬性,而同一打印任務(wù)中的其他頁面不再需要進(jìn)行 CONTENTSRC 的指定。
例三:
下面是第一個頁面中的 DeviceRect 代碼:
<IE:DEVICERECT ID="page1" CLASS="masterstyle" MEDIA="print">
<IE:LAYOUTRECT ID="layoutrect1" CONTENTSRC="2.html" CLASS="contentstyle" NEXTRECT="layoutrect2"/>
</IE:DEVICERECT>
下面是其他頁面中的 DeviceRect 代碼:
<IE:DEVICERECT ID="page2" CLASS="masterstyle" MEDIA="print">
<IE:LAYOUTRECT ID="layoutrect2" CLASS="contentstyle"/>
</IE:DEVICERECT>
下面我們將 DeviceRect 與 LayoutRect 結(jié)合起來使用,其源代碼如下:
<HTML XMLNS:IE>
<HEAD>
<?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default">
<STYLE TYPE="text/css">
.contentstyle
{
width:5.5in;
height:8in;
margin:1in;
background:white;
border:1 dashed gray;
}
.Mystyle1
{
width:8.5in;
height:11in;
background:#FFFF99;
border-left:1 solid black;
border-top:1 solid black;
border-right:4 solid black;
border-bottom:4 solid black;
margin:10px;
}
</STYLE>
</HEAD>
<BODY>
<IE:DEVICERECT ID="page1" CLASS="Mystyle1" MEDIA="print">
<IE:LAYOUTRECT ID="layoutrect1" CONTENTSRC="2.html" CLASS="contentstyle" NEXTRECT="layoutrect2"/>
</IE:DEVICERECT>
<IE:DEVICERECT ID="page2" CLASS="Mystyle1" MEDIA="print">
<IE:LAYOUTRECT ID="layoutrect2" CLASS="contentstyle"/>
</IE:DEVICERECT>
</BODY>
</HTML>
四.DeviceRect 與 LayoutRect 標(biāo)記的動態(tài)自動添加:
前面我們說到,每個單獨的打印頁面都需要各自的 DeviceRect 與 LayoutRect 標(biāo)記,那么,如果我們有 1000 個頁面需要打印,是否就要在每個頁面上重復(fù)繁瑣的 Copy & Paste 操作?
答案是否定的,我們完全可以通過 JavaScript 腳本來完成這一繁瑣的工作。
要實現(xiàn) HTML 聲明的動態(tài)創(chuàng)建,關(guān)鍵在于 <DIV> 標(biāo)記的定義,下面是其定義規(guī)則。
<DIV ID="devicecontainer">
......
</DIV>
<DIV>與</DIV>之間,采用 insertAdjacentHTML() 方式,并主要利用了其 afterBegin 與 BeforeEnd 兩個變量,現(xiàn)在我們將第一個頁面"插入"到<DIV></DIV>之間:
devicecontainer.insertAdjacentHTML("afterBegin", newHTML);
具有繼承屬性的后續(xù)頁面,調(diào)用 beforeEnd 變量:
devicecontainer.insertAdjacentHTML("beforeEnd", newHTML);
要裝載 devicecontainer 頁面,還需在 <Body>中添加:
<BODY ONLOAD="addFirstPage()">
現(xiàn)在我們在 JavaScript 中添加包含前面詳細(xì)介紹的 LayoutRect 與 DeviceRect 元素,用到的命令是 addFirstPage() 。需要注意的是,newHTML 標(biāo)記后使用的是雙引號,而 LayoutRect 與 DeviceRect 標(biāo)記后的變量使用單引號。如下:
function addFirstPage() {
newHTML = "<IE:DEVICERECT ID='devicerect1' MEDIA='print' CLASS='mystyle1'>";
newHTML += "<IE:LAYOUTRECT ID='layoutrect1' CONTENTSRC='2.html'" + "ONLAYOUTCOMPLETE='onPageComplete()' NEXTRECT='layoutrect2'" + "CLASS='contentstyle'/>";
newHTML += "</IE:DEVICERECT>";
devicecontainer.insertAdjacentHTML("afterBegin", newHTML);
}
細(xì)心的讀者一定會發(fā)現(xiàn),LayoutRect 后出現(xiàn)了一個新的屬性:LayoutRect:onLayoutComplete ,這個屬性主要指定了 LayoutRect 停止響應(yīng)的后續(xù)事件,如系統(tǒng)資源消耗殆盡而停止響應(yīng),或者 LayoutRect 指定的變量溢出。
好了,有了上面的原理,下面我們來編寫具有自動"插入"功能的 JavaScript 代碼:
function onPageComplete() {
if (event.contentOverflow) {
newHTML = "<IE:DEVICERECT ID='devicerect" + (lastPage + 1) + "' MEDIA='print' CLASS='mystyle1'>";
newHTML += "<IE:LAYOUTRECT ID='layoutrect" + (lastPage + 1) + "' ONLAYOUTCOMPLETE='onPageComplete()' NEXTRECT='layoutrect" + (lastPage + 2) + "' CLASS='contentstyle'/>";
newHTML += "</IE:DEVICERECT>";
devicecontainer.insertAdjacentHTML("beforeEnd", newHTML);
lastPage++;
}
在上面的代碼中,contentOverflow 代表的是由于頁面信息過長,本頁的 LayoutRect 停止響應(yīng),則直接跳到下一個頁面,讓 LayoutRect 重新定義下一個頁面的版面;onPageComplete() 則不管頁面是否過長,LayoutRect 是否停止響應(yīng),只要到了頁面尾部則自動跳到下一頁,這也是最常見的情況。
在編寫本腳本時,關(guān)鍵處在于保持清醒,不能讓任意一個變量出錯。其中,ID 不僅針對 DeviceRect 與 LayoutRect ,還為 NextRect 所引用,頁面指向不能出錯;當(dāng)前頁面的頁碼應(yīng)該是 lastPage+1 ,下一個頁面的頁碼應(yīng)該是 lastPage+2 ;NextRect 標(biāo)記需要下一個頁面的 LayoutRect 屬性支持,因此它的值應(yīng)該為 "layoutRect"+(lastPage+2);打開第一個頁面時,這個 LastPage 初始值為 1 。
上述就是小編為大家分享的B/S打印方案以及代碼控制IE打印設(shè)置是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。