asp 与 database (3)
5.4? XML技術(shù)報表打印方案
隨著Internet的迅速發(fā)展和廣泛普及,XML的出現(xiàn)體現(xiàn)出了它的適用性和重要性。XML是由W3C定義的一種標(biāo)記語言,由于XML是沒有版權(quán)限制的,這樣用戶可以建立屬于自己的一套軟件而無須支付任何費(fèi)用。利用ASP結(jié)合XML技術(shù),可以實(shí)現(xiàn)對XML數(shù)據(jù)的報表打印操作。其原理是:通過XML強(qiáng)大的自定義功能,用戶可以很方便地自定義出所需要的數(shù)據(jù)結(jié)構(gòu),然后在服務(wù)器端進(jìn)行動態(tài)編碼,通過Web服務(wù)器將數(shù)據(jù)發(fā)送到客戶端,在客戶端進(jìn)行格式解析后,再根據(jù)服務(wù)器端定義的打印格式,從客戶端直接控制打印機(jī)打印出所需要的報表。
5.4.1? 打印XML數(shù)據(jù)報表
XML的出現(xiàn)推動了Web的發(fā)展。在XML文檔中用戶可以自己定義標(biāo)記,從而明確表達(dá)出數(shù)據(jù)之間的結(jié)構(gòu)關(guān)系。在一些數(shù)據(jù)量不是很大的情況下,可以使用XML文檔作為存儲數(shù)據(jù)的容器,因?yàn)橄鄬τ谠L問數(shù)據(jù)庫而言,訪問XML文檔的速度比較快。在ASP應(yīng)用程序中,可以訪問XML文檔中的數(shù)據(jù),從而將其顯示到頁面中進(jìn)行打印操作。
1.方案分析
XML具有靈活的語法和擴(kuò)展性,極大地強(qiáng)化了保存數(shù)據(jù)和處理數(shù)據(jù)的能力。
XML文檔中的標(biāo)記是由用戶自己定義的,瀏覽器是不能識別的,這就使得XML文檔的數(shù)據(jù)和顯示格式是分離的。在ASP中,通過DOM技術(shù)可以訪問XML文檔中的數(shù)據(jù),然后將其內(nèi)容顯示到ASP頁面中,再應(yīng)用打印技術(shù)打印此XML數(shù)據(jù)報表。
打印XML數(shù)據(jù)報表的流程圖,如圖5.28所示。
圖5.28? 打印XML數(shù)據(jù)報表流程圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"5"5.4"5.4.1
XML在處理數(shù)據(jù)的方面應(yīng)用很廣泛,在ASP中通過使用Microsoft XML類庫,可以訪問和操控XML文檔中的數(shù)據(jù),從而實(shí)現(xiàn)對數(shù)據(jù)的有效操作。下面以網(wǎng)上企業(yè)辦公自動化管理系統(tǒng)為例,介紹如何將存儲在XML文檔中的員工工資信息讀取到ASP頁面并進(jìn)行打印操作。運(yùn)行效果如圖5.29所示。
圖5.29? 打印XML數(shù)據(jù)報表
在運(yùn)行本例程之前,需要建立有效的XML文檔,代碼如下:
例程5-16? 代碼位置:光盤"mr"5"5.4"5.4.1"payfor.xml
<?xml version="1.0" encoding="gb2312"?>
<Records>
?? <Record>
?? ??? <num>001</num>
?????? <Name>楊麗麗</Name>
?????? <age>31</age>
?????? <department>研發(fā)部</department>
?????? <payfor>5500</payfor>
?????? <other>1000</other>
?? </Record>
?? <Record>
?? ??? <num>002</num>
?????? <Name>劉圓圓</Name>
?????? <age>28</age>
?????? <department>銷售部</department>
?????? <payfor>4600</payfor>
?????? <other>592</other>
?? </Record>
?? <Record>
?? ??? <num>003</num>
?????? <Name>李方方</Name>
?????? <age>25</age>
?????? <department>廣告部</department>
?????? <payfor>4050</payfor>
?????? <other>976</other>
?? </Record>
?? <Record>
?? ??? <num>004</num>
?????? <Name>李明明</Name>
?????? <age>29</age>
?????? <department>采購部</department>
?????? <payfor>4650</payfor>
?????? <other>1050</other>
?? </Record>
</Records>
在員工工資查看程序處理頁面中,首先創(chuàng)建Document對象實(shí)例,然后設(shè)置該對象的async屬性值為false(即不允許異步下載),并調(diào)用Document對象的Load方法加載指定的XML文檔,再調(diào)用Document對象的getElementsByTagName方法以及childNodes屬性讀取XML文檔中的數(shù)據(jù)。代碼如下:
例程5-17? 代碼位置:光盤"mr"5"5.4"5.4.1"index.asp
<%
?? Set xmlDoc=Server.CreateObject("Microsoft.XMLDOM")
?? Set xml_Record=Server.CreateObject("Microsoft.XMLDOM")
?? Set xml_child=Server.CreateObject("Microsoft.XMLDOM")
?? xmlDoc.async=False
?? xmlDoc.Load(Server.MapPath("payfor.xml"))
?? If xmlDoc.parseError.errorCode <> 0 Then
?? ? Response.Write("<tr><td colspan='6'>出現(xiàn)異常錯誤!</td></tr>")??? ?
?? Else
調(diào)用Document對象的getElementsByTagName方法返回指定名稱的元素集合,使用集合的length屬性獲取到元素的總數(shù),再應(yīng)用for…to循環(huán)語句讀取元素中各節(jié)點(diǎn)的內(nèi)容。
?? ? Set xml_Record=xmlDoc.getElementsByTagName("Record")
?? ? record_num=xml_Record.length
?? ? For i=0 to (record_num-1)
?? ? Set xml_child=xml_Record.item(i)
? %>
<tr>
? <td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=xml_child.childNodes(0).text%></td>
? <td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=xml_child.childNodes(1).text%></td>
? <td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=xml_child.childNodes(2).text%></td>
? <td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=xml_child.childNodes(3).text%></td>
? <td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=xml_child.childNodes(4).text%></td>
? <td align="center" valign="middle" bgcolor="#FFFFFF"><%=xml_child.childNodes(5).text%></td>
</tr>
<%Next
? End If
%>
將XML文檔中的數(shù)據(jù)信息顯示到ASP頁面后,就可以應(yīng)用WebBrowse組件對頁面中的報表信息進(jìn)行打印操作了。代碼如下:
例程5-18? 代碼位置:光盤"mr"5"5.4"5.4.1"index.asp
<style type="text/css">
@media print{
.Noprint{display:none /*應(yīng)用該樣式的對象在實(shí)際打印時將不可見*/
}
</style>
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"></object>
<a href="#" οnclick="document.all.WebBrowser.Execwb(8,1)" class="Noprint">頁面屬性</a> <a href="#" οnclick="document.all.WebBrowser.Execwb(7,1)" class="Noprint">打印預(yù)覽</a> <a href="#" οnclick="document.all.WebBrowser.Execwb(6,1)" class="Noprint">打印</a>
?? 注意:在打印時,通過頁面設(shè)置可以設(shè)置打印時的邊距。
3.補(bǔ)充說明
在實(shí)際應(yīng)用中,有時需要將數(shù)據(jù)庫中的數(shù)據(jù)導(dǎo)出到XML文檔中,再進(jìn)行下一步的操作(如打印XML數(shù)據(jù)庫報表、查詢XML數(shù)據(jù)等)。
通過創(chuàng)建XML文檔對象,并設(shè)置對象的相關(guān)屬性和調(diào)用相關(guān)方法,可以實(shí)現(xiàn)將數(shù)據(jù)庫中的數(shù)據(jù)寫入到指定XML文檔的功能,代碼如下:
<%
If Not Isempty(Request("sure")) Then
'將數(shù)據(jù)庫中的數(shù)據(jù)寫入到XML文檔中
Set rs = Server.CreateObject("ADODB.RecordSet")
sqlstr = "SELECT * FROM tb_user"???
rs.Open sqlstr,conn,1,1
If rs.Eof Then
? Response.Write("<script language='javascript'>alert('數(shù)據(jù)庫中暫無記錄,請?zhí)砑佑涗浐笤賴L試運(yùn)行本程序!');window.location.href='index.asp';</script>")
? Response.End()
Else???????
? Dim objXMLDOM, objRootNode, objNode
? Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument") '創(chuàng)建XML文檔對象
? Set objRootNode = objXMLDOM.createElement("xml") '創(chuàng)建根節(jié)點(diǎn)??
? objXMLDOM.documentElement = objRootNode
? Do While Not rs.Eof??????
?? ??? Set objRowNode = objXMLDOM.createElement("row") '創(chuàng)建父節(jié)點(diǎn)
?? ??? Set objNode = objXMLDOM.createElement("UserName") '創(chuàng)建子節(jié)點(diǎn)
?? ??? objNode.text = rs("UserName")
?? ??? objRowNode.appendChild(objNode)
?? ??? Set objNode = objXMLDOM.createElement("UserPassword") '創(chuàng)建子節(jié)點(diǎn)
?? ??? objNode.text = rs("Upwd")???????????
?? ??? objRowNode.appendChild(objNode)?????????????????
?? ??? Set objNode = objXMLDOM.createElement("UserTel")???? '創(chuàng)建子節(jié)點(diǎn)??????
?? ??? objNode.text = rs("Utel")???????????
?? ??? objRowNode.appendChild(objNode)?????????????????
?? ??? objRootNode.appendChild(objRowNode)???????
?? ??? rs.MoveNext
? loop????????????????
objXMLDOM.Save Server.MapPath("MyXMLDoc.xml")
Response.Write("<script language='javascript'>alert('將數(shù)據(jù)庫中的數(shù)據(jù)成功寫入到XML文檔中!');window.location.href='index.asp';</script>")
? Set objNode = Nothing????????????
? Set objRowNode = Nothing????????
? Set objRootNode = Nothing????
End If???
rs.Close???
Set rs = Nothing
End If
%>
5.4.2? 分頁報表打印
在一般情況下,顯示數(shù)據(jù)的頁面都會提供分頁程序,以方便用戶查看數(shù)據(jù)信息。在ASP應(yīng)用程序中,可以使用JavaScript腳本語言來操作XML文檔中存儲的數(shù)據(jù),并將信息進(jìn)行分頁顯示。
1.方案分析
在使用XML文檔作為存儲數(shù)據(jù)的容器時,根據(jù)實(shí)際情況,對顯示的數(shù)據(jù)可以進(jìn)行分頁控制。應(yīng)用JavaScript腳本語言可以創(chuàng)建XML的Document對象,并使用Document對象的相關(guān)屬性和方法,讀取XML文檔中各節(jié)點(diǎn)包含的數(shù)據(jù),同時還可以對數(shù)據(jù)進(jìn)行分頁控制,然后在ASP頁面中通過CSS樣式來規(guī)范讀取到的XML數(shù)據(jù)的顯示格式,最后應(yīng)用打印技術(shù)按照顯示的分頁效果打印XML數(shù)據(jù)報表。
分頁報表打印的流程圖,如圖5.30所示。
圖5.30? 分頁報表打印的流程圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"5"5.4"5.4.2
使用JavaScript腳本語言可以操縱XML文檔中的數(shù)據(jù),并可以將獲取到的數(shù)據(jù)進(jìn)行分頁處理。在ASP頁面中,應(yīng)用CSS樣式可以定義XML數(shù)據(jù)的顯示格式。下面以校園管理系統(tǒng)的檔案管理模塊為例,介紹應(yīng)用JavaScript腳本語言將讀取到的XML數(shù)據(jù)進(jìn)行分頁顯示,并對顯示在頁面中XML數(shù)據(jù)報表進(jìn)行打印。運(yùn)行效果如圖5.31所示。
圖5.31? 分頁報表打印
在運(yùn)行本例程之前,需要建立有效的XML文檔,代碼如下:
例程5-19 代碼位置:光盤"mr"5"5.4"5.4.2"resume.xml
<?xml version="1.0" encoding="gb2312"?>
<Persons>
?? <Person>
?????? <Name>張三</Name>
?????? <Sex>男</Sex>
?????? <Grand>本科</Grand>
?????? <Tel>139565580</Tel>
?????? <Email>1@1.com</Email>
?????? <Like>計算機(jī)、英語</Like>
?? </Person>
?? <Person>
?????? <Name>李四</Name>
?????? <Sex>男</Sex>
?????? <Grand>本科</Grand>
?????? <Tel>133884580</Tel>
?????? <Email>2@1.com</Email>
?????? <Like>計算機(jī)、運(yùn)動</Like>
?? </Person>
?? <Person>
?????? <Name>王元元</Name>
?????? <Sex>女</Sex>
?????? <Grand>專科</Grand>
?????? <Tel>135899680</Tel>
?????? <Email>3@1.com</Email>
?????? <Like>日語、英語</Like>
?? </Person>
?? <Person>
?????? <Name>趙明明</Name>
?????? <Sex>女</Sex>
?????? <Grand>本科</Grand>
?????? <Tel>139258880</Tel>
?????? <Email>4@1.com</Email>
?????? <Like>繪畫、英語</Like>
?? </Person>
</Persons>
在檔案信息列表查看頁面中,用戶可以通過單擊“前一頁”或“后一頁”超鏈接,進(jìn)行分頁查看信息的操作,也可以通過選擇下拉列表框中的頁碼來分頁查看數(shù)據(jù)信息。在此頁面中,提供了“直接打印”、“頁面屬性”、“打印預(yù)覽”和“打印”4個關(guān)于打印技術(shù)的超鏈接,用戶可以根據(jù)實(shí)際需要進(jìn)行相應(yīng)的操作。
在程序處理頁面編寫的JavaScript腳本中,首先創(chuàng)建XML的Document對象實(shí)例,調(diào)用對象的load方法加載指定的XML文檔;然后獲取XML文檔中指定元素的個數(shù),以及元素中包含節(jié)點(diǎn)的數(shù)目,根據(jù)所設(shè)置的初始值,計算顯示的頁碼總數(shù);再定義執(zhí)行翻頁操作的相關(guān)函數(shù),并在定義的顯示XML文檔內(nèi)容的函數(shù)中包含顯示分頁狀態(tài)的函數(shù);最后調(diào)用顯示XML文檔內(nèi)容的函數(shù),實(shí)現(xiàn)分頁顯示XML數(shù)據(jù)報表的功能。代碼如下:
例程5-20 代碼位置:光盤"mr"5"5.4"5.4.2"index.asp
<script language="javascript">
var pagenum=2; //每頁顯示的記錄數(shù)
var page=0;?
var BodyHTML="";
var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
var mode="Person";
創(chuàng)建Document對象實(shí)例后,加載指定的XML文檔。
xmlDoc.async=false;
xmlDoc.load("resume.xml");
header="<table align='center' width='500' cellspaceing='1' cellpadding='2' border='1' bgcolor='#FFFFEE'><caption>職工檔案登記表</caption><tr align='center' class='title' bgcolor='#C1E6DB'><td>姓名</td><td>性別</td><td>學(xué)歷</td><td>電話</td><td>Email</td><td>愛好</td></tr>";
獲取XML文檔中的記錄條數(shù),以及記錄包含的字段數(shù),并計算顯示的總頁碼數(shù)。
recordNum=xmlDoc.getElementsByTagName(mode).length;
column=xmlDoc.getElementsByTagName(mode).item(0).childNodes;
colNum=column.length;
//計算總頁數(shù)
pagesNumber=Math.ceil(recordNum/pagenum)-1;
自定義顯示“前一頁”超鏈接的函數(shù)。
function Up_Page(page)
{
thePage="<font class='input'>前一頁</font>"
if(page+1 > 1) thePage="<a class='input' href='#' οnclick='JavaScript:return UpPageGo()'>前一頁</a>";
return thePage;
}
function UpPageGo()
{
if(page > 0) page--;
showContent();
BodyHTML="";
}
自定義顯示“后一頁”超鏈接的函數(shù)。
function Next_Page(page)
{
thePage="<font class='input'>后一頁</font>"
if(page < pagesNumber) thePage="<a class='input' href='#' οnclick='JavaScript:return NextPageGo()'>后一頁</a>";
return thePage;
}
function NextPageGo()
{
if(page < pagesNumber) page++;
showContent();
BodyTex="";
}
自定義顯示當(dāng)前頁碼的函數(shù)。
function currentPage()//顯示當(dāng)前頁碼
{
var str;
str="<font class='input'>當(dāng)前是第"+(page+1)+"頁</font>";
return str;
}
自定義顯示總頁碼的函數(shù)。
function totalPage()//顯示總頁碼
{
var str;
str="<font class='input'>共有"+(pagesNumber+1)+"頁</font>";
return str;
}
自定義顯示“分頁狀態(tài)條”的函數(shù)。
function pageBar(page)//顯示分頁狀態(tài)條
{
var str;
str="<br><center class='Noprint'>"+Up_Page(page)+" "+Next_Page(page)+" "+currentPage()+" "+totalPage()+selectPage()+"</center>";
return str;
}
自定義自動轉(zhuǎn)換顯示頁的函數(shù)。
function changePage(tpage)
{
page=tpage;
if(page >= 0) page--;
if(page < pagesNumber) page++;
showContent();
BodyHTML="";
}
自定義具體顯示頁碼功能的下拉列表框函數(shù)。
function selectPage()
{
var sp;
sp="<select name='sel_page' onChange='javascript:changePage(this.options[this.selectedIndex].value)'>";
sp=sp+"<option value=''></option>";
for(t=0;t<=pagesNumber;t++)
{
? sp=sp+"<option value='"+t+"'>"+(t+1)+"</option>";
}
sp=sp+"</select>";
return sp;
}
自定義顯示XML文檔內(nèi)容的函數(shù)。
function showContent()//將XML中的數(shù)據(jù)顯示到頁面中
{
if(!page) page=0;
n=page*pagenum;
endNum=(page+1)*pagenum;
if(endNum > recordNum) endNum=recordNum;
BodyHTML=header+BodyHTML;
for(;n<endNum;n++)
{
? kn=n+1;
? BodyHTML=BodyHTML+"<tr>";
? for(mNum=0;mNum<=colNum-1;mNum++)
? {
??? mName=column.item(mNum).tagName;
?? BodyHTML=BodyHTML+("<td>"+xmlDoc.getElementsByTagName(mName).item(n).text+"</td>");
? }
? BodyHTML=BodyHTML+"</tr>";
}
document.all.showXML.innerHTML=BodyHTML+"</table>"+pageBar(page);
BodyHTML="";
}
調(diào)用自定義的showContent()函數(shù),將XML文檔中的數(shù)據(jù)信息顯示到頁面中指定的DIV標(biāo)記中。
if(recordNum==0)
{
? document.Write("沒有可以顯示的數(shù)據(jù)!");
}
else
{
? showContent();
}
</script>
將XML文檔中的內(nèi)容顯示到頁面后,可以調(diào)用WebBrowser組件對報表進(jìn)行打印,代碼如下:
例程5-21 代碼位置:光盤"mr"5"5.4"5.4.2"index.asp
<div id="showXML"></div>
<p class="Noprint">
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"></object>
<a href="#" onClick="document.all.WebBrowser.Execwb(6,6)">直接打印</a> <a href="#" onClick="document.all.WebBrowser.Execwb(8,1)">頁面屬性</a> <a href="#" onClick="document.all.WebBrowser.Execwb(7,1)">打印預(yù)覽</a> <a href="#" onClick="document.all.WebBrowser.Execwb(6,1)">打印</a>
</p>
在頁面中應(yīng)用的CSS樣式定義如下:
例程5-22 代碼位置:光盤"mr"5"5.4"5.4.2"Include"css.css
body,td{font-size:9pt}
A:link{color:#0000FF; text-decoration:none;}
A:visited{color:#0000FF; text-decoration:none;}
A:active{color:#3333ff; text-decoration:none;}
A:hover{color:#FF0000; text-decoration:none;}
td{font-size:9pt; line-height:150%}
.title{font-size:10.8pt; font-weight:bold}
.alert{font-size:9pt; color:#990000; font-weight:bold}
.input{font-size:9pt}
3.補(bǔ)充說明
除了使用JavaScript腳本語言對XML文檔中的數(shù)據(jù)進(jìn)行分頁操作,在ASP中也可以將XML數(shù)據(jù)分頁顯示到網(wǎng)頁中。具體實(shí)現(xiàn)步驟如下:
(1)創(chuàng)建一個XML的FreeThreadedXMLDOM對象,并加載指定的XML文檔,然后選取相關(guān)節(jié)點(diǎn),代碼如下:
<%
Set newXML=Server.CreateObject("Microsoft.FreeThreadedXMLDOM")
newXML.load(server. mappath("content.xml"))
Set newobj=newXML.documentElement.selectSingleNode("newxml")
%>
(2)通過以下代碼實(shí)現(xiàn)對XML數(shù)據(jù)進(jìn)行分頁顯示,代碼如下:
<%
PageSize =5
'設(shè)置每頁顯示5條留言信息
newNum =newobj.childNodes.length-1
PageN=newNum"PageSize+1
'算出總頁數(shù)
PNo=request.querystring("PageNo")
if PNo="" then
'確定每一頁顯示最新的留言
PNo=PageN
end if
Ends=PNo*PageSize-1
'獲得起始節(jié)點(diǎn)
Strs=(PNo-1)*PageSize
'獲得結(jié)束節(jié)點(diǎn)
if Strs<0 then
Strs=0
end if
if Ends>newNum then
Strs=Strs-(Ends-newNum)
Ends=newNum
end if
if Strs<0 then
Strs=0
end if
while Strs<=Ends
'從結(jié)束節(jié)點(diǎn)到起始節(jié)點(diǎn)之間讀取節(jié)點(diǎn)數(shù)據(jù)
title=newobj.childNodes.item(Strs).childNodes.item(0).text
content = newobj.childNodes.item(Strs).childNodes.item(1).text
'取得留言內(nèi)容
content = replace(content,chr(13),"<br>")
'應(yīng)用replace函數(shù)替代回車符
content = replace(content,chr(32)," ")
'應(yīng)用replace函數(shù)替代空格符
%>
<tr>
<td ><div align="center" class="STYLE2"><%=title%></div></td>
<td class="STYLE2"><div align="center"><%=content%></div></td>
</tr>
<%
Strs=Strs+1
wend
set newXML=nothing
%> ?
</table><br>共有<<%=PageN%>>頁
<%
'分頁
if cint(PNo)<>1 then
response.write "<a href='index.asp?PageNo="&(PNo-1)&"'>上一頁</a> "
end if
if cint(PNo)<>PageN then???????
response.write "<a href='index.asp?PageNo="&(PNo+1)&"'>下一頁</a>"
end if
%>
5.4.3? XSL瀏覽報表打印
XSL語言可以用于轉(zhuǎn)換XML文檔,也可以格式化XML文檔。應(yīng)用XSL語言可以定義XML文檔的顯示格式,即將XML文檔轉(zhuǎn)換成能被瀏覽器識別的HTML文件;應(yīng)用XSL語言還可以向輸出文件中添加新的元素、重新排列數(shù)據(jù)以及決定哪些元素顯示哪些元素不顯示等。
根據(jù)實(shí)際需要,可以通過XSL格式化XML文檔,并使數(shù)據(jù)信息以一定的格式顯示到ASP頁面中,然后對報表數(shù)據(jù)執(zhí)行打印操作。
1.方案分析
使用XSL語言可以靈活、快速地定義出XML文檔的顯示格式,使格式化后的XML文檔數(shù)據(jù)以清晰的結(jié)構(gòu)顯示在用戶面前。在ASP程序中,可以應(yīng)用XSL瀏覽XML數(shù)據(jù)報表,并進(jìn)行打印操作。
首先,用戶需要建立有效的.xml文件和.xsl文件,然后在ASP程序中創(chuàng)建XML的DOMDocument對象實(shí)例,應(yīng)用該對象的相關(guān)方法加載建立好的兩個文件,并應(yīng)用.xsl文件來格式化.xml文件,這樣XML文檔中的數(shù)據(jù)就能夠以.xsl文件規(guī)定的格式進(jìn)行顯示了,再應(yīng)用相關(guān)的打印技術(shù)打印顯示在ASP頁面中的數(shù)據(jù)報表。
XSL瀏覽報表打印的流程圖,如圖5.32所示。
圖5.32? XSL瀏覽報表打印流程圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"5"5.4"5.4.3
在實(shí)際應(yīng)用中,不僅可以通過CSS樣式來定義XML文檔的顯示格式,還可以應(yīng)用XSL語言來轉(zhuǎn)換或格式化XML文檔,使瀏覽器可以識別XML文檔中的數(shù)據(jù)結(jié)構(gòu),從而使數(shù)據(jù)以指定的格式顯示在頁面中。下面以企業(yè)績效管理系統(tǒng)的員工考勤模塊為例,介紹如何使用XSL格式化XML文檔,并將XML文檔中的數(shù)據(jù)以分頁的形式顯示在頁面中,然后打印顯示的報表。運(yùn)行效果如圖5.33所示。
圖5.33? XSL瀏覽報表打印
在運(yùn)行本例程之前,需要建立有效的XML文檔,代碼如下:
例程5-23? 代碼位置:光盤"mr"5"5.4"5.4.3"emp_work.xml
<?xml version="1.0" encoding="gb2312"?>
<Persons>
?? <Person>
?? ??? <num>001</num>
?????? <date>2007年9月</date>
?????? <Name>張三</Name>
?????? <department>研發(fā)部</department>
?????? <count>10</count>
?????? <day>1</day>
?? </Person>
?? <Person>
?? ??? <num>002</num>
?????? <date>2007年9月</date>
?????? <Name>李四</Name>
?????? <department>銷售部</department>
?????? <count>2</count>
?????? <day>0</day>
?? </Person>
下面定義了兩個<Person2>的標(biāo)記,作為分頁的標(biāo)識。
?? <Person2>
?? ??? <num>003</num>
?????? <date>2007年9月</date>
?????? <Name>楊林林</Name>
?????? <department>企劃部</department>
?????? <count>0</count>
?????? <day>2</day>
?? </Person2>
?? <Person2>
?? ??? <num>004</num>
?????? <date>2007年9月</date>
?????? <Name>孫圓圓</Name>
?????? <department>廣告部</department>
?????? <count>1</count>
?????? <day>0</day>
?? </Person2>
</Persons>
建立了有效的XML文檔后,為此XML文檔建立.xsl文件,在.xsl文件中使用表格來規(guī)定數(shù)據(jù)的顯示格式。代碼如下:
例程5-24? 代碼位置:光盤"mr"5"5.4"5.4.3"emp_work.xsl
<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/Persons">
首先在<p>標(biāo)記中建立表格,此表格的作用是使XML文檔中<Person>標(biāo)記內(nèi)的數(shù)據(jù)顯示在指定的單元格中。
<p><table align="center" width="500" cellpadding="2" cellspacing="1" border="0" bgcolor="#666600" class="table_style">
<caption align="center">員工考勤記錄表</caption>
? <tr align="center" class="title" bgcolor="#e5e5e5">
??? <td width="25"><xsl:text disable-output-escaping="yes"></xsl:text></td>
?? <td>序號</td>
?? <td>日期</td>
?? <td>姓名</td>
?? <td>所屬部門</td>
?? <td>早退遲到次數(shù)</td>
?? <td>缺席天數(shù)</td>
? </tr>
? <xsl:for-each select="Person">
? <tr bgcolor="#ffffff">
??? <td align="right"><xsl:value-of select="position()"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="num"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="date"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="Name"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="department"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="count"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="day"/></td>
? </tr>
? </xsl:for-each>
</table></p>
再次在<p>標(biāo)記中建立表格,此表格的作用是使XML文檔中<Person2>標(biāo)記內(nèi)的數(shù)據(jù)顯示在指定的單元格中。
<p><table align="center" width="500" cellpadding="2" cellspacing="1" border="0" bgcolor="#666600" class="table_style">
? <tr align="center" class="title" bgcolor="#e5e5e5">
??? <td width="25"><xsl:text disable-output-escaping="yes"></xsl:text></td>
?? <td>序號</td>
?? <td>日期</td>
?? <td>姓名</td>
?? <td>所屬部門</td>
?? <td>早退遲到次數(shù)</td>
?? <td>缺席天數(shù)</td>
? </tr>
? <xsl:for-each select="Person2">
? <tr bgcolor="#ffffff">
??? <td align="right"><xsl:value-of select="position()"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="num"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="date"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="Name"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="department"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="count"/></td>
?? <td style="color:#990000" align="center"><xsl:value-of select="day"/></td>
? </tr>
? </xsl:for-each>
</table></p>
</xsl:template>
</xsl:stylesheet>
建立了有效的.xml文件和.xsl文件后,自定義一個函數(shù),此函數(shù)的作用是創(chuàng)建XML的DOMDocument對象實(shí)例,應(yīng)用對象的load方法分別加載.xml文件和.xsl文件,然后調(diào)用DOMDocument對象的TransformNode方法使用.xsl文件格式化.xml文件。代碼如下:
例程5-25? 代碼位置:光盤"mr"5"5.4"5.4.3"Include"formatxml.asp
<%
Function FormatXML(XMLfile,XSLfile)
Dim objXML,objXSL
strXMLfile=Server.MapPath(XMLfile)
strXSLfile=Server.MapPath(XSLfile)
Set objXML=Server.CreateObject("MSXML2.DOMDocument")
Set objXSL=Server.CreateObject("MSXML2.DOMDocument")
objXML.async=false
If objXML.Load(strXMLfile) Then
? objXSL.async=false
? objXSL.ValidateonParse=false
? If objXSL.Load(strXSLfile) Then
??? On Error Resume Next
?? FormatXML=objXML.transformNode(objXSL)'很重要
?? If objXSL.parseError.errorCode <> 0 Then
?? ? Response.Write("<br><hr>")
?? ? Response.Write("Error Code: "&objXSL.parseError.errorCode)
?? ? Response.Write("<br>Error Reason: "&objXSL.parseError.reason)
?? ? Response.Write("<br>Error Line: "&objXSL.parseError.line)
?? ? FormatXML="<span class=""alert"">格式化XML文件錯誤!</span>"
?? End IF
? Else
?? ? Response.Write("<br><hr>")
?? ? Response.Write("Error Code: "&objXSL.parseError.errorCode)
?? ? Response.Write("<br>Error Reason: "&objXSL.parseError.reason)
?? ? Response.Write("<br>Error Line: "&objXSL.parseError.line)
?? ? FormatXML="<span class=""alert"">格式化XML文件錯誤!</span>"
? End If
Else
?? ? Response.Write("<br><hr>")
?? ? Response.Write("Error Code: "&objXSL.parseError.errorCode)
?? ? Response.Write("<br>Error Reason: "&objXSL.parseError.reason)
?? ? Response.Write("<br>Error Line: "&objXSL.parseError.line)
?? ? FormatXML="<span class=""alert"">格式化XML文件錯誤!</span>"
End If
Set objXML=Nothing
Set objXSL=Nothing
End Function
%>
做好前期準(zhǔn)備之后,在首頁面中包含Include文件夾中的formatxml.asp文件,調(diào)用自定義的FormatXML(XMLfile,XSLfile)函數(shù)顯示XML文檔中的數(shù)據(jù)信息,并引用WebBrowser組件打印頁面中的XML數(shù)據(jù)報表。代碼如下:
例程5-26? 代碼位置:光盤"mr"5"5.4"5.4.3"index.asp
<style media="print">
.Noprint{display:none;}
</style>
<!--#include file="Include/formatxml.asp"-->
<%=FormatXML("emp_work.xml","emp_work.xsl")%>
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0">
</object>
<p> <a href="#" οnclick="document.all.WebBrowser.Execwb(8,1)" class="Noprint">頁面屬性</a> <a href="#" οnclick="document.all.WebBrowser.Execwb(7,1)" class="Noprint">打印預(yù)覽</a> <a href="#" οnclick="document.all.WebBrowser.Execwb(6,1)" class="Noprint">打印</a> </div></p>
3.補(bǔ)充說明
除了調(diào)用XML對象的相關(guān)方法使用.xsl文件格式化.xml文件,還可以在XML文檔中直接鏈接指定的.xsl文件,從而實(shí)現(xiàn)轉(zhuǎn)換XML文檔格式的效果。代碼如下:
XSL樣式表文件xmlf.xsl。
<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
?? <html>
?? <body>
?? <center>
?? <table width="300" height="30" border="10" cellspacing="0" cellpadding="0">
?? ? <tr align="center">
?????? <td>書名</td>
?????? <td>頁碼</td>
?? ? </tr>
<xsl:for-each select="PUBLICATION/BOOK">
?? ? <tr align="center" height="30">
?????? <td><xsl:value-of select="TITLE"/></td>
?????? <td><xsl:value-of select="PAGES"/></td>
?? ? </tr>
</xsl:for-each>?????
?? </table>
?? </center>
?? </body>
?? </html>
</xsl:template>
</xsl:stylesheet>
XML文件index.xml。
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type="text/xsl" href="xmlf.xsl"?>
<PUBLICATION>
?? <BOOK>
?????? <TITLE>ASP技術(shù)</TITLE>
?????? <PAGES>760</PAGES>
?? </BOOK>
?? <BOOK>
?????? <TITLE>SQL技術(shù)</TITLE>
?????? <PAGES>520</PAGES>
?? </BOOK>
</PUBLICATION>
在XML文檔中如果鏈接了多個XSL樣式表,瀏覽器將使用第一個XSL樣式表而忽略其他XSL樣式表;如果同時鏈接一個CSS樣式表文件和一個XSL樣式表,瀏覽器將只使用XSL樣式表。
5.5? 其他報表打印方案
除了以上介紹的Excel報表打印方案、XML技術(shù)報表打印方案和Crystal Report水晶報表打印方案,在ASP程序中還可以應(yīng)用其他技術(shù)來實(shí)現(xiàn)報表打印的功能。本節(jié)將介紹Word報表打印、自定義ActiveX組件打印Access報表、圖形報表打印以及套打報表。
5.5.1? Word報表打印
Microsoft Word是微軟公司推出的Microsoft Office辦公軟件中的一個組件,它是一個功能強(qiáng)大的文字處理軟件,可以進(jìn)行文字輸入、編輯、排版和打印操作等。在ASP程序中,可以創(chuàng)建Word的相關(guān)對象將網(wǎng)頁中的內(nèi)容導(dǎo)入到Word中,也可以調(diào)用Word中的數(shù)據(jù)報表,然后進(jìn)行報表打印。
1.方案分析
在Web服務(wù)器上安裝了Microsoft Word軟件后,ASP就可以創(chuàng)建Word的相關(guān)對象,從而應(yīng)用該對象的屬性和方法對網(wǎng)頁中的數(shù)據(jù)或者Word文檔中的數(shù)據(jù)進(jìn)行操作了。
網(wǎng)頁上顯示的數(shù)據(jù)一般都是從數(shù)據(jù)庫中讀取出來的,創(chuàng)建Word的Application對象可以將網(wǎng)頁中具有一定顯示格式的數(shù)據(jù)導(dǎo)入到Word文檔中,然后進(jìn)行報表打印的操作。
在一些實(shí)際工作中,用戶可能會應(yīng)用Word文檔來存儲一些數(shù)據(jù)報表(如:制作商務(wù)表格等),并進(jìn)行排版工作等,為了方便用戶查看Word文檔中的內(nèi)容,ASP可以編寫動態(tài)代碼打開指定的Word文檔,然后再執(zhí)行打印命令。
Word報表打印的流程圖,如圖5.34所示。
圖5.34? Word報表打印的流程圖
2.實(shí)施過程
Microsoft Word在文字編輯、打印方面的應(yīng)用很廣泛,ASP通過調(diào)用Word的相關(guān)對象可以訪問Word文檔中的數(shù)據(jù)內(nèi)容。下面介紹兩種在ASP程序中通過Word進(jìn)行報表打印的方法,分別是將網(wǎng)頁內(nèi)容導(dǎo)入到Word和打印Word報表。
l????????? 方法一? 將網(wǎng)頁內(nèi)容導(dǎo)入到Word
? 實(shí)例位置:光盤"mr"5"5.5"5.5.1"01
在本章的5.2節(jié)中介紹了Excel報表打印方案,在ASP中不僅可以將網(wǎng)頁中的內(nèi)容保存到Excel中,還可以將網(wǎng)頁中指定的內(nèi)容導(dǎo)入到Word中。下面以企業(yè)內(nèi)部管理系統(tǒng)的庫存管理模塊為例,介紹將網(wǎng)頁中顯示的數(shù)據(jù)導(dǎo)入到Word,然后再進(jìn)行打印操作的過程。運(yùn)行結(jié)果如圖5.35所示。
圖5.35? 將網(wǎng)頁內(nèi)容導(dǎo)入到Word
在庫存商品信息查看頁面中,可以瀏覽到從庫存商品信息表中讀取到的數(shù)據(jù)信息。代碼如下:
例程5-27? 代碼位置:光盤"mr"5"5.5"5.5.1"01"index.asp
<%
??? Set rs=Server.CreateObject("ADODB.Recordset")
?? sqlstr="select * from tb_store"
?? rs.open sqlstr,conn,1,1
?? do while not rs.eof
%>
<tr align="center">
? <td height="26"><%=rs("Gname")%></td>
? <td height="26"><%=rs("Gunit")%></td>
? <td width="93" height="26"><%=rs("Gstd")%></td>
? <td width="167" height="26"> <%=rs("Gprovide")%></td>
? <td width="85" height="26"> <%=rs("Gconect")%></td>
</tr>
<%
??? rs.movenext
?? loop
?? rs.close
?? Set rs=Nothing
%>
<div align="center"><a href="vbscript:" onClick="vbscript:SaveDoc()">Word報表打印</a></div>
單擊頁面中的“Word報表打印”超鏈接,就可以將表格中的數(shù)據(jù)寫入到Word文檔中,同時生成的臨時Word文檔會自動打開。運(yùn)行效果如圖5.36所示。
圖5.36? 保存網(wǎng)頁內(nèi)容的Word文檔
在程序處理頁面的客戶端VBScript腳本中,自定義一個子過程用于將網(wǎng)頁中的表格數(shù)據(jù)寫入到Word文檔中。具體的實(shí)現(xiàn)步驟如下:
(1)創(chuàng)建一個Word的Application對象實(shí)例,再調(diào)用Word的Documents集合的Add方法建立一個新的文檔,并將頁面中的表格數(shù)據(jù)存儲在一個數(shù)組中。
(2)將表格的標(biāo)題寫入到Word中,并增添一個空行。
(3)在Word文檔中建立一個表格,并將數(shù)組中的內(nèi)容填寫在該表格中。
(4)保存新建立的Word文檔。
代碼如下:
例程5-28? 代碼位置:光盤"mr"5"5.5"5.5.1"01"index.asp
<script language="vbscript">
Sub SaveDoc
Dim Table1
Set table1=document.all.data
row=Table1.rows.length
set wdapp=CreateObject("Word.Application")? //創(chuàng)建Word應(yīng)用程序
wdapp.visible=true
set wddoc=wdapp.documents.add? //添加新的文檔
colnum =Table1.rows(1).cells.length
將頁面中表格的內(nèi)容存放在數(shù)組中。
reDim theArray(colnum,row)
For i=0 to row-1
?? For j=0 to colnum-1
?????? thearray(j+1,i+1)=table1.rows(i).cells(j).innerHTML
?? next
next
intNumrows=row
將表格的標(biāo)題信息寫入到Word文檔中,并設(shè)置其字體樣式。
wdapp.application.activedocument.paragraphs.add.range.insertbefore("庫存商品記錄表")
set rngpara=wdapp.application.activedocument.paragraphs.add.range
with rngpara
.paragraphformat.alignment=1
.font.name="arial"
.font.size=9
End with
Set rngPara=wdapp.Application.ActiveDocument.Paragraphs(1).Range
With rngPara
.Bold=True
.ParagraphFormat.Alignment=1
.Font.Name="Arial"
.Font.Size=12
End With
在文檔的指定段落的區(qū)域內(nèi),添加一表格,將數(shù)組中的數(shù)據(jù)寫入到表格中。
set rngcurrent=wdapp.application.activedocument.paragraphs(3).range
set tabCurent=wdapp.application.activedocument.tables.add(rngcurrent,intnumrows,colnum)
For i=1 To row
?? For j=1 to colnum??? ?????? wdapp.application.activeDocument.Tables(1).Rows(i).Cells(j).Range.InsertAfter theArray(j,i)? ?????? wdapp.application.activeDocument.Tables(1).Rows(i).Cells(j).Range.paragraphFormat.alignment=1
?? next
next
保存建立的Word文檔。
wdapp.application.activeDocument.SaveAs "NewDoc.doc",0,false,"",true,"",false,false,false,false,false
End sub
</script>
將網(wǎng)頁中的內(nèi)容導(dǎo)入到Word文檔后,用戶可以根據(jù)實(shí)際需要再對數(shù)據(jù)報表進(jìn)行編輯操作,然后打印報表。
l????????? 方法二? 打印Word報表
? 實(shí)例位置:光盤"mr"5"5.5"5.5.1"02
在ASP中不僅可以調(diào)用Word的相關(guān)對象將網(wǎng)頁中的內(nèi)容導(dǎo)入到Word,還可以打開Word文檔直接進(jìn)行打印操作。下面以企業(yè)營銷管理系統(tǒng)的銷售報表模塊為例,介紹如何打開指定的Word報表文件,并進(jìn)行打印操作。運(yùn)行效果如圖5.37所示。
圖5.37? 打印Word報表
在銷售報表查看和打印頁面中,首先選擇相關(guān)的Word文檔,然后單擊“Word報表打印”按鈕,這時選擇的Word文檔將自動打開,并處于打印的狀態(tài)中。
為了便于讀者理解,下面以列表的形式給出銷售報表查看頁面index.asp中所涉及到的表單及表單元素,如表5.8所示。
表5.8?????????? ??????銷售報表查看頁面index.asp中的表單及表單元素
| 名稱 | 元素類型 | 重要屬性 | 含義 |
| form | form | action="" method="post" enctype="multipart/form-data" | 選擇需要打印的Word文檔 |
| file1 | input | type="file" id="file1" size="20" | 確定Word文檔的路徑 |
| | input | type="submit" id="print" onClick="openWord(file1.value)" | Excel文件路徑 |
在頁面中單擊“Word報表打印”按鈕后的運(yùn)行效果如圖5.38所示。
圖5.38? 打開指定的Word文檔
在程序處理頁面中的客戶端VBScript腳本中,自定義一個子過程用于打開并打印指定的Word文檔。在該子過程中,首先創(chuàng)建Word的Application對象實(shí)例,再調(diào)用Documents集合的Open方法打開Word文檔,最后調(diào)用Printout方法打印Word文檔。代碼如下:
例程5-29? 代碼位置:光盤"mr"5"5.5"5.5.1"02"index.asp
<script language="vbscript">
Sub openWord(filename)?
Set wrd=CreateObject("word.Application")
wrd.visible=true
wrd.Documents.Open(filename)
wrd.Application.Printout()
wrd=null
End Sub
</script>
3.補(bǔ)充說明
Microsoft Word是常用的文字編輯工具,使用Word可以進(jìn)行記錄會議內(nèi)容、起草協(xié)議等工作。為了用戶操作方便,在ASP中可以調(diào)用Word直接打印頁面中的數(shù)據(jù)信息,即將用戶在表單中輸入的信息直接封裝到Word中,然后再進(jìn)行打印操作。如圖5.39所示。
圖5.39? 調(diào)用Word進(jìn)行Web打印
自定義一個VBScript腳本子過程,在該子過程中,首先獲取頁面中表單的數(shù)據(jù)信息,然后在客戶端VBScript腳本中創(chuàng)建Word的Document對象,應(yīng)用對象的相應(yīng)方法將頁面內(nèi)容裝入到Word文檔中,并直接進(jìn)行打印操作。代碼如下:
<script language="vbscript">
Sub word_print
Set objWordDoc=CreateObject("Word.Document")
title=document.all.form1.txt_title.value&CHR(10)
nowtime=document.all.form1.txt_time.value&CHR(10)
table=title&nowtime&document.all.form1.txt_content.value
objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore(table)
objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("")
Set rngPara=objworddoc.Application.ActiveDocument.Paragraphs(1).Range
objworddoc.Application.ActiveDocument.SaveAs "如何調(diào)用Word進(jìn)行Web打印"
objWordDoc.application.printout()
End Sub
</script>
5.5.2? 打印Access報表
在Microsoft Access數(shù)據(jù)庫中,用戶可以根據(jù)數(shù)據(jù)表創(chuàng)建Access報表,從而快速、準(zhǔn)確地掌握數(shù)據(jù)信息。在ASP應(yīng)用程序中,通過調(diào)用Access的相關(guān)對象可以打印指定的Access報表。
1.方案分析
Microsoft Access數(shù)據(jù)庫不僅具有強(qiáng)大的數(shù)據(jù)存儲功能,還擁有完善的報表功能,它支持子報、表、多欄報表、圖形報表等多種復(fù)雜元素。在ASP中,調(diào)用Access的Application對象,可以開發(fā)直接打印Access報表的程序。
打印Access報表的流程圖,如圖5.40所示。
圖5.40? 打印Access報表流程圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"5"5.5"5.5.2
在ASP應(yīng)用程序中直接打印Access報表,可以方便用戶對數(shù)據(jù)庫的一些相關(guān)操作。下面以新聞網(wǎng)站為例,介紹ASP調(diào)用Access的Application對象實(shí)現(xiàn)打印Access數(shù)據(jù)庫中新聞報表的功能。運(yùn)行效果如圖5.41所示。
圖5.41? 打印Access報表
在Microsoft Access數(shù)據(jù)庫中,可以使用向?qū)?chuàng)建報表。下面介紹具體創(chuàng)建報表的步驟:
(1)打開Access數(shù)據(jù)庫,單擊左側(cè)面板中的“報表”對象,在右側(cè)選擇“使用向?qū)?chuàng)建報表”的命令,打開“報表向?qū)А贝翱?#xff0c;在此窗口中選擇表及字段名稱,如圖5.42所示。
圖5.42? 選擇表及指定字段
(2)單擊“下一步”按鈕,可在打開的窗口中“確定是否添加分組類別”。再單擊“下一步”按鈕,在打開的窗口中可以確定記錄所用的排序次序,如圖5.43所示。
圖5.43? 確定記錄所用的排序次序
(3)單擊兩次“下一步”按鈕,分別確定報表的布局方式和所用樣式。然后在下一個窗口中為報表指定標(biāo)題,這里輸入“打印新聞報表”,如圖5.44所示。最后,單擊“完成”按鈕成功創(chuàng)建Access報表。
圖5.44? 定義報表標(biāo)題
創(chuàng)建Access報表后,在ASP頁面中建立表單。在表單中,用戶通過選擇所要操作的數(shù)據(jù)庫文件以及輸入Access數(shù)據(jù)庫中報表的名稱,來觸發(fā)打印Access報表的程序。下面給出表單中關(guān)鍵元素的代碼:
例程5-30? 代碼位置:光盤"mr"5"5.5"5.5.2"index.asp
<form action="" method="post" name="form1" onSubmit="PrintReport()">
Access數(shù)據(jù)庫路徑:<input name="txt_db" type="file" id="txt_db">
Access數(shù)據(jù)庫中報表名稱:<input name="txt_report" type="text" id="txt_report" title="Access數(shù)據(jù)庫中報表名稱">
<input type="submit" name="Submit" value="打印Access報表"? onClick="return Mycheck(this.form)">
<input type="reset" name="Submit2" value="重置表單內(nèi)容"></td>
</form>
在ASP頁面中,自定義一個客戶端VBScript腳本的sub過程。在該過程中,首先創(chuàng)建Access的Application對象實(shí)例,然后調(diào)用對象的OpenCurrentDatabase方法連接所指定的Access數(shù)據(jù)庫,再調(diào)用OpenReport方法打印指定名稱的Access報表,最后給出打印成功的提示信息。代碼如下:
例程5-31? 代碼位置:光盤"mr"5"5.5"5.5.2"index.asp
<script language="vbscript">
sub PrintReport()
Set pr = CreateObject("Access.Application")
pr.OpenCurrentDatabase document.all.txt_db.value
pr.DoCmd.OpenReport document.all.txt_report.value
pr.CloseCurrentDatabase
Set pr = Nothing
Msgbox "恭喜您,打印Access報表成功!"
end sub
</script>
3.補(bǔ)充說明
編寫ASP應(yīng)用程序所采用的VBScript語言是一種簡單的腳本語言,只能實(shí)現(xiàn)有限的功能。而使用一些開發(fā)工具編寫的組件,可以調(diào)用各種系統(tǒng)資源,實(shí)現(xiàn)較為復(fù)雜的功能。微軟公司的ASP具有良好的可擴(kuò)展性,而擴(kuò)展ASP最有效的途徑就是開發(fā)自定義的DLL組件,使用DLL組件的優(yōu)勢如下:
(1)實(shí)現(xiàn)代碼封裝技術(shù)。在開發(fā)程序時,ASP代碼是嵌入在HTML語言中的,如果頁面設(shè)計有變動,設(shè)計人員很難對嵌有代碼的頁面做改動,如果將代碼封裝在組件中,既方便設(shè)計人員進(jìn)行頁面布局,又增強(qiáng)程序的可讀性。
(2)起到保護(hù)頁面源碼的作用。ASP程序是無須編譯的,即它是以源碼的形式存儲在服務(wù)器上的,源程序很容易被他人獲取。而組件是經(jīng)過編譯的,服務(wù)器端只有一個編譯的DLL文件,保證源代碼不被泄漏。
(3)編譯好的組件可以重復(fù)使用,節(jié)約開發(fā)時間。
(4)用戶將程序開發(fā)代碼封裝在組件中,可以申請知識產(chǎn)權(quán)保護(hù)其利益。
讀者可以嘗試使用Visual Basic軟件來自定義ActiveX組件,然后調(diào)用該組件來實(shí)現(xiàn)特定的功能模塊。
5.5.3? 圖形報表打印
圖形報表是一種非常直觀的數(shù)據(jù)表現(xiàn)形式,它是通過柱狀圖、餅型圖、折線圖等多種圖表格式來統(tǒng)計數(shù)據(jù)的報表形式。在ASP中,可以利用圖形報表來統(tǒng)計和處理數(shù)據(jù),并進(jìn)行打印操作等。
1.方案分析
在實(shí)際工作中,為了使用戶能夠以直觀的方式查看到數(shù)據(jù)報表的內(nèi)在結(jié)構(gòu),并能夠明確報表所表達(dá)的含義,可以使用圖形報表作為報表的表現(xiàn)形式。在ASP應(yīng)用程序中,可以調(diào)用Visual Basic軟件中內(nèi)置的MSChart組件(MSChart組件是Microsoft提供的ActiveX組件之一,可以使用圖形方式顯示數(shù)據(jù)的圖表),將數(shù)據(jù)庫中的數(shù)據(jù)信息以圖形的方式展現(xiàn)在頁面中,從而實(shí)現(xiàn)圖形報表打印的功能。
圖形報表打印的流程圖,如圖5.45所示。
圖5.45? 圖形報表打印流程圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"5"5.5"5.5.3
在ASP中可以引用外部組件,使用柱狀圖、折線圖等形式將統(tǒng)計數(shù)據(jù)展現(xiàn)在網(wǎng)頁中。下面以網(wǎng)站的銷售管理模塊為例,介紹在選擇查詢條件并對商品銷售情況進(jìn)行統(tǒng)計核實(shí)時,利用圖形報表顯示查詢結(jié)果的過程。運(yùn)行效果如圖5.46所示。
圖5.46? 圖形報表打印
在商品銷售統(tǒng)計頁面中,提供了按月、按年或者按照具體日期進(jìn)行銷售統(tǒng)計的功能。在默認(rèn)情況下,是針對所有商品進(jìn)行銷售統(tǒng)計的,用戶也可以輸入具體的商品編號只針對一種商品進(jìn)行銷售統(tǒng)計。
在程序處理頁面中,首先根據(jù)選擇的統(tǒng)計類型,確定對應(yīng)的SQL查詢語句;然后使用<object>標(biāo)記嵌入MSChart組件;再通過JavaScript腳本語言設(shè)定MSChart組件的各屬性值,使查詢到的結(jié)果以圖形方式顯示在頁面中。代碼如下:
例程5-32? 代碼位置:光盤"mr"5"5.5"5.5.3"index.asp
<%
If Not Isempty(Request("btt_sell")) Then
? txt_Gnum=Request.Form("txt_Gnum")
? txt_type=Request.Form("txt_type")
? txt_amount=Request.Form("txt_amount")
? txt_start=Request.Form("txt_start")
? txt_end=Request.Form("txt_end")
如果用戶在商品編號文本框中輸入內(nèi)容,則判斷此商品編號是否存在。
? If txt_Gnum<>"" Then
??? Set rs=Server.CreateObject("ADODB.Recordset")
??? sqlstr="select Gnum from tb_sell where Gnum='"&txt_Gnum&"'"
??? rs.open sqlstr,conn,1,1
??? If rs.eof or rs.bof Then
????? Response.Write("<script language='javascript'>alert('此商品沒有銷售信息,請重新輸入!');history.back();</script>")??? ?
??? End If
?? rs.close
?? Set rs=Nothing
? End If
根據(jù)用戶選擇的統(tǒng)計類型,確定SQL查詢語句。獲取到的變量txt_type的值如果值為1,則按照商品的銷售月份進(jìn)行分組查詢,并統(tǒng)計指定月份的銷售金額;如果值為2,則按照商品的銷售年份進(jìn)行分組查詢,并統(tǒng)計指定年份的銷售金額。
? Select case txt_type
? case "1"
??? fig="個月"
??? If txt_Gnum<>"" Then
????? sqlstr="select * from (select top "&txt_amount&" sum(Smoney) as totals,Month(Sdate) as IssueDate from tb_sell where Gnum='"&txt_Gnum&"' group by Month(Sdate) order by Month(Sdate) desc) as a order by a.IssueDate"
??? Else
????? sqlstr="select * from (select top "&txt_amount&" sum(Smoney) as totals,Month(Sdate) as IssueDate from tb_sell group by Month(Sdate) order by Month(Sdate) desc) as a order by a.IssueDate"
??? End If
? case "2"
??? fig="年"
??? If txt_Gnum<>"" Then
????? sqlstr="select * from (select top "&txt_amount&" sum(Smoney) as totals,Year(Sdate) as IssueDate from tb_sell where Gnum='"&txt_Gnum&"' group by Year(Sdate) order by Year(Sdate) desc) as a order by a.IssueDate"
??? Else
????? sqlstr="select * from (select top "&txt_amount&" sum(Smoney) as totals,Year(Sdate) as IssueDate from tb_sell group by Year(Sdate) order by Year(Sdate) desc) as a order by a.IssueDate"
??? End If
? End Select
通過日期區(qū)間統(tǒng)計商品銷售情況。
? If txt_start<>"" and txt_end<>"" Then
??? If txt_Gnum<>"" Then
?? ? sqlstr="select * from (select sum(Smoney) as totals,Sdate as IssueDate from tb_sell where Gnum='"&txt_Gnum&"' and Sdate between #"&txt_start&"# and #"&txt_end&"# group by Sdate order by Sdate desc) as a order by a.IssueDate"
?? Else
????? sqlstr="select * from (select sum(Smoney) as totals,Sdate as IssueDate from tb_sell where Sdate between #"&txt_start&"# and #"&txt_end&"# group by Sdate order by Sdate desc) as a order by a.IssueDate"
?? End If
? End If
? Set rs=Server.CreateObject("ADODB.Recordset")
? rs.open sqlstr,conn,1,1
? counts=rs.recordcount
%>
使用<object>標(biāo)記引用MSChart組件,并在JavaScript腳本中定義組件的各屬性值,從而將查詢到的結(jié)果以圖表的形式顯示在頁面表格中。
<table width="600" border="1" align="center" cellpadding="0" cellspacing="0"?? bordercolor="#FFFFFF" bordercolorlight="#9CA6C6" bordercolordark="#CCE3FF">
? <tr bgcolor="#FF9933">
??? <td height="10" colspan="6" class="word_white"> </td>
? </tr>
? <tr align="center" bgcolor="#C8E3FF">
??? <td height="14">
<%
if counts>0 then
sum=0
%>
<object classid="clsid:3A2B370C-BA0A-11D1-B137-0000F8753F5D" name="chart" width="100%" height="300">
?? <%'定義對象,該對象命名為chart%>
</object>
<% for i=1 to counts
? If txt_amount="" Then txt_amount=1
? If fig="" Then fig="企業(yè)"
%>
<script language="javascript">
chart.chartType=1;
chart.ColumnCount=1;???
chart.TitleText="最近 "+<%=txt_amount%>+"<%=fig%>"+" 商品銷售情況顯示圖表 : ";??
chart.rowcount=<%=counts%>;???????????
chart.row=<%=i%>;??????????????????????
chart.rowlabel="<%=rs("IssueDate")%>(月/年/日期)";
chart.Data=<%=rs("totals")%>;?????????
chart.Footnote="注:縱坐標(biāo)為銷售金額";
</script>
<%sum=sum+rs("totals")
? rs.movenext?????
? next???????????
%>
</td>
? </tr>
? <tr>
??? <td height="30" colspan="6"> 最近<%Response.Write(txt_amount&fig)%>的銷售金額為 <%=sum%>元 </td>
? </tr>
</table>
<br>
引用WebBrowser組件,打印頁面中的圖形報表。
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"></object>
<div align="center"><a href="#" onClick="document.all.WebBrowser.Execwb(8,1)" class="Noprint">頁面屬性</a> <a href="#" onClick="document.all.WebBrowser.Execwb(7,1)" class="Noprint">打印預(yù)覽</a> <a href="#" onClick="document.all.WebBrowser.Execwb(6,1)" class="Noprint">打印</a></div>
<%End IF
End IF
%>
3.補(bǔ)充說明
在網(wǎng)絡(luò)應(yīng)用程序中,經(jīng)常會遇到由瀏覽者自己輸入日期的情況,如注冊頁面中的生日、商品銷售中售貨日期等,如果輸入的日期格式不正確,數(shù)據(jù)則不能正確保存。為了方便用戶操作及保證輸入日期格式的正確性,可以在需要輸入日期的位置加入Visual Basic的日期拾取組件(Microsoft Date and Time Picker),由用戶自己選擇日期。如圖5.47所示。
圖5.47? 調(diào)用Microsoft Date and Time Picker組件
DateTimePicker組件是Microsoft提供的ActiveX組件之一,可以返回格式化的日期字段,使得選擇日期很容易。在使用DateTimePicker組件之前,應(yīng)注冊MSCOMCT2.OCX文件并安裝Visual Basic軟件。調(diào)用日歷組件及獲取選擇的日期的關(guān)鍵代碼如下:
<form name="myform" method="post" action="">
? <tr bgcolor="#FFFFFF">
??? <td width="107" height="22" align="right">您選擇的日期為:</td>
??? <td width="286" height="22"><input name="Date_time" type="text" id="Date_time" onMouseOver="myevent()" onFocus="myevent()"></td>
? </tr>?
</form>
? <tr bgcolor="#FFFFFF">
??? <td height="22" align="right">選擇日期:</td>
??? <td height="22">
<script language="javascript">
function myevent(){
var date=new Date(mydate.value) ;
year=date.getUTCFullYear();
month=date.getUTCMonth()+1;
day=date.getUTCDate();
myform.Date_time.value=year+"-"+month+"-"+day;
//myform.submit();
}
</script>
<object classid="clsid:20DD1B9E-87C4-11D1-8BE3-0000F8754DA1" name="mydate" width="110" height="20">
? <param name="format" value=1>
</object></td>
? </tr>
5.5.4? 套打報表
套打是現(xiàn)在應(yīng)用較為廣范的一種打印方式,它是一種在印制有憑證、賬簿、報表格式、證書等紙張上進(jìn)行打印的打印方式,以這種方式進(jìn)行打印時,無須打印表格的表格線及其他固定的格式內(nèi)容,有利于加快打印速度、節(jié)約打印耗材、延長打印機(jī)的使用壽命等。
1.方案分析
在一些工作領(lǐng)域中(例如通信、郵政、商務(wù)洽談、財務(wù)等),為了加快工作效率,并為用戶提供方便,工作人員通常會將一些常用的業(yè)務(wù)事項或流程、憑證等事先打印出來,再由用戶按照上面的提示進(jìn)行填寫、核實(shí)等。
使用ASP開發(fā)動態(tài)網(wǎng)站時,可以在頁面中設(shè)計出所需要的格式,然后從數(shù)據(jù)庫中讀取所需要的數(shù)據(jù),并將數(shù)據(jù)放置在頁面指定的位置,從而實(shí)現(xiàn)套打報表的功能。套打報表的流程圖,如圖5.48所示。
圖5.48? 套打報表流程圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"5"5.5"5.5.4
在生活和工作過程中,當(dāng)人們郵寄一些快件時,首先要在快遞單上填寫郵件的基本信息。在開發(fā)動態(tài)網(wǎng)站時,為了滿足用戶需求,可以提供實(shí)時打印快遞單的功能。下面以電子商務(wù)網(wǎng)站的訂單信息管理模塊為例,介紹套打快遞單的實(shí)現(xiàn)過程。運(yùn)行效果如圖5.49所示。
圖5.49? 套打快遞單
在套打快遞單頁面中,用戶可以通過填寫寄件人或收件人的姓名來查詢快遞單的詳細(xì)信息。程序處理頁面根據(jù)獲取到的表單數(shù)據(jù),確定查詢的SQL語句,然后將從數(shù)據(jù)庫中讀取到的數(shù)據(jù)添加到頁面中指定位置,并應(yīng)用打印技術(shù)執(zhí)行套打操作。代碼如下:
例程5-33? 代碼位置:光盤"mr"5"5.5"5.5.4"index.asp
<%
Dim SendTime,SendAddress,ReceiveAddress,SendTel,Sender,ReceiveTel,Receiver,ThingsName,PayMoney,ThingsNumber,ThingsWeight,ThingsPrice
sql_type=Trim(Request.Form("type"))
txt_name=Trim(Request.Form("txt_name"))
Set rs=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from tb_info where 1=1"
根據(jù)用戶填寫的查詢條件,確定SQL查詢語句。
If txt_name<>"" then
?? select case sql_type
?? case "0"
?? sqlstr=sqlstr&" and sender='"&txt_name&"'"
?? case "1"
?? sqlstr=sqlstr&" and receiver='"&txt_name&"'"
?? end select
End If
rs.open sqlstr,conn,1,1
If rs.eof or rs.bof Then
? ? Response.Write("<p align=center>暫時不能提供任何信息!</p>")
?? Response.End
End if
對查詢到信息的進(jìn)行分頁處理。
rs.pagesize=1? '定義每頁顯示的記錄數(shù)
pages=clng(Request("pages"))? '獲得當(dāng)前頁數(shù)
If pages<1 Then pages=1
If pages>rs.recordcount Then pages=rs.recordcount
showpage rs,pages? '執(zhí)行分頁子程序showpage?????
Sub showpage(rs,pages) ?'分頁子程序showpage(rs,pages)
rs.absolutepage=pages?? '指定指針?biāo)诘漠?dāng)前位置
For i=1 to rs.pagesize? '循環(huán)顯示記錄集中的記錄SendTime=Now()
SendAddress=rs("sendAddress")
ReceiveAddress=rs("ReceiveAddress")
SendTel=rs("SendTel")
Sender=rs("Sender")
ReceiveTel=rs("ReceiveTel")
Receiver=rs("Receiver")
ThingsName=rs("ThingsName")
PayMoney=rs("PayMoney")
ThingsNumber=rs("ThingsNumber")
ThingsWeight=rs("ThingsWeight")
ThingsPrice=rs("ThingsPrice")
SendTime=rs("sendTime")
%>
…略,表格信息
<%
? rs.movenext
? If rs.eof Then Exit For
? Next
? End Sub
%>
????? <br>
????? <table width="450" height="25"? border="0" align="center" cellpadding="-2" cellspacing="0" class="print">
??????? <tr valign="middle" bgcolor="#FFFFFF">
????????? <%If Not (rs.eof and rs.bof) Then%>
????????? <td width="280" height="28"><% if pages<>1 then %>
??????????? <a href=?pages=1>第一頁</a> <a href=?pages=<%=(pages-1)%>>上一頁</a>
??????????? <%end if
????????????? if pages<>rs.pagecount then %>
??????????? <a href=?pages=<%=(pages+1)%>>下一頁</a> <a href=?pages=<%=rs.pagecount%>>最后一頁</a>
??????????? <%end if%></td>
????????? <%If not(rs.Eof and rs.Bof) Then%>
????????? <td width="220" height="28" align="right" class="word_grey">[<%=pages%>/<%=rs.PageCount%>] 每頁<%=rs.PageSize%>條 共<%=rs.RecordCount%>條信息</td>
??? <%End If
?? ? rs.close
?? ? Set rs=Nothing
?? ?End If
?? %>
??????? </tr>
??????? <tr bgcolor="#000000">
????????? <td colspan="2" valign="bottom" height="1"></td>
??????? </tr>
????? </table>
????? <br>
應(yīng)用WebBrowser組件進(jìn)行套打報表的操作。
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"> </object>
????? <div align="center"><a href="#" onClick="document.all.WebBrowser.Execwb(8,1)" class="Noprint">頁面設(shè)置</a> <a href="#" onClick="document.all.WebBrowser.Execwb(7,1)" class="Noprint">打印預(yù)覽</a> <a href="#" onClick="document.all.WebBrowser.Execwb(6,1)" class="Noprint">打印</a></div>
3.補(bǔ)充說明
使用WebBrowser組件執(zhí)行打印報表操作時,根據(jù)報表的實(shí)際結(jié)構(gòu),用戶可以通過“頁面設(shè)置”來定義打印選項,從而使打印能夠順利進(jìn)行。例如,當(dāng)紙張縱向打印不適合報表的寬度時,可以調(diào)整為“橫向”打印;可以設(shè)置“頁邊距”,使報表在指定的紙張位置處進(jìn)行打印;可以設(shè)置打印頁面的頁眉頁腳等。
“頁面設(shè)置”所包含的選項,如圖5.50所示。
圖5.50? 頁面設(shè)置窗口
?
在網(wǎng)絡(luò)信息時代,人們對網(wǎng)絡(luò)信息系統(tǒng)的依賴正逐漸增加,保證網(wǎng)絡(luò)安全變得愈加重要。網(wǎng)絡(luò)安全的本質(zhì)就是需要保證網(wǎng)絡(luò)上的信息安全,主要包括信息的保密性、完整性、可用性和準(zhǔn)確性等。
網(wǎng)站屬于計算機(jī)網(wǎng)絡(luò)中的一部分,它用來向用戶提供服務(wù)及相關(guān)信息。因此網(wǎng)絡(luò)中的安全隱患都會映射到它的身上。如何更有效地保護(hù)重要的數(shù)據(jù)信息,提高網(wǎng)站的安全性已經(jīng)成為Web程序開發(fā)中必須考慮和解決的一個重要問題。
本章將詳細(xì)介紹在網(wǎng)絡(luò)開發(fā)中的一些安全問題,及針對這些安全問題實(shí)施的各種策略和解決方案。讀者通過本章的學(xué)習(xí),可采用這些技術(shù)加強(qiáng)網(wǎng)站的安全,使網(wǎng)站的運(yùn)行得到可靠的保障。
6.3? 用戶權(quán)限方案
為了提高網(wǎng)站的安全性,經(jīng)常會為網(wǎng)站中的用戶分配不同的權(quán)限,這樣不僅可以有效的管理用戶,而且可以在很大程度上提高網(wǎng)站的安全性。本節(jié)將對在開發(fā)和運(yùn)營一個網(wǎng)站時,如何為不同級別的用戶分配不同的權(quán)限做了具體、全面的分析。
6.3.1? 默認(rèn)用戶權(quán)限
在一些企業(yè)管理系統(tǒng)中,經(jīng)常會有多位管理人員對系統(tǒng)中的內(nèi)部資源進(jìn)行管理。為了提高系統(tǒng)的安全性,大多數(shù)情況下,系統(tǒng)中只有一位具有全局權(quán)限的管理員,并且該管理員具有添加普通管理員的權(quán)限,在添加這些普通管理員時,可以為新的管理員進(jìn)行權(quán)限的分配。
1.方案分析
? 實(shí)例位置:光盤"mr"6"6.3"6.3.1
進(jìn)入用戶登錄頁面后,首先在登錄表單中添加用戶的登錄信息,然后提交表單,這樣該用戶的所有登錄信息將被提交的用戶登錄信息處理頁。在用戶信息處理頁中,首先判斷用戶的用戶名和密碼是否正確,如果錯誤則返回登錄頁面,否則繼續(xù)判斷該用戶所屬級別,并根據(jù)用戶級別為其分配不同的權(quán)限。例如,人力資源管理系統(tǒng)中的用戶可以分為系統(tǒng)用戶(或全局用戶)、讀寫用戶和只讀用戶,系統(tǒng)用戶具有全局管理的權(quán)限,讀寫用戶具有對常規(guī)數(shù)據(jù)進(jìn)行修改、刪除等權(quán)限,而只讀用戶只具有最基本的瀏覽權(quán)限。默認(rèn)用戶權(quán)限方案分析的示意圖,如圖6.16所示。
圖6.16? 默認(rèn)用戶權(quán)限的示意圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"6"6.3"6.3.1
運(yùn)行網(wǎng)上企業(yè)辦公自動化系統(tǒng)的用戶信息修改頁面,如圖6.17所示,單擊該頁面中的用戶“權(quán)限”下拉列表框,可以發(fā)現(xiàn)該系統(tǒng)中用戶權(quán)限主要分為系統(tǒng)、讀寫和只讀3種。當(dāng)對用戶權(quán)限進(jìn)行修改時首先從用戶權(quán)限下拉列表中為用戶指定權(quán)限,然后單擊“修改”按鈕即可實(shí)現(xiàn)用戶權(quán)限的修改。
圖6.17? 用戶權(quán)限修改頁面
在網(wǎng)上企業(yè)辦公自動化系統(tǒng)管理頁面中單擊“人力資源”超鏈接,即可進(jìn)入用戶信息管理頁面。在該頁面中可以添加新用戶信息、修改個人信息、修改其他用戶信息、刪除用戶信息等操作。用戶信息添加頁面主要用于向數(shù)據(jù)庫中添加新的用戶信息。運(yùn)行結(jié)果如圖6.18所示。
圖6.18? 用戶信息添加頁面
制作添加用戶信息的表單頁面,該頁面主要用于系統(tǒng)用戶添加用戶信息。在添加用戶信息時,將應(yīng)用JavaScript腳本驗(yàn)證輸入信息是否合法。添加用戶信息表單頁面所涉及的重要表單元素如表6.1所示。
表6.1????????????? ????添加用戶信息頁面所涉及的重要表單元素
| 名稱 | 元素類型 | 含義 | 重要屬性 |
| form1 | form | 表單 | <form ACTION="personnel_add.asp" METHOD="POST" name="form1"> |
| username | text | 用戶名 | <input name="username" type="text" class="Sytle_text" id="username"> |
| branch | select | 部門 | <select name="branch" id="select4"> <option value="開發(fā)部" selected>開發(fā)部</option> <option value="人事部">人事部</option> <option value="銷售部">銷售部</option> </select> |
| name | text | 姓名 | <input name="name" type="text" class="Sytle_text" id="name"> |
| sex | select | 性別 | <select name="sex" id="sex"> <option value="男" selected>男</option><option value="女">女</option> </select> |
| purview | select | 權(quán)限 | <select name="purview" id="select"> <option value="系統(tǒng)" selected>系統(tǒng)</option> <option value="讀寫">讀寫</option><option value="只讀">只讀</option> </select> |
| Button | Button | “提交”按鈕 | <input name="Button" type="button" class="Style_button" value="提交" onClick="Mycheck()"> |
| Submit2 | reset | “重置”按鈕 | <input name="Submit2" type="reset" class="Style_button" value="重置"> |
| myclose | button | “關(guān)閉”按鈕 | <input name="myclose" type="button" class="Style_button" id="myclose" value="關(guān)閉" onClick="javascrip:window.close()"> |
在實(shí)現(xiàn)用戶信息添加時,首先判斷客戶端輸入的用戶信息是否合法,然后在將合法的用戶信息保存到用戶信息表中,通過以下代碼實(shí)現(xiàn)用戶信息的添加,代碼如下:
例程6-15? 代碼位置:光盤"mr"6"6.3"6.3.2"personnel_add.asp
<!--#include file="../Connections/conn.asp" -->
<%
if request.Form("username")<>""then
'檢測用戶名是否存在
?? Set rs= Server.CreateObject("ADODB.Recordset")
?? sql="SELECT UserName FROM dbo.Tab_User WHERE UserName='" &Request.Form("UserName")&"'"
?? rs.open sql,conn,1,3
?? if rs.eof then
'保存員工信息
?????? username=request.Form("username")
?????? cname=request.Form("name")
?????? branch=request.Form("branch")
?????? PWD=request.Form("PWD")
?????? job=request.Form("job")
?????? tel=request.Form("tel")
?????? purview=request.Form("purview")
?????? sex=request.Form("sex")
?????? email=request.Form("email")
?????? address=request.Form("address")
?????? Ins="Insert into dbo.Tab_User (username,name,branch,PWD,job,tel,purview,sex,"&_
?????? "email,address) values('"&username&"','"&cname&"','"&branch&"','"&PWD&"','"&_
?????? job&"','"&tel&"','"&purview&"','"&sex&"','"&email&"','"&address&"')"
?????? conn.execute(Ins)
%>
?????? <script language="javascript">
?????? alert("員工信息添加成功!");
?????? opener.parent.location.reload();
?????? window.close();
?????? </script>
?? <%
Else
%>
?????? <script language="javascript">
?????? alert("該員工信息已經(jīng)存在!");
?????? </script>
?? <%
?? end if
end if
%>
<script language="javascript">
function Mycheck()
{
if (form1.username.value=="")
{ alert("請輸入員工姓名!");form1.username.focus();return;}
if (form1.PWD.value=="")
{ alert("請輸入密碼!");form1.PWD.focus();return;}
if (form1.tel.value=="")
{
alert("請輸入員工的聯(lián)系電話!");
form1.tel.focus();return;
}
if(form1.email.value!="" && (form1.email.value.indexOf('@',0)==-1|| form1.email.value.indexOf('.',0)==-1))
{alert("您輸入的E-mail地址不對!");form1.email.focus();return;}
if (form1.address.value=="")
{
alert("請輸入員工的住址!");
form1.address.focus();return;
}
form1.submit();}
</script>
用戶成功登錄后,首先判斷此用戶是否是系統(tǒng)用戶,如果該用戶是系統(tǒng)用戶,則可以通過“人力資源管理”模塊,進(jìn)行“添加新用戶”、“修改個人信息”、“用戶信息修改”和“用戶信息刪除”操作(可以對所有用戶進(jìn)行修改和刪除操作);否則只可以對用戶本身的密碼進(jìn)行修改。用戶信息修改頁面的運(yùn)行結(jié)果如圖6.19所示。
圖6.19? 用戶信息修改頁面
通過以下代碼實(shí)現(xiàn)用戶信息的修改,代碼如下:
例程6-16? 代碼位置:光盤"mr"6"6.3"6.3.2"personnel_modify.asp
<!--#include file="../Connections/conn.asp" -->
<%
'查詢員工信息
If Request.QueryString("ID")<>""then
session("ID")=Request.QueryString("ID")
end if
Set rs_personnel = Server.CreateObject("ADODB.Recordset")
sql_P="SELECT ID,UserName,name,PWD,purview,branch,job,sex,Email,Tel,Address"&_
" FROM dbo.Tab_User WHERE ID="&session("ID")&""
rs_personnel.open sql_p,conn,1,3
%>
<%
'修改員工信息
if request.Form("Name")<>"" then
?? cname=request.Form("name")
?? PWD=request.Form("PWD")
?? purview=request.Form("purview")
?? sex=request.Form("sex")
?? tel=request.Form("tel")
?? branch=request.Form("branch")
?? job=request.Form("job")
?? email=request.Form("email")
?? address=request.Form("address")
?? UP="Update dbo.Tab_User set name='"&cname&"',PWD='"&PWD&"',purview='"&_
?? purview&"',sex='"&sex&"',tel='"&tel&"',branch='"&branch&"',job='"&job&_
?? "',email='"&email&"',address='"&address&"' where ID='"&session("ID")&"'"
?? conn.execute(UP)
%>
?? <script language="javascript">
?? alert("數(shù)據(jù)修改成功!");
?? opener.parent.location.reload();
?? window.close();
?? </script>
<%
end if
%>
<script language="javascript">
function Mycheck()
{
if (form1.name.value=="")
{ alert("請輸入員工姓名!");form1.name.focus();return;}
if (form1.PWD.value=="")
{ alert("請輸入密碼!");form1.PWD.focus();return;}
if (form1.tel.value=="")
{
alert("請輸入員工的聯(lián)系電話!");
form1.tel.focus();return;
}
if(form1.email.value!="" && (form1.email.value.indexOf('@',0)==-1|| form1.email.value.indexOf('.',0)==-1))
{
alert("您輸入的E-mail地址不對!");
form1.email.focus();return;
}
if (form1.address.value=="")
{
alert("請輸入員工的住址!");
form1.address.focus();return;
}
form1.submit();}
</script>
通過以下代碼實(shí)現(xiàn)用戶信息的刪除,代碼如下:
例程6-17? 代碼位置:光盤"mr"6"6.3"6.3.2"personnel_del.asp
<!--#include file="../Connections/conn.asp" -->
<%
if request.Form("UserName")<>"" then
?? DEL="Delete From dbo.Tab_User where ID='"&session("ID")&"'"
?? conn.execute(Del)
%>
?? <script language="javascript">
?? alert("員工信息已經(jīng)刪除!");
?? opener.location.reload();
?? window.close();
?? </script>
<%end if%>
<%
if Request.QueryString("ID")<>""then
?? session("ID")=Request.QueryString("ID")
end if
Set rs_personnel = Server.CreateObject("ADODB.Recordset")
sql_P="SELECT ID,UserName,Name,PWD,purview,branch,sex,Email,Tel,Address"&_
" FROM dbo.Tab_User WHERE ID="&session("ID")&""
rs_personnel.open sql_P,conn,1,3
%>
3.補(bǔ)充說明
為用戶分配默認(rèn)的權(quán)限,即可在添加用戶信息時指定,也可以先注冊用戶信息,然后根據(jù)不同用戶的職能為其分配不同的權(quán)限。為了提高網(wǎng)站的安全性,在為用戶指定默認(rèn)權(quán)限時,一定要根據(jù)用戶的職能權(quán)限進(jìn)行的合理分配,否則一旦非法用戶登錄系統(tǒng)將會給整個系統(tǒng)造成極大的損失。
6.3.2? 簡單自定義用戶權(quán)限
簡單自定義權(quán)限是指在添加新管理員時,根據(jù)該管理員的管理職責(zé)而為其分配的權(quán)限。例如,在為系統(tǒng)添加數(shù)據(jù)錄入管理人員時,只需為其分配數(shù)據(jù)添加和數(shù)據(jù)刪除的權(quán)限即可,為了提高整個系統(tǒng)的安全性,不必為其過多的分配其他權(quán)限。下面將以辦公自化管理系統(tǒng)為例來講解簡單自定義用戶權(quán)限的具體實(shí)現(xiàn)過程。
1.方案分析
一個網(wǎng)站管理系統(tǒng)的后臺用戶主要分為兩種,一種是全局管理員,另一種是普通管理員。全局管理員具有整個后臺的全局管理權(quán)限,除了具有對后臺數(shù)據(jù)進(jìn)行管理的所有權(quán)限外,還具有對普通管理員進(jìn)行管理的權(quán)限;而普通管理員只具有對后臺數(shù)據(jù)進(jìn)行添加、修改和刪除的權(quán)限以及對個人信息進(jìn)行修改的權(quán)限。管理人員首先進(jìn)入后臺登錄頁面,然后在登錄表單中輸入個人的登錄信息并提交表單,這樣該管理員的登錄信息將被提交到用戶信息驗(yàn)證頁,如果用戶的個人信息填寫錯誤則返回到登錄頁,否則對用戶的級別進(jìn)行判斷,并根據(jù)用戶的級別為其分配不同的權(quán)限。實(shí)現(xiàn)簡單自定義用戶權(quán)限的示意圖,如圖6.20所示。
圖6.20? 簡單自定義用戶權(quán)限的示意圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"6"6.3"6.3.2
下面將以辦公自動化管理系統(tǒng)為例講解如何實(shí)現(xiàn)簡單自定義用戶權(quán)限。當(dāng)超級用戶成功進(jìn)入系統(tǒng)后,可以進(jìn)行新用戶的添加,如圖6.21所示。首先在該頁面的用戶名和密碼的文本框中輸入合法的用戶名和密碼,然后從權(quán)限列表框中選擇要為該用戶分配的權(quán)限,最后單擊“提交”按鈕即可實(shí)現(xiàn)自定義權(quán)限的添加。
圖6.21? 添加超級用戶信息頁面
通過以下代碼實(shí)現(xiàn)數(shù)據(jù)庫的連接,代碼如下:
例程6-18? 代碼位置:光盤"mr"6"6.3"6.3.2"data"conn.asp
<%
set conn=server.CreateObject("Adodb.Connection")
Path="driver={SQL Server};server=.;uid=sa;pwd=;database=db_safe"
conn.open path
function HTMLcode(fString)
if not isnull(fString) then
??? fString = Replace(fString, CHR(13), "")
??? fString = Replace(fString, CHR(10) & CHR(10), "</P><P>")
??? fString = Replace(fString, CHR(10), "<BR>")
?? fString = Replace(fString, CHR(32), " ")
??? HTMLcode = fString
end if
end function
%>
在用戶管理模塊中單擊“用戶添加”超鏈接,即可進(jìn)入到用戶添加頁面。用戶信息添加頁面主要用于向數(shù)據(jù)庫中添加新的用戶信息。其運(yùn)行結(jié)果如圖6.22所示。
圖6.22? 用戶信息添加頁面的運(yùn)行結(jié)果
制作添加用戶信息的表單頁面,該頁面主要用于收集超級用戶添加的用戶信息和驗(yàn)證輸入信息是否合法。添加用戶信息表單頁面所涉及的重要表單元素如表6.2所示。
表6.2????????????????? 添加用戶信息頁面所涉及的重要表單元素
| 名稱 | 元素類型 | 含義 | 重要屬性 |
| form1 | form | 表單 | action="" method="post" name="form1" |
| username | text | 用戶名 | <input name="username" type="text" id="username" size="20"> |
| post | hidden | 隱藏域 | <input name="post" type="hidden" id="post" value="1"> |
| userpwd | password | 密碼 | <input name="userpwd" type="password" id="userpwd" size="20"> |
| menu1 | select | 文本域 | <select name="menu1" size="3" onChange="MM_jumpMenu('nei',this,0)"> <% set rs2=server.CreateObject("adodb.recordset") sql2="select * from renshi" rs2.open sql2,conn,1,1 if not rs2.eof then for i=1 to rs2.recordcount and not rs2.eof%>? <option value=nei.asp?id=<%=rs2("id")%>> <%=rs2("name")%></option> <% rs2.movenext if rs2.eof then exit for Next else response.Write("<option value='沒有用戶'>沒有用戶</option>")? end if????????? %></select> |
| Submit | Submit | “提交”按鈕 | <input type="submit" name="Submit" value="提交"> |
| Submit2 | reset | “重置”按鈕 | <input type="reset" name="Submit2" value="重置"> |
在實(shí)現(xiàn)用戶信息添加時,首先判斷客戶端輸入的用戶信息是否合法,然后在將合法的用戶信息保存到用戶信息表中,通過以下代碼實(shí)現(xiàn)用戶信息的添加,代碼如下:
例程6-19? 代碼位置:光盤"mr"6"6.3"6.3.2"adduser.asp
<!--#include file=data/conn.asp-->
<!--#include file=connfig.asp-->
<!--#include file=inc/yan.asp-->
<%
?? '驗(yàn)證用戶身份
?? call case10
?? if request("post")=1 then
?? ? if request("username")="" or request("userpwd")="" then
?? response.Write("<script language=JavaScript>" & "alert('用戶名或者密碼不能為空!');" & "history.back()" & "</script>")
?? else
?? ?if request("user")=0 then
?????? ? call wr1
?????? else
?????? ?? call wr2
?????? end if
?? ? end if
?? end if
?? '添加普通用戶
?? function wr1
?? username=trim(replace(request("username"),"'",""))
?? userpwd=trim(replace(request("userpwd"),"'",""))
?? for i=1 to len(username)
?? ? user=mid(username,i,1)
?? ? if user="'" or user="%" or user="<" or user=">" or user="&" or user="|" then
?????? response.write "<script language=JavaScript>" & "alert('您的用戶名含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
?????? response.end
?? ? end if
?? next
?? for i=1 to len(userpwd)
?? ? pass=mid(userpwd,i,1)
?? ? if pass="'" or pass="%" or pass="<" or pass=">" or pass="&" or pass="|" then
?????? ?response.write "<script language=JavaScript>" & "alert('您的密碼含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
?????? ?response.end
?? ? end if
?? next
?? ???? '判斷用戶名是否已經(jīng)存在
?????? ?set rs1=server.CreateObject("adodb.recordset")
?????? ?sql1 = "Select * From users Where username='"&request("username")&"'"
?????? ?rs1.open sql1,conn,1,1
?????? ?If not rs1.EOF Then
?????? ?response.Write("<script language=JavaScript>" & "alert('用戶名已經(jīng)存在!');" & "window.location.href='adduser.asp';" & "</script>")
?????? ?response.End()
?????? ?end if
?????? ?rs1.close
?? '添加用戶權(quán)限
?? set rs=server.CreateObject("adodb.recordset")
?? sql="select * from users"
?? rs.open sql,conn,1,3
?? rs.addnew
?? rs("username")=request("username")
?? rs("userpwd")=request("userpwd")
?? rs("shenhe")=request("shenhe")
?? rs("huiyi")=request("huiyi")
?? rs("gonggong")=request("gonggong")
?? rs("geren")=request("geren")
?? rs("renshi")=request("renshi")
?? rs("name")=session("na")
?? rs("time")=now()
?? rs.update
?? rs.close
?? response.Write("<script language=JavaScript>" & "alert('添加成功!');" & "window.location.href='adduser.asp';" & "</script>")
?? response.End()
?? end function
?? ?'添加超級用戶
?? function wr2
?? username=trim(replace(request("username"),"'",""))
?? userpwd=trim(replace(request("userpwd"),"'",""))
?? for i=1 to len(username)
?? ? user=mid(username,i,1)
?? ? if user="'" or user="%" or user="<" or user=">" or user="&" or user="|" then
?????? response.write "<script language=JavaScript>" & "alert('您的用戶名含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
?????? response.end
?? ? end if
?? next
?? for i=1 to len(userpwd)
?? ? pass=mid(userpwd,i,1)
?? ? if pass="'" or pass="%" or pass="<" or pass=">" or pass="&" or pass="|" then
?????? ?response.write "<script language=JavaScript>" & "alert('您的密碼含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
?????? ?response.end
?? ? end if
?? next
?????? ?set rs1=server.CreateObject("adodb.recordset")
?????? ?sql1 = "Select * From users Where username='"&request("username")&"'"
?????? ?rs1.open sql1,conn,1,1
?????? ?If not rs1.EOF Then
?????? ?response.Write("<script language=JavaScript>" & "alert('用戶名已經(jīng)存在!');" & "history.back()" & "</script>")
?????? ?end if
?????? ?rs1.close
?? set rs=server.CreateObject("adodb.recordset")
?? sql="select * from users"
?? rs.open sql,conn,1,3
?? rs.addnew
?? rs("username")=request("username")
?? rs("userpwd")=request("userpwd")
?? rs("name")=session("na")
?? rs("chaoji")=1
?? rs("time")=now()
?? rs.update
?? rs.close
?? response.Write("<script language=JavaScript>" & "alert('添加成功!');" & "history.back()" & "</script>")
?? end function
%>
在進(jìn)行用戶登錄時,首先判斷此用戶是否是超級用戶,如果該用戶是超級用戶,則可以通過“用戶管理”模塊,進(jìn)行“用戶添加”、“用戶修改”和“刪除”操作(可以對所有用戶進(jìn)行修改和刪除操作);否則只可以對用戶本身的密碼進(jìn)行修改。用戶信息修改頁面的運(yùn)行結(jié)果如圖6.23所示。
圖6.23? 用戶信息修改頁面的運(yùn)行結(jié)果
通過以下代碼實(shí)現(xiàn)用戶信息的修改,代碼如下:
例程6-20? 代碼位置:光盤"mr"6"6.3"6.3.2"adduser1.asp
<!--#include file=data/conn.asp-->
<!--#include file=connfig.asp-->
<!--#include file=inc/yan.asp-->
<%
call case10
?set rs2=server.CreateObject("adodb.recordset")
??? sql2="select * from users where id="&request("id")
??? rs2.open sql2,conn,1,1
if request("post")=1 then
? if request("username")="" or request("userpwd")="" then
response.Write("<script language=JavaScript>" & "alert('用戶名或者密碼不能為空!');" & "history.back()" & "</script>")
else
?if request("user")=0 then
????? call wr1
??? else
?????? call wr2
??? end if
? end if
end if
function wr1
if session("na")="" then
na=rs2("name")
else
na=session("na")
end if
username=trim(replace(request("username"),"'",""))
userpwd=trim(replace(request("userpwd"),"'",""))
for i=1 to len(username)
? user=mid(username,i,1)
? if user="'" or user="%" or user="<" or user=">" or user="&" or user="|" then
??? response.write "<script language=JavaScript>" & "alert('您的用戶名含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
??? response.end
? end if
next
for i=1 to len(userpwd)
? pass=mid(userpwd,i,1)
? if pass="'" or pass="%" or pass="<" or pass=">" or pass="&" or pass="|" then
???? response.write "<script language=JavaScript>" & "alert('您的密碼含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
???? response.end
? end if
next
set rs=server.CreateObject("adodb.recordset")
sql="select * from users where id="&session("id")
rs.open sql,conn,1,3
rs("username")=request("username")
rs("userpwd")=request("userpwd")
rs("shenhe")=request("shenhe")
rs("huiyi")=request("huiyi")
rs("gonggong")=request("gonggong")
rs("geren")=request("geren")
rs("renshi")=request("renshi")
rs("name")=na
rs("chaoji")=0
rs.update
rs.close
response.Write("<script language=JavaScript>" & "alert('修改成功!');" & "history.back()" & "</script>")
end function
?function wr2
?if session("na")="" then
na=rs2("name")
else
na=session("na")
end if
username=trim(replace(request("username"),"'",""))
userpwd=trim(replace(request("userpwd"),"'",""))
for i=1 to len(username)
? user=mid(username,i,1)
? if user="'" or user="%" or user="<" or user=">" or user="&" or user="|" then
??? response.write "<script language=JavaScript>" & "alert('您的用戶名含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
??? response.end
? end if
next
for i=1 to len(userpwd)
? pass=mid(userpwd,i,1)
? if pass="'" or pass="%" or pass="<" or pass=">" or pass="&" or pass="|" then
???? response.write "<script language=JavaScript>" & "alert('您的密碼含有非法字符,請重新輸入!');" & "history.back()" & "</script>"
???? response.end
? end if
next
set rs=server.CreateObject("adodb.recordset")
sql="select * from users where id="&session("id")
rs.open sql,conn,1,3
rs("username")=request("username")
rs("userpwd")=request("userpwd")
rs("name")=na
rs("chaoji")=1
rs.update
rs.close
response.Write("<script language=JavaScript>" & "alert('修改成功!');" & "history.back()" & "</script>")
end function
%>
通過以下代碼實(shí)現(xiàn)用戶信息的刪除,代碼如下:
例程6-21? 代碼位置:光盤"mr"6"6.3"6.3.2"del.asp
<!--#include file=data/conn.asp-->
<!--#include file=connfig.asp-->
<!--#include file=inc/yan.asp-->
<%
?? '驗(yàn)證用戶權(quán)限
?? call case10
?? if request("del")<>"" and ps("chaoji")=1 then
?? call del
?? end if
?? '刪除用戶
?? function del
?? sql2="delete from users where id="&request("del")
?? conn.Execute(sql2)
?? end function
%>
當(dāng)?shù)卿浀挠脩羰瞧胀ㄓ脩魰r,只可以對用戶本身的密碼進(jìn)行修改。通過以下代碼實(shí)現(xiàn)普通用戶密碼的修改操作,代碼如下:
例程6-22? 代碼位置:光盤"mr"6"6.3"6.3.2"yonghugai.asp
<!--#include file=data/conn.asp-->
<!--#include file=connfig.asp-->
<%
if request("post")<>"" then
call write1
end if
function write1
if request("userpwd1")<>"" and request("userpwd2")<>"" then
if request("userpwd1")<>request("userpwd2") then
response.Write("<script language=javascript>alert('兩次輸入密碼不一致!!')</script>")
else
set rs=server.CreateObject("adodb.recordset")
sql="select * from users where username='"&session("admin_name")&"'"
rs.open sql,conn,1,3
rs("userpwd")=request("userpwd1")
rs.update
end if
else
response.Write("<script language=javascript>alert('密碼不能為空!')</script>")
end if
if request("qq")<>"" then
set rs1=server.CreateObject("adodb.recordset")
sql1="select * from renshi where name='"&rs("name")&"'"
rs1.open sql1,conn,1,3
rs1("tel")=request("tel")
rs1("age")=request("age")
rs1("email")=request("email")
rs1("address")=request("address")
rs1.update
rs1.close
end if
response.Redirect("chenggong.htm")
end function
set rs3=server.CreateObject("adodb.recordset")
sql3="select * from users where username='"&session("admin_name")&"'"
rs3.open sql3,conn,1,3
set rs4=server.CreateObject("adodb.recordset")
sql4="select * from renshi where name='"&rs3("name")&"'"
rs4.open sql4,conn,1,3
%>
3.補(bǔ)充說明
在實(shí)現(xiàn)簡單自定義用戶權(quán)限時,也可以將普通用戶權(quán)限和超級用戶權(quán)限的選項放在下拉列表中,并在Dreamweaver中插入兩個下拉列表框,同時將下拉列表的類型設(shè)置為“列表”類型,選擇“允許多選”前面的復(fù)選框,設(shè)置完成后將相關(guān)的權(quán)限信息輸入到下拉列表框中,此時可以按shift鍵進(jìn)行用戶權(quán)限的多選操作,即實(shí)現(xiàn)與復(fù)選框同樣的功能。通過該方法同樣可以實(shí)現(xiàn)簡單自定義用戶權(quán)限的設(shè)置,運(yùn)行結(jié)果如圖6.24所示。
圖6.24? 應(yīng)用下拉列表實(shí)現(xiàn)簡單自定義用戶權(quán)限的設(shè)置
6.3.3? 復(fù)雜自定義用戶權(quán)限
在某些較大規(guī)模的管理系統(tǒng)中,為了有效合理的對系統(tǒng)信息進(jìn)行管理,無論是全局管理員還是普通管理者的權(quán)限都是極其復(fù)雜的。那么如何在復(fù)雜的管理系統(tǒng)中定義及分配用戶的權(quán)限呢?下面將以企業(yè)進(jìn)銷存管理系統(tǒng)為例來講解復(fù)雜自定義用戶權(quán)限的設(shè)計方案及具體實(shí)現(xiàn)過程。
1.方案分析
實(shí)現(xiàn)“復(fù)雜自定義用戶權(quán)限”與實(shí)現(xiàn)“簡單自定義用戶權(quán)限”的實(shí)現(xiàn)方案大體類似,區(qū)別是在為用戶指定權(quán)限時需要考慮更多的因素。管理人員首先進(jìn)入后臺登錄頁面,然后在登錄表單中輸入個人的登錄信息并提交表單,這樣該管理員的登錄信息將被提交到用戶信息驗(yàn)證頁,如果用戶的個人信息填寫錯誤則返回到登錄頁,否則可以對用戶的級別進(jìn)行判斷,并根據(jù)用戶的級別為其分配不同的權(quán)限。實(shí)現(xiàn)復(fù)雜自定義用戶權(quán)限的示意圖,如圖6.25所示
圖6.25? 復(fù)雜自定義用戶權(quán)限的示意圖
2.實(shí)施過程
? 實(shí)例位置:光盤"mr"6"6.3"6.3.3
全局管理員成功登錄企業(yè)進(jìn)銷存管理系統(tǒng)的后臺時,就可以進(jìn)入該系統(tǒng)的“權(quán)限管理”模塊,如圖6.26所示。在“權(quán)限管理”模塊中列出了所有管理員的用戶名和該管理員的權(quán)限信息,如果預(yù)刪除某管理員,可以直接單擊該管理員所對應(yīng)的“刪除”超鏈接即可。如果對某用戶的權(quán)限進(jìn)行設(shè)置或重新分配時,可以單擊該管理員后的“權(quán)限設(shè)置”超鏈接進(jìn)入權(quán)限設(shè)置頁面可以對該管理員的權(quán)限進(jìn)行重新設(shè)定。
圖6.26? 復(fù)雜自定義用戶權(quán)限管理頁面
本系統(tǒng)后臺數(shù)據(jù)庫采用的是Access數(shù)據(jù)庫,系統(tǒng)數(shù)據(jù)庫名稱為db_database.mdb。數(shù)據(jù)庫db_database.mdb中包含兩張數(shù)據(jù)表:分別為tb_use(管理員信息表)和tb_purview(權(quán)限信息表)。下面將分別給出這兩個數(shù)據(jù)表的表結(jié)構(gòu)。
(1)tb_use(管理員信息表)主要用于保存管理員的名稱及密碼信息,其表結(jié)構(gòu)如表6.3所示。
表6.3?? ????????????????????????表tb_use的結(jié)構(gòu)
| 字段名稱 | 數(shù)據(jù)類型 | 長度 | 默認(rèn)值 | 描述 |
| id | 自動編號 | 管理員ID號 | ||
| use | 文本 | 50 | 管理員名稱 | |
| pwd | 文本 | 50 | 管理員密碼 |
(2)tb_purview(權(quán)限信息表)主要用于保存管理員的權(quán)限信息,其表結(jié)構(gòu)如表6.4所示。
表6.4???????????????????????????? tb_purview表
| 字段名稱 | 數(shù)據(jù)類型 | 長度 | 默認(rèn)值 | 描述 |
| id | 數(shù)字 | 長整型 | 0 | 管理員ID號 |
| purviewSet | 是/否 | 權(quán)限設(shè)置 | ||
| basicSet | 是/否 | 基本信息管理 | ||
| stockSet | 是/否 | 進(jìn)貨管理 | ||
| sellSet | 是/否 | 銷售管理 | ||
| storageSet | 是/否 | 庫存管理 | ||
| querySet | 是/否 | 查詢統(tǒng)計 | ||
| reportSet | 是/否 | 報表管理 |
通過以下代碼實(shí)現(xiàn)數(shù)據(jù)庫的連接,代碼如下:
例程6-23? 代碼位置:光盤"mr"6"6.3"6.3.3"Conn"conn.asp
<%
Set conn=Server.CreateObject("ADODB.Connection")
sql="Provider=Microsoft.jet.oledb.4.0;data source="&Server.MapPath("database/db_database.mdb")
conn.open(sql)
%>
在權(quán)限管理的主頁中單擊“添加管理員信息”超鏈接,即可進(jìn)入到添加管理員信息頁面。添加管理員信息頁面主要用于向數(shù)據(jù)庫中添加新的管理員。運(yùn)行結(jié)果如圖6.27所示。
圖6.27? 添加管理員信息頁面的運(yùn)行結(jié)果
制作添加管理員信息的表單頁面,該頁面主要用于收集管理員添加的管理員信息和驗(yàn)證輸入信息是否合法。添加管理員信息表單頁面所涉及的重要表單元素如表6.5所示。
表6.5????????????????? 添加管理員信息頁面所涉及的重要表單元素
| 名稱 | 元素類型 | 含義 | 重要屬性 |
| form1 | form | 表單 | action="tjyg.asp" method="post" name="form1" |
| use | text | 管理員名稱 | <input name="use" type="text" id="use" size="19"> |
| pwd | password | 管理員密碼 | <input name="pwd" type="password" id="pwd" size="20"> |
| pwd1 | password | 確認(rèn)密碼 | <input name="pwd1" type="password" id="pwd1" size="20"> |
| Img1 | Img | “保存”按鈕 | <img src="images/button2.gif" width="58" height="24" onClick="Mycheck1();"> |
| Img2 | img | “關(guān)閉”按鈕 | <img src="images/button3.gif" width="58" height="24" onClick="window.close();opener.location.reload();"> |
在實(shí)現(xiàn)管理員信息添加時,首先判斷客戶端輸入的管理員信息是否合法,然后在將合法的管理員信息保存到管理員信息表中,并同時級聯(lián)插入權(quán)限信息,級聯(lián)插入權(quán)限信息主要通過獲取Access數(shù)據(jù)庫中插入記錄的自動編號實(shí)現(xiàn)的。代碼如下:
例程6-24? 代碼位置:光盤"mr"6"6.3"6.3.3"tjyg.asp
<!--#include file="conn/conn.asp"-->
<%
function filter_Str(InString)
'***********************************
'功能:過濾輸入字符串中的危險符號
'調(diào)用方法:filter_Str("String")
'***********************************
?? NewStr=Replace(InString,"'","''")
?? NewStr=Replace(NewStr,"<","<")
?? NewStr=Replace(NewStr,">",">")
?? NewStr=Replace(NewStr,"chr(60)","<")
?? NewStr=Replace(NewStr,"chr(37)",">")
?? NewStr=Replace(NewStr,"""",""")
?? NewStr=Replace(NewStr,";",";;")
?? NewStr=Replace(NewStr,"--","-")
?? NewStr=Replace(NewStr,"/*"," ")
?? NewStr=Replace(NewStr,"%"," ")
?? filter_Str=NewStr
end function
if request.Form("use")<>"" then
?? use=filter_Str(request.Form("use"))
?? pwd=filter_Str(request.Form("pwd"))
?? '檢測輸入的管理員是否已存在
?? set rs=server.CreateObject("Adodb.recordset")
?? sql="select * from tb_use where use='"&use&"'"
?? rs.open sql,conn,1,3
?? if rs.eof and rs.bof then
?? '通過下面的程序代碼來保存用戶注冊信息
?? rs.addnew()
?? rs("use")=use
?? rs("pwd")=pwd
?? rs.update
?? '獲取Access數(shù)據(jù)庫中插入記錄的自動編號
?? temp=rs.bookmark
?? rs.bookmark=temp
?? id=rs("id")
?? ins1="insert into tb_purview(id,purviewSet,basicSet,stockSet,sellSet,storageSet,querySet,reportSet)values("&id&","&false&","&false&","&false&","&false&","&false&","&false&","&false&")"
?? conn.execute(ins1)
%>
?? <script language="javascript">
?? alert("管理員信息添加成功,繼續(xù)添加!");
?? window.location='tjyg.asp';
?? </script>
?? <%
Else
%>
?? <script language="javascript">
?? alert("該管理員信息已存在!");
?? window.location='tjyg.asp';
?? </script>
<%
end if
end if
%>
顯示管理員列表頁面即權(quán)限管理的主頁面,在該頁面中將顯示所有管理員信息,其中管理員的權(quán)限是以復(fù)選框的形式進(jìn)行顯示,頁面運(yùn)行結(jié)果如圖6.26所示,代碼如下:
例程6-25? 代碼位置:光盤"mr"6"6.3"6.3.3"main.asp
<%
Set rs=Server.CreateObject("Adodb.RecordSet")
sql="select * from tb_use u inner join tb_purview p on u.id=p.id order by u.id asc"
rs.open sql,conn,1,3
if rs.bof and rs.eof then
response.Write("暫無管理員信息!")
else
%>
<table width="696" height="67" border="1" align="center" cellpadding="0" cellspacing="0" bordercolor="#6598CD">
<tr>
<td height="25" bgcolor="#99CDFF">
<div align="center" class="STYLE6">管理員名稱</div>
</td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">權(quán)限管理</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">基礎(chǔ)信息管理</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">進(jìn)貨管理</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">銷售管理</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">庫存管理</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">查詢統(tǒng)計</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">報表管理</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">權(quán)限設(shè)置</div></td>
<td bgcolor="#99CDFF"><div align="center" class="STYLE6">操作</div></td>
</tr>
<%
for i=1 to rs.recordcount
%>
<tr>
<td height="20" bgcolor="#FFFFFF">
<div align="center" class="STYLE6"><%=rs("use")%></div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled"
<%if rs("purviewSet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled" <%if rs("basicSet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled" <%if rs("stockSet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled" <%if rs("sellSet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled" <%if rs("storageSet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled" <%if rs("querySet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF">
<div align="center" class="STYLE6">
<input name="checkbox" type="checkbox" class="noborder" value="checkbox" disabled="disabled" <%if rs("reportSet") then response.write("checked") end if%>>
</div>
</td>
<td bgcolor="#FFFFFF"><div align="center"><span class="STYLE6">
<%
if rs1("purviewSet")=true and rs("use")<>"mr" then
%>
<a href="#" onClick="window.open('qx.asp?id=<%=rs("u.id")%>','','width=292,height=175')"><span class="STYLE9">權(quán)限設(shè)置</span></a>
<%else%>
<span class="STYLE9"> </span>
<%end if%>
</td>
<td bgcolor="#FFFFFF">
<div align="center">
<%if rs1("purviewSet")=true and rs("use")<>"mr" then%>?
<a href="del.asp?id=<%=rs("u.id")%>"><span class="STYLE9">刪除</span></a>
<%
Else
%>
<span class="STYLE9"> </span>
<%
end if
%>
</div>
</td>
</tr>
<%
rs.movenext
if rs.eof then exit for
next
%>
</table>
<%
end if
%>
管理員在進(jìn)行登錄時,首先判斷此管理員是否擁有權(quán)限管理的功能,如果有權(quán)限管理功能,則可以通過單擊某條管理員信息右側(cè)的“權(quán)限設(shè)置”超鏈接即可進(jìn)入到管理員權(quán)限修改頁面,在該頁面中將顯示該管理員的權(quán)限信息,設(shè)置相應(yīng)的信息后,單擊“保存”按鈕即可將管理員的權(quán)限信息保存到數(shù)據(jù)表中;否則將不顯示“權(quán)限設(shè)置”超鏈接。管理員權(quán)限修改頁面的運(yùn)行結(jié)果如圖6.28所示。
圖6.28? 管理員權(quán)限修改頁面的運(yùn)行結(jié)果
通過以下代碼實(shí)現(xiàn)管理員權(quán)限的修改,代碼如下:
例程6-26? 代碼位置:光盤"mr"6"6.3"6.3.3"ok.asp
<!--#include file="conn/conn.asp"-->
<%
if request.Form("Button")="保存" then
?? purviewSet=request.Form("purviewSet")
?? if purviewSet="" then purviewSet=false
?? basicSet=request.Form("basicSet")
?? if basicSet="" then basicSet=false
?? stockSet=request.Form("stockSet")
?? if stockSet="" then stockSet=false
?? sellSet=request.Form("sellSet")
?? if sellSet="" then sellSet=false
?? storageSet=request.Form("storageSet")
?? if storageSet="" then storageSet=false
?? querySet=request.Form("querySet")
?? if querySet="" then querySet=false
?? reportSet=request.Form("reportSet")?
?? if reportSet="" then reportSet=false
?? UP="Update tb_purview set purviewSet="&purviewSet&",basicSet="&basicSet&",stockSet="&stockSet&",sellSet="&sellSet&",storageSet="&storageSet&",querySet="&querySet&",reportSet="&reportSet&" where ID="&session("ID")&""
?? conn.execute(UP)
end if
%>
通過以下代碼實(shí)現(xiàn)管理員信息的刪除,代碼如下:
例程6-27? 代碼位置:光盤"mr"6"6.3"6.3.3"del.asp
<!--#include file="conn/conn.asp"-->
<%
if request.QueryString("id")<>"" then
?? Del="Delete from tb_use where ID="&request.QueryString("id")&""
?? conn.execute(Del)
%>
<script language="javascript">
window.location.href='main.asp';
</script>
<%
end if
%>
3.補(bǔ)充說明
在本方案中實(shí)現(xiàn)管理員信息添加時,首先需要將管理員信息添加到管理員信息數(shù)據(jù)表中,然后需要在權(quán)限信息表中也同時級聯(lián)插入該管理員的權(quán)限信息,實(shí)現(xiàn)級聯(lián)插入管理員權(quán)限信息主要通過獲取Access數(shù)據(jù)庫中插入記錄的自動編號實(shí)現(xiàn)的。下面對該技術(shù)進(jìn)行詳細(xì)介紹。
本方案主要通過Bookmark屬性使用戶對Recordset中的記錄進(jìn)行標(biāo)記,稍后再返回給它。使用Bookmark屬性可以保存當(dāng)前記錄的位置并隨時返回該記錄。Bookmark屬性只能在支持書簽功能的Recordset對象中使用。
打開Recordset對象時,其每個記錄都有唯一的書簽。要保存當(dāng)前記錄的書簽,請將Bookmark 屬性的值賦給一個變量。移動到其他記錄后要快速返回到該記錄時,請將該Recordset對象的 Bookmark屬性設(shè)置為該變量的值。
如果使用Clone方法創(chuàng)建Recordset對象的一個副本,則原始的和復(fù)制的Recordset對象Bookmark屬性設(shè)置相同并可以替換使用。但是無法替換使用不同Recordset對象的書簽,即使這些書簽是通過同一數(shù)據(jù)源或命令創(chuàng)建的。
在客戶端上使用Recordset對象時,Bookmark屬性始終有效。例如以下代碼:
temp=rs.bookmark
rs.bookmark=temp
為了使讀者能夠更好地理解和運(yùn)用該技術(shù),下面將給出一個具體的應(yīng)用方案。在開發(fā)留言板程序時,應(yīng)設(shè)置回復(fù)功能。本方案主要通過Recordset對象中的Bookmark屬性使用戶對Recordset 中的記錄進(jìn)行標(biāo)記,稍后再返回給它。當(dāng)對留言信息進(jìn)行回復(fù)時,回復(fù)的信息將直接與留言信息依依相對應(yīng),就無須在指定回復(fù)留言的ID號。運(yùn)行結(jié)果如圖6.29所示。
圖6.29? 向Access數(shù)據(jù)庫中插入記錄
通過以下代碼實(shí)現(xiàn)數(shù)據(jù)庫的連接,代碼如下:
<%
set conn=server.CreateObject("adodb.connection")
sql="Driver={Microsoft Access Driver (*.mdb)};DBQ=" &server.MapPath("Database/db_database.mdb")
conn.open(sql)
%>
添加表單、文本框和文本域,并設(shè)置其相關(guān)的屬性值,代碼如下:
<form method="post" name="form1">
<input name="title" type="text" class="text" id="title" size="32">
<textarea name="content" cols="30" rows="8" class="text" id="content">
</textarea>
<input name="Submit" type="submit" class="button" value="提交">
<input name="Submit2" type="reset" class="button" value="重置">
</form>
通過以下代碼實(shí)現(xiàn)立即獲取插入記錄的自動編號,代碼如下:
<%
if request.form("title")<>"" then
title=request.form("title")
content=request.form("content")
Set rs=Server.CreateObject("ADODB.Recordset")
sql="select * from tb_sml"
rs.open sql,conn,1,3
rs.addnew()
rs("title")=title
rs("content")=content
rs.update()
temp=rs.bookmark
rs.bookmark=temp
topicID=rs("ID")
ins="insert into tb_back (title_ID) values ("&topicID&")"
conn.execute(ins)
end if
%>
6.5? ASP文件安全技術(shù)方案
使用瀏覽器的“查看源文件”功能只可以查看IIS服務(wù)器編譯后的HTML標(biāo)簽和JavaScript等客戶端腳本,但使用迅雷等下載工具就可以將ASP源文件下載到本地,如果不對ASP文件加密,所有站點(diǎn)源文件將被竊取,這樣不僅不利于維護(hù)網(wǎng)站的版權(quán),而且會給站點(diǎn)的安全帶來很大的隱患。本節(jié)將介紹如何對ASP文件進(jìn)行加密。
6.5.1? 應(yīng)用Script Encoder加密工具
Script Encoder是Microsoft推出的一個script加密工具,它是一個簡單的命令行工具,可以對html文件進(jìn)行加密,只是對其中的VBscript部分進(jìn)行加密處理,其他的文本部分均保持不變,加密后對script的功能并無影響,僅是其代碼變成密文,用源文件方式查看只是一些亂碼。該程序除了可對html文件加密外,也可以對asa、asp、cdx、js、sct、vbs文件進(jìn)行加密。該程序很小只有64K,使用非常簡單,在DOS命令行下執(zhí)行,也可在Windows下帶參數(shù)運(yùn)行。
1.方案分析
應(yīng)用Script Encoder對asp文件進(jìn)行加密,首先依次單擊“開始”→“程序”→“附件”→“命令提示符”,在MS-DOS命令行中輸入以下命令,即可對某asp文件進(jìn)行加密,加密格式如下:
SCRENC? [switches]? <要加密asp文件名>? <加密后的文件名>
在SRCENC命令中應(yīng)用到了switches選項,該選項的常用參數(shù)如下所示,下面對常用的屬性進(jìn)行詳細(xì)說明:
/s 可選。命令中帶了該參數(shù),加密過程中屏幕上就不會有輸出。screnc /s lacl.sct ulacl.sct對當(dāng)前目錄中的腳本小程序lacl.sct加密,加密過程中屏幕不顯示任何信息。
/f 可選。指定輸出文件是否覆蓋同名輸入文件。忽略,將不執(zhí)行覆蓋。screnc /f lacl.asp對文件lacl.asp加密,并用編碼后的同名文件覆蓋原文件。
/xl 可選。是否在asp文件的頂部添加@Language指令。忽略,將添加。
/l defLanguage 可選。指定Script Encoder加密中選擇的缺省腳本語言。文件中不包含這種腳本語言特性的腳本將被Script Encoder 忽略。
對于HTML文件,JScript為內(nèi)置缺省腳本語言;對于ASP文件,VBScript為缺省腳本語言;對于擴(kuò)展名為.vbs或.js的文件,Script Encoder也有適應(yīng)能力。screnc /l vbscript lacl.htm ulacl.htm對文件lacl.htm加密,并生成輸出文件ulacl.htm,確保沒有指定語言屬性的腳本使用VBScript。
/e defExtension 可選。指定待加密文件的文件擴(kuò)展名。缺省狀態(tài)下,Script Encoder能識別asa、asp、cdx、htm、html、js、sct和vbs文件。screnc /e asp 11\*.* f:\labxw-jm對11目錄中的所有.ASP 文件進(jìn)行加密,并把編碼后的輸出文件放在f:\labxw-jm目錄中。
2.實(shí)施過程
? 實(shí)例位置:光盤\mr\6\6.5\6.5.1
Script Encoder加密工具可以對asp、html、asa、cdx、sct和vbs等文件進(jìn)行加密。下面將使用Script Encoder加密工具對index.asp進(jìn)行加密,其中index.asp加密前的內(nèi)容如圖6.40所示。
具體步驟如下:
(1)安裝Script Encoder加密工具到目錄c:\test下。
(2)把需要加密的ASP文件也拷到目錄c:\test下。
(2)依次選擇“開始”→“程序”→“附件”→“命令提示符”。
(3)在“命令提示符”對話框中,首先轉(zhuǎn)換到目錄c:\test(即輸入命令 cd c:\test)下,然后再C盤中建立test1文件夾,文件夾建立完成后并輸入以下代碼即可:
screnc *.asp c:\test1
最后應(yīng)該得到如下代碼:
C:\test>screnc *.asp c:\test1
通過Script Encoder加密工具對index.asp文件進(jìn)行加密后的結(jié)果如圖6.41所示。
圖6.40? 加密前的文件
圖6.41? 加密后的文件
3.補(bǔ)充說明
通過本方案的學(xué)習(xí),讀者可以很輕松地對指定的ASP文件進(jìn)行加密,還可以對html文件進(jìn)行加密,但是不能對JavaScript腳本語言進(jìn)行加密處理。
6.5.2? 將ASP文件轉(zhuǎn)換成HTML文件
對ASP文件進(jìn)行加密,除了使用Script Encoder加密工具外,還可以將ASP文件轉(zhuǎn)換為HTML格式的文件。下面將對ASP文件轉(zhuǎn)換為HTML文件的具體實(shí)現(xiàn)過程進(jìn)行分析和說明。
1.方案分析
首先通過Microsoft.XMLHTTP方法可以獲取到asp文件中信息內(nèi)容的二進(jìn)制數(shù)據(jù),然后再通過ADO的Stream對象將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為字符串,最后將獲取到的數(shù)據(jù)寫入到html文件中。
2.實(shí)施過程
? 實(shí)例位置:光盤\mr\6\6.5\6.5.2
在開發(fā)動態(tài)網(wǎng)站時,應(yīng)考慮到隨著網(wǎng)站訪問量的不斷增多,服務(wù)器的承載壓力也會越來越大。如果將asp文件轉(zhuǎn)換成html文件,既可以減輕服務(wù)器的承載壓力和提高網(wǎng)站的瀏覽速度,又可以保證asp文件的源代碼不被泄漏,從而達(dá)到提高asp文件安全性的目的,如圖6.42所示。
圖6.42? 將ASP文件轉(zhuǎn)換成HTML文件的運(yùn)行結(jié)果
運(yùn)行本實(shí)例,如圖6.42所示,首先在圖中的文本框中輸入要轉(zhuǎn)換成html格式的asp文件的地址,然后單擊“提交”按鈕即可實(shí)現(xiàn)將asp格式文件轉(zhuǎn)換為html格式,實(shí)現(xiàn)該過程的關(guān)鍵代碼如下:
例程6-29? 代碼位置:光盤\mr\6\6.5\6.5.2\index.asp
<%
Function GetContent(url)?
'獲取文件內(nèi)容
? Dim XMLObj
? Set XMLObj = CreateObject("Microsoft.XMLHTTP")
? With XMLObj
?? .Open "Get", url, False
?? .Send
?? GetContent=BytesToBstr(.ResponseBody)
? End With?
End Function
Function BytesToBstr(info)?
'將二進(jìn)制轉(zhuǎn)換為字符串
?dim objstream
?set objstream = Server.CreateObject("adodb.stream")
?objstream.Type = 1
?objstream.Mode =3
?objstream.Open
?objstream.Write info
?objstream.Position = 0
?objstream.Type = 2
?objstream.Charset = "GB2312"
?BytesToBstr = objstream.ReadText
?objstream.Close
?set objstream = nothing
End Function
If Request.Form("url")<>"" Then
on error resume next
Url=Request.Form("url")?
'需要注意的是這里的URL指定為您要讀取的頁面地址
'開始獲取/更新頁面...
wstr = GetContent(Url)
'生成html文檔
Set FSO=Server.CreateObject("Scripting.FileSystemObject")
htmPath=server.MapPath("index.htm")
If (FSO.FileExists(htmPath)) Then
? FSO.DeleteFile(htmPath)
End If
Set TSobj=FSO.CreateTextFile(htmPath)
TSobj.Writeline(wstr)
set TSobj=nothing
set FSO=nothing
If err<>0 Then
? Response.Write("<script language='javascript'>alert('操作失敗,未能生成HTML文件!');window.location.href='index.asp';</script>")
? Response.End()
Else
? Response.Redirect("index.htm")
End If
End If
%>
3.補(bǔ)充說明
將asp格式的文件轉(zhuǎn)換為html格式,即可以有效地提高服務(wù)器端的速度,而且還可以在很大程度上提高站點(diǎn)的安全性。
轉(zhuǎn)載于:https://www.cnblogs.com/jiania1224/archive/2009/04/01/1426810.html
總結(jié)
以上是生活随笔為你收集整理的asp 与 database (3)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vmware, failed to lo
- 下一篇: php中计算时间差的几种方法,PHP 中