Posts Tagged ‘组件’

ASP.NET中根据XML动态创建使用WEB组件

星期二, 06月 3rd, 2008

前段时间笔者在开发中需要动态创建WEB组件,本以为是小事一桩,谁知看时容易做时难.里面还真有些小问题.下面笔者就结合自己de程序来介绍一下如何动态创建并使用WEB组件,希望能给做类似工作de朋友提供一点帮助.
一、程序思路
程序主要分三部分:
1、程序要根据XML中de数据信息确定需要创建deWEB组件de个数.
2、动态创建WEB组件.
3、使用动态创建deWEB组件.
其中2和3是笔者要重点介绍de部分.
下面笔者就按照这三部分结合程序实例(以c#为例)来一一介绍.
二、读取XML文件
读取XML文件在很多de资料中都有详细de说明,而且相信很多朋友都已经很好de掌握了其技术.但为了保证文章de完整性,笔者在这里还是要赘述几句.深谐其味de朋友可以略过此段不看.
笔者程序中要读取deXML文件形如下列:
config.xml
<?xml version=”1.0″?>
<Root>
<Nettype>net</Nettype>
<Totalnum>6</Totalnum>
<Cells>2</Cells>
<IPlink>
<Name>站点1</Name>
<IP>192.8.198.1</IP>
<Sequence>1</Sequence>
</IPlink>
<IPlink>
<Name>站点2</Name>
<IP>192.8.198.2</IP>
<Sequence>2</Sequence>
</IPlink>
… …
</Root>
读取XML文件de程序如下:
protected void readconfig()
{
try
{
System.Xml.XmlDocument mXmlDoc=new System.Xml.XmlDocument();
mXmlDoc.Load(Server.MapPath(configfilepath));
nettype=mXmlDoc.SelectNodes(”//Root/Nettype”)[0].InnerText; totalnum=int.Parse(mXmlDoc.SelectNodes(”//Root/Totalnum”)[0].InnerText);
//读出列数
cells=int.Parse(mXmlDoc.SelectNodes(”//Root/Cells”)[0].InnerText);
XmlNodeList mXmlNodes=mXmlDoc.SelectNodes(”//Root/IPlink”);
foreach(XmlNode IPlinkchildlNode in mXmlNodes)
{
//得到序列号
int icount=int.Parse(IPlinkchildlNode.ChildNodes[2].InnerText);
//根据序列号,将测量点de名称放入名称数组相应de位置上
namestr[icount]=IPlinkchildlNode.ChildNodes[0].InnerText;
//根据序列号,将测量点deIP放入IP数组相应de位置上
ipstr[icount]=IPlinkchildlNode.ChildNodes[1].InnerText;
}
}
catch
{
errmessage.InnerHtml=”<table align=center><tr>
<td align=left><font color=red>不能读取配置文件,可能de错误是<br>” “1、配置文件不存在<br>”
“2、配置文件内容被损坏”
“</font></td></tr></table>”;
}
}
程序中对XML中无子节点de元素如:
<Nettype>net</Nettype>
直接使用如下语句读取.
mXmlDoc.SelectNodes(”//Root/Nettype”)[0].InnerText;
对于有子节点de元素如:
<IPlink>
<Name>站点1</Name>
<IP>192.8.198.1</IP>
<Sequence>1</Sequence>
</IPlink>
要使用语句如下来读取.
IPlinkchildlNode.ChildNodes[N].InnerText
其中 ChildNodes[N] 中de[N]为子节点de序号,子节点
<Name>站点1</Name>
de序号应该为[0].

三、动态创建WEB组件.
先来看程序实例:
private void createconfigtable(int totalnum,int[] sequenceint,string[] namestr,string[] ipstr)
{
//根据得到测量点de总数,动态生成输入框
for(int i=1;i<=totalnum;i )
{
//创建表格
HtmlTable showtable = new HtmlTable();
showtable.Border=0;
showtable.ID=”showtable” i.ToString();
showtable.BorderColor=”#000000″;
showtable.CellPadding=4;
showtable.CellSpacing=4;
showtable.Align=”center”;
myPlaceHolder.Controls.Add(showtable);
//创建一行
HtmlTableRow tRow = new HtmlTableRow();
showtable.Rows.Add(tRow);
//创建第一列(序号)
HtmlTableCell tCell = new HtmlTableCell();
Label sequenceLabel = new Label();
sequenceLabel.ID=”sequenceLabel” i.ToString();
sequenceLabel.Text=”序号:”;
sequenceLabel.Enabled=true;
tCell.Controls.Add(sequenceLabel);
tRow.Cells.Add(tCell);
//创建第二列
tCell = new HtmlTableCell();
sequencedataTB = new TextBox();
sequencedataTB.ID=”sequencedataTB” i.ToString();
sequencedataTB.Text=i.ToString();
sequencedataTB.Width=30;
sequencedataTB.Text=sequenceint[i].ToString();
sequencedataTB.ReadOnly=false;
//创建第三列(名称)
tCell = new HtmlTableCell();
Label nameLabel = new Label();
nameLabel.ID=”nameLabel” i.ToString();
nameLabel.Text=”名称:”;
nameLabel.Enabled=true;
tCell.Controls.Add(nameLabel);
tRow.Cells.Add(tCell);
//创建第四列
tCell = new HtmlTableCell();
nameTB=new TextBox();
nameTB.ID=”nameTB” i.ToString();
nameTB.Width=120;
nameTB.Text=namestr[i];
nameTB.MaxLength=50;
tCell.Controls.Add(nameTB);
tRow.Cells.Add(tCell);
//创建第五列(IP)
tCell = new HtmlTableCell();
Label ipLabel = new Label();
ipLabel.ID=”ipLabel” i.ToString();
ipLabel.Text=”IP:”;
ipLabel.Enabled=true;
tCell.Controls.Add(ipLabel);
tRow.Cells.Add(tCell);
//创建第六列
tCell = new HtmlTableCell();
ipTB=new TextBox();
ipTB.ID=”ipTB” i.ToString();
ipTB.Width=120;
ipTB.Text=ipstr[i];
ipTB.MaxLength=15;
tCell.Controls.Add(ipTB);
tRow.Cells.Add(tCell);
}
}
tCell.Controls.Add(sequencedataTB);
tRow.Cells.Add(tCell);
… …
//创建第五列(IP)
tCell = new HtmlTableCell();
Label ipLabel = new Label();
ipLabel.ID=”ipLabel” i.ToString();
ipLabel.Text=”IP:”;
ipLabel.Enabled=true;
tCell.Controls.Add(ipLabel);
tRow.Cells.Add(tCell);
//创建第六列
tCell = new HtmlTableCell();
ipTB=new TextBox();
ipTB.ID=”ipTB” i.ToString();
ipTB.Width=120;
ipTB.Text=ipstr[i];
ipTB.MaxLength=15;
tCell.Controls.Add(ipTB);
tRow.Cells.Add(tCell);
}
}
程序中demyPlaceHolder 是 System.Web.UI.WebControls.PlaceHolder 组件,使用该组件deHTML语法如下:
… …
<tr>
<td>
<asp:PlaceHolder id=”myPlaceHolder” runat=”server”></asp:PlaceHolder>
</td>
</tr>
… …
使用该组件de目de是为了定位动态创建de表格.该组件在页面上de位置即为动态创建de表格de位置.
程序中另外一个要说明de地方是动态创建de组件deIDde设定.组件deIDde设定要注意两点:
1、ID号不能重复
2、要便于在程序中使用.因为要在程序中使用动态创建de组件,要通过该组件deID来查找.(关于这一点,在“使用动态创建deWEB组件”部分会有较为详细de介绍)

EJB组件与可重用性的矛盾

星期一, 06月 2nd, 2008

EJB技术正在像其他辉煌过de技术一样走到了一个关口.2000年以前这项技术充满了传奇色彩,被大批企业不假思索地接受.然而理想毕竟是理想,经过了几年de发展,今天这项技术却正在被怀疑或者至少说让技术人员犹豫不决,现实de是J2EEde对手出来了,.NET似乎又有着后发de技术优势.大部分de探讨和争论已经开始转向这两个体系结构de对比.Java阵营内部同样发出了怀疑de声音,最直接de就是对EJBde攻击,因为人们发现原来这项技术所做de承诺似乎都走向了相反de方向
  1.大量de案例由于采用了这种技术反而使得系统开发日趋复杂,而不是想像de简化开发周期加长成了家常便饭,实现一个进销存就把很多人难倒.
  2. EJB成了昂贵de代名词,而不是期望de成本降低
  3. 废了半天劲还不如用消息传递进行系统互操作
  4. 最终发现彻底地摆脱平台是不可能de
  但是Java总归还是不错de,于是有了Spring等等N种体系.EJB开始让人们困惑.任何技术和人生一样有它de困惑期,但是EJB给人们de困惑尤为经典,更具意义.J2EE和其他体系de对比已经泛滥于网上,实际应用de经验也随处可见,以至于不需要这里介绍,但是EJB现在并未被单独地被重视这是应该值得注意de,这与J2EE发展史却是背道而驰de.必须承认这么一个事实,EJB是被单独提出和定义de,最早是完全单独de一种规范,这与所谓体系结构并没有直接de关系,或者说EJBde意义和目标绝不只是在J2EE内封装商业逻辑,所以过于在框架内讨论EJB,或者说认为J2EEde弱点一定要蔓延到EJB上是否合适是值得探讨de.
  EJB诞生de初期人们de兴奋关键在于这种模型吸收了以往组件技术de精华,并有很大发展,使人们看到了强健de商业组件制造成本降低de期望,特别是跨越平台de可装配性和移植性,这是软件工程界一直de梦想,因为这意味着企业端计算程序设计工业化和细致分工也许要成为可能.这种思想目前也影响了界面一级de应用,例如所谓dePortlet技术,IBM公司deWebSphere平台de技术也许不是可怕de,但是有几十个合作伙伴事实上给它提供了类似de合作,这才真正是让对手感到害怕de.因此我谈论EJBde时候,谈论它de价值和作用,脱离了它de设计目标也就失去了更大de意义,以下de商业环境和软件技术瓶颈应该重新被审视:
  1. 软件工程就重用领域来讲是否超越了组件时代,或者说已经不需要组件了?
  2. 软件de重用是否只需要互调用而不需要重复装配,乃至装配到不同de部位?
  3. 商业逻辑是否仍然需要封装,并保持强健de特性,不间断地服务
  4. 组件和强健和可用性是互联特性能取代de吗?
  5. 是否有更廉价de组件形式超越EJB并同样获得众多de支持?
  6. .NETde组件标准和EJB是否有可比性,或者说什么组件形式和EJB才有可比性?
  当冷静地思考de时候就知道,技术不应该被当作明星吹捧,但同样也没有容易倒下de软件技术.EJB不成熟,但不等于可以轻易被否定.是EJB使得很多普通de程序员能够介入原来贵族似de组件开发,甚至是简单deWindows上面开发UNIX上de组件,EJBde历史问题大多数在于将这种技术错误地滥用:一个浏览人数少de可怜广告浏览程序也要用组件,对于一个只想简单算出库存de客户设计了所谓N年后才需要de扩展性.同样现实中在这一技术擅长de领域,至少目前还无法找到更强大de竞争者.技术选择是应用型de技术人员永恒de主题,类似de困惑会不断de出现,最重要de是认同它们de理想和目标,保持对它们客观清醒de认识.放到擅长de领域de技术才是最优美de,这和人生没有什么两样.

在jsp程序中使用com组件

星期一, 06月 2nd, 2008

  在jsp程序中使用com组件de机会并不多,jsp也没有直接操作comde函数,但有de工作有时候还必须使用com组件来完成,下面就来说一下具体de操作方法.
  在jsp中使用com组件有两种方法:一种是用javascript在客户端来控制(严格说这个应该是htmlde功能),如:

  <OBJECT id=”myCom” classid=”clsid:9D8A2E2F-D38F-CDAC-D0C5-5B3FB2275442″ codebase=”.com/com.cab#version=1.9.9.0″ >
  </OBJECT>
  <script>
  function Hello() {
  var result= myCom.Hello(“李宗斌“);
  return result;
  }
  </scipt>

  结果返回:您好,李宗斌

  但是这种方法有个弊端就是只能在客户端操作,不能操作服务器端de东西.而且每个客户端都要安装这个组件才能运行.
  第二种是直接用jsp通过Java-COM连接桥JACOB来操作服务器端decom组件.JACOBde下载地址是http://danadler.com/jacob/.运行de时候需要两个文件:jacob.jar和jacob.dll.
  配置de方法是:把jacob.jar放到CLASSPATH里,把jacob.dll所在de路径加到path里.如d:\com

  使用de方法如下:

  1.先在服务器端注册com组件;
  2.找到组件de名字(一般应该是知道de,不知道de话就到注册表中去找);
  3.程序示例:

  <%@ page contentType=”text/html; charset=gb2312″ language=”java” %>
  <%@ page import=”com.jacob.com.*” %>
  <%@ page import=”com.jacob.activeX.*” %>
  <%
  System.runFinalizersOnExit(true);
  ActiveXComponent mf = new ActiveXComponent(”MakerCom.MakerExt”);//找到组件
  Object myCom = mf.getObject();//生成一个对象
  String result= Dispatch.call( myCom, “Hello”, new Variant( “李宗斌”) ) ;
  /*调用组件de方法,myCom是组件de对象名,Hello是组件de函数,new Variant( “李宗斌”) 是组件de参数变量,如果有多个可以在后边加上,方法一致*/
  out.println(result);
  %>

JSP的9种基本内置组件

星期一, 06月 2nd, 2008

来源:网友提供如有版权问题请与我联系

基本组件

JSP共有以下9种基本内置组件(可与ASPde6种内部组件相对应):
request 用户端请求,此请求会包含来自GET/POST请求de参数
response 网页传回用户端de回应
pageContext 网页de属性是在这里管理
session 与请求有关de会话期
application servlet正在执行de内容
out 用来传送回应de输出
config servletde构架部件
page JSP网页本身
exception 针对错误网页,未捕捉de例外

您可以使用它们来存取执行JSP相关代码deservlet. 为了避免谈论到太多Servlet API de细节,让我来检视一些您可以利用它们来做de事:
不必使用运算式,您可以直接存取内部out物件来列印一些东西到response:
<% out.println("Hello"); %>
不必直接传送参数到JavaBean,您可以按照请求部件来取得参数de值:
<% String name=request.getParameter("name");
out.println(name); %>.
等等.
以下着重介绍session对象.
  会话状态维持是 Web 应用开发者必须面对de问题.有多种方法可以用来解决这个问题,如使用 Cookies 、隐藏de表单输入域,或直接将状态信息附加到 URL 中.Java Servlet 提供了一个在多个请求之间持续有效de会话对象,该对象允许用户存储和提取会话状态信息.JSP也同样支持Servlet中de这个概念.
  在 Sun de JSP 指南 中可以看到许多有关隐含对象de说明(隐含de含义是,这些对象可以直接引用,不需要显式地声明,也不需要专门de相关代码创建其实例).例如 request 对象,它是 HttpServletRequest de一个子类.该对象包含了所有有关当前浏览器请求de信息,包括 Cookies , HTML 表单变量等等. session 对象也是这样一个隐含对象.这个对象在第一个 JSP 页面被装载时自动创建,并被关联到 request 对象上.与 ASP 中de会话对象相似, JSP 中de session 对象对于那些希望通过多个页面完成一个事务de应用是非常有用de.
   为说明 session 对象de具体应用,接下来我用三个页面模拟一个多页面de Web 应用.第一个页面( q1.html )仅包含一个要求输入用户名字de HTML 表单,相关代码如下:
  < HTML>
  < BODY>
  < FORM METHOD=POST ACTION="q2.jsp">
 请输入您de姓名:
  < INPUT TYPE=TEXT NAME="thename">
  < INPUT TYPE=SUBMIT VALUE="SUBMIT">
  < /FORM>
  < /BODY>
  < /HTML>
   第二个页面是一个 JSP 页面( q2.jsp ),它通过 request 对象提取 q1.html 表单中de thename 值,将它存储为 name 变量,然后将这个 name 值保存到 session 对象中. session 对象是一个名字 / 值对de集合,在这里,名字 / 值对中de名字为“ thename ”,值即为 name 变量de值.由于 session 对象在会话期间是一直有效de,因此这里保存de变量对后继de页面也有效. q2.jsp de另外一个任务是询问第二个问题.下面是它de相关代码:
  < HTML>
  < BODY>
  < %@ page language="java" %>
  < %! String name=""; %>
  < %
  name = request.getParameter("thename");
  session.putValue("thename", name);
  %>
 您de姓名是: < %= name %>
  < p>
  < FORM METHOD=POST ACTION="q3.jsp">
 您喜欢吃什么 ?
  < INPUT TYPE=TEXT NAME="food">
  < P>
  < INPUT TYPE=SUBMIT VALUE="SUBMIT">
  < /FORM>
  < /BODY>
  < /HTML>
   第三个页面也是一个 JSP 页面( q3.jsp ),主要任务是显示问答结果.它从 session 对象提取 thename de值并显示它,以此证明虽然该值在第一个页面输入,但通过 session 对象得以保留. q3.jsp de另外一个任务是提取在第二个页面中de用户输入并显示它:
  < HTML>
  < BODY>
  < %@ page language="java" %>
  < %! String food=""; %>
  < %
  food = request.getParameter("food");
  String name = (String) session.getValue("thename");
  %>
 您de姓名是: < %= name %>
  < P>
 您喜欢吃: < %= food %>
  < /BODY>
  < /HTML>

利用PHP实现与ASP Banner组件相似的类

星期一, 06月 2nd, 2008

<?php
/*******************************************************
作者: 吴振亨 (Biz)–phpscript
E-mail:wuzhenheng@china.com
web: http://phpscript.osh.com.cn
文件名:AdRotator.class.php3
版权声明:
如果您使用了本文件,请给作者写一封E-mail
如有问题欢迎与作者联系
谢谢您de关注!
********************************************************/
/*
广告条管理程序
public method
GetAdvertisement($adfile)
parameters
Target=
Width=
Height=
Border=
Redirect=
*/
class AdRotator {
var $Target="_blank";
var $Width="460";
var $Height="60";
var $Border=0;
var $Redirect="";
var $BannerData=array ();
var $RandTemp=1;
function AdRotator()
{
}
/*
public
返回广告de链接字串
*/
function GetAdvertisement($adfile)
{
if(count($this->BannerData)==0)
{
$this->BannerData=$this->ReadAdFile($adfile);
}
$AdData=$this->BannerData;
$uplimited=count($AdData);
//随机产生一个ID
srand((double)microtime()*1000000000000000000);
$id=@rand(1,$uplimited);
while($this->RandTemp==$id)
{
srand((double)microtime()*1000000000000000000);
//$id=@rand(1,count($AdData));
$id=@rand(1,$uplimited);
}
$this->RandTemp=$id;
//echo $id;
//echo count($AdData);
//echo $AdData[5]["image"];

$LinkString=" <a href="".$this->Redirect;
$LinkString.="?url=".$AdData[$id]["url"];
$LinkString.="" Target="".$this->Target;
$LinkString.="" Title="".$AdData[$id]["title"];
$LinkString.="" >";
$LinkString.=" <img border="".$this->Border;
$LinkString.="" src="".$AdData[$id]["image"];
$LinkString.="" width="".$this->Width;
$LinkString.="" height="".$this->Height;
$LinkString.="" >";
$LinkString.="</a>";
//echo $LinkString;
return $LinkString;
}
/*
private
读入文件de基本设置
*/
function ReadAdFile($adfile)
{
$FP=fopen($adfile,"r");
while($buffer=@fgets($FP,1024))
{
if(!eregi("#",$buffer))
{
if(eregi("^*",$buffer))
{
$switchto="off";
}
$SetTemp=split("=",$buffer);
if($switchto=="")
{
switch ($SetTemp[0])
{
case "REDIRECT":
$this->Redirect=$SetTemp[1];
break;
case "WIDTH":
$this->WIDTH=$SetTemp[1];
break;
case "HEIGHT":
$this->HEIGHT=$SetTemp[1];
break;
case "BORDER":
$this->BORDER=$SetTemp[1];
break;
case "TARGET":
$this->Target=$SetTemp[1];
break;
}
}
else
{
switch ($SetTemp[0])
{
case "image":
$i ;
$BannerData[$i]["image"]=$SetTemp[1];
//echo "<br>";echo $buffer;echo $SetTemp[1];
//echo $BannerData[$i]["image"];
break;
case "url":
$BannerData[$i]["url"]=$SetTemp[1];
break;
case "title":
$BannerData[$i]["title"]=$SetTemp[1];
break;
case "rate":
$BannerData[$i]["rate"]=$SetTemp[1];
break;
}//end of switch
}//end of if($switch)
}//end of if(#)
}//end of while
return $BannerData;
}//end of function
}//end of class
/*
使用方法
广告设置文件书写格式banner.txt
——开始—
REDIRECT=./adredir.asp
WIDTH=468
HEIGHT=60
BORDER=0
*
#注释
#某某公司广告1
image=../banner/1.gif
url=http://www.asps0ite.com1
title=One
rate=30
—-结束—–
说明:
与ASPde广告组件相仿
*表示设置,其他为图片de设置 #:表示注释
—-使用—–
$banner=new AdRotator();
echo $banner->GetAdvertisement("./banner.txt");
echo $banner->GetAdvertisement("./banner.txt");
echo $banner->GetAdvertisement("./banner.txt");
*/
?>
【本文版权归作者与奥索网共同拥有,如需转载,请注明作者及出处】

asp水印组件之AspJpeg的结合代码实例

星期一, 06月 2nd, 2008

1、什么是AspJpeg?
AspJpeg是一款功能强大de基于Microsoft IIS环境de图片处理组件,网络上对其进行详细和深入介绍de中文文章并不多,即使有一般也只是牵涉到图片缩略图和图片水印,这与其为英文版本有着密切de关系.
AspJpeg可以使用很少de相关代码在您deASP/ASP.Net应用程序上动态de创建高质量de缩略图象,支持de图象格式有:JPEG, GIF, BMP, TIFF, PNG
AspJpeg主要可以做到:
生成缩略图片
生成水印图片
图片合并
图片切割
数据库支持
安全码技术
2、AspJpeg功能摘要
支持JPEG, GIF, BMP, TIFF 和 PNG 格式图片. 输出格式始终为 JPEG
源图片可以来源于磁盘、内存、或者记录集(数据库)
缩略图片可以保存到磁盘、内存、或者HTTP流
支持三种更改大小方式: nearest-neighbor, bilinear, and bicubic.
可以在图片之上添加图片或者文字.
支持画中画
支持复制,反转,旋转,锐化,灰度调节.
可以调节压缩比率,以得到最佳输出效果和大小.
从Jpeg图片中抽取EXIF 和 IPTC数据.
CMYK-RGB转换
Read/write access to individual pixels of an image. (从图象中对任意象素进行读/写存取.)
3、AspJpeg系统需求
Windows 95/98/NT/2000/XP/2003, and
IIS 4.0 and ASP/ASP.NET, or
Visual Basic 5.0 , or
Visual C 5.0 , or
any development environment supporting COM.
4、AspJpeg安装
全新安装:
在AspJpeg安装过程中输入序列号即可,如果安装位置磁盘格式为NTFS,则可能出现访问权限问题,需手工设置安装目录对Everyone有访问权限.
更新安装:
如果之前有装过其它版本deAspJpeg组件,则需要先卸载原来de组件,再进行新版本de安装.
先停止IIS
Net Stop iisadmin /y
卸载旧版组件
regsvr32 /u Path/aspjpeg.dl(Path为安装路径)
重启IIS
Net Start w3svc
然后再进行全新安装或复制AspJpeg.dll文件到安装目录进行手工安装:
regsvr32 Path/aspjpeg.dll(Path为安装路径)
如果在正常安装过程中没有输入序列号或手工安装则必须在注册表中加入以下项,为方便起见您可以直接将以下相关代码保存为.reg文档并导入注册表:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Persits Software\AspUpload3\RegKey]
@=”21764-40765-60456″

5、如何创建一个AspJpeg实例?
Set Jpeg = Server.CreateObject(”Persits.Jpeg”)

6、如何查看到期时间(是否注册成功)?
Set Jpeg = Server.CreateObject(”Persits.Jpeg”)
Response.Write Jpeg.Expires

注册成功则到期时间为:9999-9-9
否则为:安装日期加1个月期限
7、如何用AspJpeg组件生成图片缩略图?
<%
Set Jpeg = Server.CreateObject(”Persits.Jpeg”) ‘创建实例
Path = Server.MapPath(”../images/apple.jpg”) ‘处理图片路径
Jpeg.Open Path ‘打开图片
‘调整宽度和高度为原来de50%
Jpeg.Width = Jpeg.OriginalWidth / 2
Jpeg.Height = Jpeg.OriginalHeight / 2
Jpeg.Save Server.MapPath(”apple_small.jpg”) ‘保存图片到磁盘
Jpeg.Close:Set Jpeg = Nothing
%>

8、如何用AspJpeg组件生成图片水印?
<%
Set Jpeg = Server.CreateObject(”Persits.Jpeg”)
Jpeg.Open Server.MapPath(”images/dodge_viper.jpg”)
开始写文字
Jpeg.Canvas.Font.Color = &000000” red 颜色
Jpeg.Canvas.Font.Family = “Courier New” 字体
Jpeg.Canvas.Font.Bold = True 是否加粗
Jpeg.Canvas.Print 10, 10, “Copyright (c) XYZ, Inc.”
打印坐标x 打印坐标y 需要打印de字符
以下是对图片进行边框处理
Jpeg.Canvas.Pen.Color = &H000000” black 颜色
Jpeg.Canvas.Pen.Width = 2 画笔宽度
Jpeg.Canvas.Brush.Solid = False 是否加粗处理
Jpeg.Canvas.Bar 1, 1, Jpeg.Width, Jpeg.Height
起始X坐标 起始Y坐标 输入长度 输入高度
Jpeg.Save Server.MapPath(”images/dodge_viper_framed.jpg”) 保存
%>

9、如何用AspJpeg组件进行图片合并?
AspJpeg 1.3 enables you to place images on top of each other via the method DrawImage. To use this method, you must create two instances of the AspJpeg objects and populate both of them with images via calls to Open (or OpenBinary). When calling Canvas.DrawImage, the 2nd instance of AspJpeg is passed as an argument to this method, along with the X and Y offsets (in pixels):
使用该方法,您必需创建两个AspJpeg实例对象
<%
Set Jpeg1 = Server.CreateObject(”Persits.Jpeg”)
Set Jpeg2 = Server.CreateObject(”Persits.Jpeg”)
Jpeg1.Open Server.MapPath(”t.jpg”)
Jpeg2.Open Server.MapPath(”t1.jpg”)
Jpeg1.Canvas.DrawImage 10, 10, Jpeg2 ‘ optional arguments omitted
jpeg1.save Server.mappath(”tt.jpg”)
%>

10、如何用AspJpeg组件进行图片切割?
AspJpeg 1.1 is also capable of cutting off edges from, or cropping, the resultant thumbnails via the method Crop(x0, y0, x1, y1). The size of the cropped image is specified by the coordinates of the upper-left and lower-right corners within the resultant thumbnail, not the original large image.
<%
Set Jpeg = Server.CreateObject(”Persits.Jpeg”)
Jpeg.Open Server.MapPath(”t.jpg”)
jpeg.Crop 20, 30, jpeg.Width - 20, jpeg.Height - 10
jpeg.save Server.mappath(”tt.jpg”)
Response.write(”<img src=tt.jpg>”)
%>

11、如何用AspJpeg组件创建安全码?
创建安全码原理上和创建水印差不多.
<%
function make_randomize(max_len,w_n) ‘max_len 生成长度,w_n:0 可能包含字母,1:只为数字
randomize
for intcounter=1 to max_len
whatnext=int((1-0 1)*rnd w_n)
if whatnext=0 then
upper=122
lower=97
else
upper=57
lower=48
end if
strnewpass=strnewpass & chr(int((upper-lower 1)*rnd) lower)
next
make_randomize=strnewpass
end function
‘生成安全码de图片.
random_num=make_randomize(4,1) ”生成4位数字de安全码
session(”random_num”)=random_num ‘为么调用session,没有sessionde安全码是完全没有意义de.呵呵 .
Set Jpeg = Server.CreateObject(”Persits.Jpeg”) ‘调用组件
Jpeg.Open Server.MapPath(”t.jpg”) ‘打开准备de图片
Jpeg.Canvas.Font.Color = &HFFFFFF
Jpeg.Canvas.Font.Family = “Arial Black”
Jpeg.Canvas.Font.Bold = false
Jpeg.Canvas.PrintText 0, -2, random_num
jpeg.save Server.MapPath(”tt.jpg”) ‘保存
%>
<img src=”tt.jpg” border=”0″ align=”absmiddle”>

12、如何让AspJpeg组件支援数据库?
图片存进数据库只能以二进制数据保存,这里即利用AspJpegdeBinary方法,下面以两个AspJpeg用户手册上de相关代码为例,具体请参考AspJpeg用户手册:
Opening Images from Memory
<% ‘ Using ADO, open database with an image blob
strConnect = “DRIVER={Microsoft Access Driver (*.mdb)};DBQ=” & Server.MapPath(”../db/aspjpeg.mdb”)
Set rs = Server.CreateObject(”adodb.recordset”)
SQL = “select image_blob from images2 where id = ” & Request(”id”)
rs.Open SQL, strConnect, 1, 3
Set Jpeg = Server.CreateObject(”Persits.Jpeg”)
‘ Open image directly from recordset
Jpeg.OpenBinary rs(”image_blob”).Value
‘ Resize
jpeg.Width = Request(”Width”)
‘ Set new height, preserve original aspect ratio
jpeg.Height = jpeg.OriginalHeight * jpeg.Width / jpeg.OriginalWidth
Jpeg.SendBinary
rs.Close
%>

Output to Memory
<%

Set rs = Server.CreateObject(”adodb.recordset”)
rs.Open “images”, strConnect, 1, 3
rs.AddNew
rs(”image_blob”).Value = Jpeg.Binary
rs.Update

%>

奇妙的文件系统对象组件

星期一, 06月 2nd, 2008

翻译 讨饭猫

很久以前(其实就几个月)就知道 Chinaasp 有个实际效果象黑客deASE程序,最近 Chinaasp 又提供了精华区全文检索功能.看来文件系统对象组件还是很有用de,对吧?如果您对此有兴趣,可以看看这篇文章.本文属入门级,修行还靠您自己,呵呵.

注意:我在下文中要操作de是Web服务器de文件系统,所以首先要确定您对该服务器有足够de权限.如果您不想麻烦您deWeb Master,您也可以用微软dePersonal Web Server来进行您de试验.

FSO对象包括

驱动器对象(Drive Object)用来存取本地盘或网络盘,

文件系统对象(FielSystemObject 简称FSO)是用来存取文件系统

文件夹对象(Folder Object)用于存取文件夹de各种属性

文本流对象(TextStream Object 简称TS)存取文件内容

使用以上对象,您de确可以在一台电脑上为所欲为,但同样也可能会造成灾难,所以在使用FSOde时候要注意安全,特别是在Web应用中,Web服务器中会存储诸如用户信息,日志文件等等重要信息,更要格外小心.在本文中,我主要探讨FSO对象和TextStream对象

(FSO由Microsoft提供,所以本文内容只适用于Windows操作系统下deASP编程.)

如何使用FSO?

要开始干坏事之前,首先要学会建立FSO.如果您曾经在ASP中创建过对象,那么这事好办:

<%

Set fso = Server.CreateObject("Scripting.FileSystemObject")

%>

现在我已经建立了FSO,并赋值给变量fso,接下来就可以使用我熟悉deobject.method方法来使用它了(如果您对对象de操作不熟悉,请自己去补课,这里恕不奉陪).在下面de例子中,主要使用de是fso.method和fso.property.

(FSO模块来自微软提供de脚本运行库scrrun.dll中,许多应用系统都会调用它,例如Access,Word等等,并非专为ASP应用开发.)

下面是我要用到de部分FSO方法:

CopyFile 拷贝一个或多个文件

CreateTextFile 创建一个文件并返回一个TS对象

DeleteFile 删除一个文件

OpenTextFile 打开一个文件并返回一个可用于读和添加deTS对象.

要获得完整deFSO方法,请参看MSDN.下面看个例子吧.

写文件

设想您要建立一个简单deguestbook,而又不想用复杂de数据库,或者您deISP限制您用数据库,大可以用FSO来干.

假设您要从用户提交deform中收集信息,html这样写.

<html>

<body>

<form action="formhandler.asp" method="post">

<input type="text" size="10" name="username">

<input type="text" size="10" name="homepage">

<input type="text" size="10" name="Email">

</form>

</body>

</html>

再看看用于处理这个formdeformhandler.asp.

<%

‘ 获取 form信息

strName = Request.Form("username")

strHomePage = Request.Form("homepage")

strEmail = Request.Form("Email")

‘ 建立fso对象

Set fso = Server.CreateObject("Scripting.FileSystemObject")

path = "c:\temp\test.txt"

ForReading = 1, ForWriting = 2, ForAppending = 3

‘ 打开文件

set file = fso.opentextfile(path, ForAppending, TRUE)

‘ 把信息写入文件

file.write(strName) & vbcrlf

file.write(strHomePage) & vbcrlf

file.write(strEmail) & vbcrlf

‘ 关闭并清除对象

file.close

set file = nothing

set fso = nothing

看看上面,OpenTextFile方法返回了一个TS对象,TS对象提供了例如Write,ReadLine,SkipLine等一系列de方法来操作文件内容.VB常量vbcrlf是换行符.

(我在OpentextFile方法中指定了TRUE参数,通知系统当文件不存在时生成一个新文件.如果不用TRUE,当文件不存在时就会返回一个难看de错误提示.)

现在打开c:\temp\test.txt,您可以看到如下信息:

User’s name

User’s home page

User’s email

当然,实际内容是用户de输入.哈,一个简单deguestbook诞生啦.

读文件

好,现在我deguestbook里已经存储了不少用户de信息了,如果这时一个用户想看看我访客de信息,我得把信息再还原出来.由于不是数据库,得自己动手来解决分段问题.看看test.txt,每三行就是一个用户de信息,好办:

<%

‘ 建立fso对象

set fso = Server.Createobject("Scripting.FileSystemObject")

path = "c:\temp\test.txt"

‘打开文件

set file = fso.opentextfile(path, 1) <– 用于读

do until file.AtEndOfStream

Response.write("Name: " & file.ReadLine & " ")

Response.write("Home Page: " & file.ReadLine & " ")

Response.write("Email: " & file.ReadLine & "<p>")

loop

‘ 关闭并清除

file.close

set file = nothing

set fso = nothing

%>

(这里我只是将信息简单输出,您可以根据实际情况作调整,包括输出到表格和DHTML form中.)

ReadLine方法用于从文件中读取一行,下次调用ReadLine方法将读取下一行.AtEndOfStream是TS对象de一个属性,让您知道是否到达文件结尾.

假设由于某种原因文件有问题,例如某个用户只有两行,那么我会得到以下错误信息:

Server object error ‘ASP 0177 : 800a003e’

所以加入一些错误处理相关代码是必要de.

FSOde权限问题

现在我已经对FSO有一些基本认识了,是时候来讨论一下FSOde权限问题.FSOde读取权限就是创建FSOde账号所拥有de权限.如果某人从Internet上使用这个页面,那么创建FSOde就是Internet账号.如果您用administrator本机登录并访问页面,那么建立deFSO就拥有administratorde权限.

Internet账号(IUSER_机器名)通常只有读权限,这意味着用户永远无法写guestbook文件.所以必须想办法解决.

第一个办法,是让用户首先要用一个有写权限de账号登录.但实际上所有从Internet访问de用户都是以anonymous登录,所以这个方法比较难实现.

第二个方法是建立一个允许账号为 IUSER_机器名 de用户读写de目录.但这样可能会带来安全漏洞.如果这个目录让黑客知道了,就可以往里面写一些相关代码并通过某种方式运行它,那您就惨了.所以最好将这个目录建立在Web路径之外(也就是inetpub路径之外).

用FSO实现search功能

现在让我来做更进一步de工作,用FSO在我deWeb站点上实现search功能.建立搜索引擎de关键是递归.

首先来建立搜索页面.假设我已经给用户提供了一个输入搜索字符串de页面.

Dim objFolder

Dim strSearchText

Dim objFSO

strSearchText = Request.Form("SearchText") <– 搜索字符串

‘ 建立 FSO 和文件夹对象

Set fso = Server.CreateObject("Scripting.FileSystemObject")

Set objFolder = objFSO.GetFolder(Server.MapPath("/"))

Search objFolder

上面de相关代码只是进行了一些变量初始化工作,真正deserach工作由下面这个Search函数执行.

Function Search(objFolder)

Dim objSubFolder

‘循环搜寻当前文件夹中de每个文件

For Each objFile in objFolder.Files

Set objTextStream = objFSO.OpenTextFile(objFile.Path,1) <– For Reading

‘把文件内容读入一个变量

strFileContents = objTextStream.ReadAll

‘如果在文件中找到该字符串,写个指到该文件de链接

If InStr(1, strFileContents, strSearchText, 1) then

Response.Write "<A HREF=""/" & objFile.Name &""">" & objFile.Name & "</A><BR>"

bolFileFound = True

End If

objTextStream.Close

Next

‘以下是递归部分

‘ 如果其中有子目录,再调用Search函数

For Each objSubFolder in objFolder.SubFolders

Search objSubFolder

Next

End Function

该程序会自动搜索Web root目录以下de所有子目录,还不错吧?

(FSO要使用物理绝对路径,而不是Web Pathde相对路径.例如,要打开de是c:\inetpub\wwwroot\temp\index.html,而不能是www.enfused.com/temp/index.html 或 /temp/index.html.要将后一种路径转换为物理绝对路径,使用Server.MapPath("filename").)

随着文件和子目录数de增加,程序运行de时间会变长.所以如果是要提供繁重de搜寻功能,还是建议使用象 Microsoft Index Server这样de专业工具.

用FSO进行目录管理

现在知道FSOde好处了吧?下面我尝试用FSO来做更复杂一些de工作.

Web目录管理就是在Web环境下进行文档de新建删除改名移动等工作,一个好deWeb目录管理工具可以为用户提供一个与我惯用de环境一样de操作方法来管理Web服务器上de文件.

那么先让我来试试文件改名.首先要告诉大家,不幸得很,FSO不允许直接文件改名,所以我要绕个弯进行.

<%

‘ 建立fso对象

set fso = Server.Createobject("Scripting.FileSystemObject")

path = "c:\temp\test.txt"

strDate = Replace(Date(), "/", "")

strDir = "c:\inetpub\wwwroot\articles\" & strDate

strNewFileName = Hour(Now) & "_" & Minute(Now) & "_" &second(Now) & ".html"

‘ 打开旧文件

set file = fso.opentextfile(path, 1) <– 用于读

strText = file.readall

set file = nothing

‘ 检查是是否要建立文件夹

if not fso.folderexists(Server.MapPath(strDir)) then

set f = fso.CreateFolder(Server.MapPath(strDir))

else

set f = fso.GetFolder(Server.MapPath(strDir))

end if

‘ 创建并写入新文件

set file = fso.Createtextfile(f.path & "\" & strNewFileName)

file.write(strText)

set f = nothing

file.close

set file = nothing

‘ 删除旧文件

fso.DeleteFile(path & "\" & rst("FileName") & i)

‘ 清除

set fso = nothing

%>

我在这里特别举这个例子就是因为FSO在这个功能上存在缺陷,所以我必须分两步走.首先新建一个文件,注意,由于用户可能将文件改名到另一个目录下,所以我必须判断新目录是否存在(就是if not fso.folderexists那段相关代码).新文件建好后,用fso.DeleteFile 将旧文件删除.

FSO功能上de弱点

FSO还是存在一些弱点.例如,它在处理二进制文件de时候就不那么方便.对于象MS Word文档,图像等许多文件,您只能执行移动,删除等操作,而不能打开,读/写.当然,FSO提供了另外一套操作它们de方法(具体请参考MSDN),但始终不如我惯用deopen方法那么顺手.

另一个不足与文件大小有关.由于FSO操作需要经常地将文件内容读入内存,文件有多大,就需要多少内存,所以如果您要处理大文件或一大堆小文件de话,内存de开销会很可观,可能会对系统运行速度有影响.解决办法是将大文件分段处理,并记住经常地清除内存(把变量设为null或"",set 对象=nothing).

此外,FSO不能改变文件和文件夹de属性.例如,在建立guestbookde例子中,其实有一个安全机制我没有实现,就是将保存信息de文件de属性设为只读,只有在更新de时候才临时改为可写,写完后再改回只读,许多用CGI或Perl写deguestbook程序都有这种功能,可惜用FSO无法实现该功能.

FSO还能干些什么?

总de来说,FSO还是很强大de.FSO还有一些一般没人注意到de很酷de功能.下面列出一些,当您看完可能会说“呀,我以前怎么不知道.”呵呵.

GetSpecialFolder 方法

返回一个特殊deWindows文件目录:Windows安装文件目录,系统文件目录,临时文件目录.使用方法分别是:FSO.GetSpecialFolder([0, 1, or 2])

GetTempName 方法

返回一个随机生成de临时文件或文件夹.象处理上面所说de将大文件分割处理de时候这个功能特别有用.(讨饭猫:如果Win98常死机de话,我经常可以在Windows根目录下看到大量de长度为0de随机文件名,估计就是这个用途)

GetAbsolutePathName 方法

返回一个文件夹de绝对路径(有点象Server.MapPath).例如,FSO.GetAbsolutePathName("region")会返回象"c:\mydocs\myfolder\region" 这样de路径,具体取决于您de当前目录.

GetExtensionName 方法

返回文件de扩展名.例如 FSO.GetExtensionName("c:\docs\test.txt") 返回 "txt".

GetBaseName 和 GetParentFolder 方法

分别返回根目录名和父目录名.例如 FSO.GetParentFolder ("c:\docs\mydocs") 返回 "docs".

Drives 属性

返回本机上所有驱动器de集合.如果您要建立一个explorer风格de界面,这个功能再有用不过.

记住要建立一套完善de错误信息处理机制,因为上面这些功能如果遇到象文件夹不存在之类错误时,会返回一些可恶de错误相关代码.

看到这里,是不是觉得FSO有用呢?实际上,我所提到de内容只是冰山de一角.在Enfused等大站点上,还可以看到更多与此有关话题de讨论.

Copyright 1999-2000 internet.com Corp. All RIGHTS RESERVED.

filesystemobject组件的用法示例

星期一, 06月 2nd, 2008

””””””””””””””””””””””””””””””””””””

‘ CreateLyrics

‘ 目de:

‘ 在文件夹中创建两个文本文件.

‘ 示范下面de内容

‘ - FileSystemObject.CreateTextFile

‘ - TextStream.WriteLine

‘ - TextStream.Write

‘ - TextStream.WriteBlankLines

‘ - TextStream.Close

””””””””””””””””””””””””””””””””””””

Sub CreateLyrics(Folder)

Dim TextStream

Set TextStream = Folder.CreateTextFile("OctopusGarden.txt")

TextStream.Write("Octopus’ Garden ") ‘ 请注意,该语句不添加换行到文件中.

TextStream.WriteLine("(by Ringo Starr)")

TextStream.WriteBlankLines(1)

TextStream.WriteLine("I’d like to be under the sea in an octopus’ garden in the shade,")

TextStream.WriteLine("He’d let us in, knows where we’ve been — in his octopus’ garden in the shade.")

TextStream.WriteBlankLines(2)

TextStream.Close

Set TextStream = Folder.CreateTextFile("BathroomWindow.txt")

TextStream.WriteLine("She Came In Through The Bathroom Window (by Lennon/McCartney)")

TextStream.WriteLine("")

TextStream.WriteLine("She came in through the bathroom window protected by a silver spoon")

TextStream.WriteLine("But now she sucks her thumb and wanders by the banks of her own lagoon")

TextStream.WriteBlankLines(2)

TextStream.Close

End Sub

‘ GetLyrics

‘ 目de:

‘ 显示 lyrics 文件de内容.

‘ 示范下面de内容

‘ - FileSystemObject.OpenTextFile

‘ - FileSystemObject.GetFile

‘ - TextStream.ReadAll

‘ - TextStream.Close

‘ - File.OpenAsTextStream

‘ - TextStream.AtEndOfStream

‘ - TextStream.ReadLine

””””””””””””””””””””””””””””””””””””

Function GetLyrics(FSO)

Dim TextStream

Dim S

Dim File

‘ 有多种方法可用来打开一个文本文件,和多种方法来从文件读取数据.

‘ 这儿用了两种方法来打开文件和读取文件:

Set TextStream = FSO.OpenTextFile(TestFilePath & "\Beatles\OctopusGarden.txt", OpenFileForReading)

S = TextStream.ReadAll & NewLine & NewLine

TextStream.Close

Set File = FSO.GetFile(TestFilePath & "\Beatles\BathroomWindow.txt")

Set TextStream = File.OpenAsTextStream(OpenFileForReading)

Do While Not TextStream.AtEndOfStream

S = S & TextStream.ReadLine & NewLine

Loop

TextStream.Close

GetLyrics = S

End Function

关于用ADO STREAM做的无组件上传程序简单介绍

星期一, 06月 2nd, 2008

前面有人贴了用ADO STREAM做de无组件上传程序,今天我做一下关于它de简单介绍

以前,如果要用ASP操作文件,比如移动、复制、删除或者创建一个记事本文件,基本上都是通过FILESYSTEMOBJECT对象做de,当然,这个东西很专业,也没说什么不好,它可以提供完善de文件信息,比如建立时间,大小,上次修改时间等等,但是如果您不做痛苦de高代价de字符格式转换de话,利用它您无法直接操作二进制文件.

但是,现在我介绍destream物件可以同时操作文本对象和二进制对象,要求是您de机器上要安装有ADO2.5或者更高版本,您可以从http://www.microsoft.com/data里去DOWNde.

这个stream对象包含了许多操作二进制和文本文件de方法,让我来看例子吧

打开stream对象

<!–METADATA TYPE="typelib" UUID="00000205-0000-0010-8000-00AA006D2EA4" NAME="ADODB Type Library"–><%’Create a Stream instanceDim objStreamSet objStream = Server.CreateObject("ADODB.Stream")’Open the streamobjStream.Open

对于以上de引用,如果您有不明白de地方,可以看我以前贴de帖子,具体什么名字忘记了

注意:如果版本不对以上相关代码会提示错误信息de.

现在您已经建立了一个0长度deSTREAM,任何时候,您都可以使用size属性看改streamde大小,现在我要指定操作什么类型de信息,二进制还是text ,如果是text还要指定是ASCII还是UNICODE格式

如下相关代码:

objStream.Type = adTypeText

objStream.Charset = "ascii"

接下来我向这个stream里写进一个text文件,用它deloadfromfile方法

objStream.LoadFromFile "D:\Inetpub\wwwroot\webtech\083100-1.shtml"

在这里要注意de是,如果您操作stream,一定要搞清楚位置de概念,这里我使用了loadfromfile方法以后,原来stream里de内容会被全部清除,然后,该文件被装载到stream里面,接着streamde位置恢复为0,(streamde开始位置)

您如果在当前0位置写入信息,就会覆盖原来de内容,所以您如果想要追加东西de话,必须从最后位置开始操作,如下相关代码:

objStream.Position = objStream.Size

该相关代码把当前位置移到最后

现在我可以往后面加东西了,嘿嘿,比如

objStream.WriteText "请访问我de聊天室,MM尤其欢迎"

哈哈

现在我达到了我de目de了,让我把它保存下来

这里要注意de是因为您是用iuser_machinenamede帐号de,所以相应目录要对该帐号开放写权限de,这个是没办法de事,不然会出错.

objStream.SaveToFile"D:\InetPub\wwwroot\demos\StreamDemo.txt", adSaveCreateOverwrite

继承我de优良传统,使用完以后,关闭释放

‘Close the stream and set it to nothing…

objStream.Close

Set objStream = Nothing

%>

前面我也说过,它也能操作二进制对象,其实只要修改一些参数就可以了,让我来看一个例子:

<!–METADATA TYPE="typelib"

UUID="00000205-0000-0010-8000-00AA006D2EA4"

NAME="ADODB Type Library"

–>

<%

‘Create a stream object

Dim objStream

Set objStream = Server.CreateObject("ADODB.Stream")

‘Open a GIF file

objStream.Type = adTypeBinary

objStream.Open

objStream.LoadFromFile "D:\Inetpub\wwwroot\images\banner\dimacbanner1.gif"

‘Output the contents of the stream object

Response.ContentType = "image/gif"

Response.BinaryWrite objStream.Read

‘Clean up….

objStream.Close

Set objStream = Nothing

%>

您可以试试用这个写一个上传de东西,这样学习起来快,反正有现成de老师在,可以参考

:P

希望能对您有帮助,对了,我de聊天室是http://www.sanchat.com,不要忘记捧场啊!!!

巧用FileSystem组件实现WEB应用中的本地特定打印

星期一, 06月 2nd, 2008

1、引言

随着Internetde飞速发展,许多企业都纷纷开发基于WEBde业务应用系统.一般情况下,基于WEBde业务应用都采用三层或三层以上de结构,前台即客户端是普通deWEB浏览器,中间业务逻辑应用层存放于WEB服务器上,由WEB服务器上de服务构件访问后台数据库.为了业务系统与Internetde互联,WEB服务器和数据库系统均托管在IDC(互联网数据中心),因而需要从托管在 IDCde服务器上提取业务数据在本地打印输出.在客户端浏览器只能打印简单deHTML页面de情况下,要求更为强大灵活de打印输出功能;通过采用相关de技术对浏览器de功能进行扩展,能够完成更复杂de数据打印de任务,如收条、回执等.笔者曾经为一网络教育公司开发教育管理软件时采用FileSystem组件实现在本地打印三联收款凭证和准考证等de功能.

2、FileSystem组件使用简介

FileSystem组件其实是一个ActiveX控件,其存在于WINDOWS平台中(不管是Win98、Win2000,还是NT环境都包含该组件.),CLSID:0D43FE01-11CF-8940-00A0C9054228.熟悉ASP编程人可能都使用过FileSystem组件,一般情况下该组件用在服务器端,用来对文本文件、文件夹及驱动器进行访问和控制.可以通过两种方法创建FileSystem组件de对象实例:

1、使用ASPde内置对象SERVERde方法Server.CreateObject来创建服务器端对象de实例.

2、使用Vbscript脚本函数CreateObject来创建客户端对象de实例(也可以在服务器端用该方法,但有时会出错,一般不使用;).

FileSystem组件对文本文件进行操作有如下方法:

CreateTextFile(Filename,[Overwrite if exists],[Unicode/ASCII]) //创建文本文件

OpenTextFile(Filename,[Input/output mode],[Create if not exists],[Format]) //打开文本文件

CopyFile(Filename1,Filename2,[Overwrite]) //拷贝文本文件

MoveFile (Filename1,Filename2) //移动文本文件

DeleteFile (Filename) //删除文本文件

GetFile (Filename) //获得文本文件

FileExists (Filename) //判断文本文件是否存在

FileSystem组件对文件夹和驱动器也有和文本文件相类似de方法,在此不一一赘述.

其实,FileSystem组件也可使用于客户端,采用创建FileSystem组件对象实例de第二种方法即可以使用该组件对客户端系统de文本文件、文件夹及驱动器进行访问和控制.因为微软平台带有FileSystem组件,所以对于微软平台de客户端则不需要从远程服务器下载,其在安装操作系统时会自己安装并注册;而对于其他平台de客户端则须安装插件并下载FileSystem组件.

3、本地端特定打印de实现机制

利用FileSystem组件实现本地端特定打印de过程如图所示:

<IMG SRC="http://www.computerworld.com.cn/htm/app/aprog/01_9_14_5.jpg" border=0>

1、客户端向WEB服务器发送数据请求;

2、WEB服务器根据业务处理逻辑与后台数据库进行交互,取得所需数据形成HTML页面,并附带有FileSystem组件对象deVBScript脚本,向客户端浏览器发回HTML页面;

3、在客户端运行脚本,脚本取得HTML页面构件de数据,建立与打印机de连接,向打印机输出打印数据.

前两步与一般deWEB应用没有什么区别,需要说明de是第三步:首先使用Vbscript脚本函数CreateObject来创建FileSystem组件对象de实例;然后调用该实例创建文本文件deCreateTextFile方法,把打印端口LPT1或LPT2作为文件名参数,并将可覆盖文件参数设为TRUE,建立与打印机de连接;调用获得de打印机文本文件流实例de写文本方法WriteLine向打印机输出打印de内容.

4、程序示例

客户端脚本:

<script Language=VBScript>

function print_onclick //打印函数

dim label

label=document.printinfo.label.value //获得HTML页面de数据

set objfs=CreateObject("Scripting.FileSystemObject") //创建FileSystem组件对象de实例

set objprinter=objfs.CreateTextFile ("LPT1:",true) //建立与打印机de连接

objprinter.Writeline("__________________________________") //输出打印de内容

objprinter.Writeline("| |")

objprinter.Writeline("| 您打印de数据是:"&label& " |”)

objprinter.Writeline("| |")

objprinter.Writeline("|_________________________________|")

objprinter.close //断开与打印机de连接

set objprinter=nothing

set objfs=nothing // 关闭FileSystem组件对象

end function

</script>

服务器端脚本:

<%………

set conn=server.CreateObject ("adodb.connection")

conn.Open "DSN=name;UID=XXXX;PWD=XXXX;"

set rs=server.CreateObject("adodb.recordset")

rs.Open(“select ……”),conn,1,1

……….%> //与数据库进行交互

HTML页面编码:

<HTML>

………

<FORM ID=printinfo NAME="printinfo" >

<INPUT type="button" value="打印>>" id=print name=print > //调用打印函数

<INPUT type=hidden id=text1 name=label value=<%=………%>> //保存服务器端传来de数据

………

</HTML>

5、说明及结论

1、使用此方法实现打印任务之前,必须调节浏览器de安全设置;在Internet选项上安全级别降低,对自己de站点充分信任,可以通过浏览器执行脚本访问本机资源.

2、本方法可以实现在局域网de打印机上打印远程服务器de数据,只须用局域网上打印机注册在本地de端口代替本地打印机端口作为创建文本文件deCreateTextFile方法de参数即可.

3、本方法可以实现根据用户选择打印de宽度、高度和数量及内容,并可重复打印.

4、不需要编写ActiveX控件即可以完成特定de打印功能,实现较为简单.

5、不足之处是需要调节浏览器de安全设置,且不支持图片和特殊字体de打印.