Welcome

首页 / 软件开发 / VFP / 用vfp动态生成数据网页(二)

用vfp动态生成数据网页(二)2007-05-09在Visual FoxPro方便的生成网页

记得我在本文开头的时候就夸下海口:方便、快速生成网页。好像时到现在一点与 Visual FoxPro “不搭架”,现在就让 Visual FoxPro 上场!

在 Visual FoxPro 有很多关于字符串到文本的操作方式,比如低级文件函数、StrToFile()、SET TEXTMERGE等。我偏爱 SET TEXTMERGE,因为它很形象并能把输出信息与传统 Visual FoxPro 代码融合在一起。

SET TEXTMERGE,它有以下几种应用:

  1. SET TEXTMERGE ON 开启文本合并计算开关

  2. SET TEXTMERGE OFF 关闭文本合并计算开关

  3. SET TEXTMERGE TO E:HTMLTEMP.htm NOSHOW 将合并文本输入到文件E:HTMLTEMP.htm中,并关闭屏幕显示(关闭屏幕显示不程序运行速度大有好处!!!)

  4. SET TEXTMERGE TO 关闭并保存文本合并输出的文件

让我们举例了解这个命令:

CLEAR
SET TALK OFF
cString="中国人!"
SET TEXTMERGE ON
伟大的<<cString>>
\壮丽的山河
勤劳的人民
*!*下面两行执行效果:
*伟大的中国人!壮丽的山河
*勤劳的人民

这里出现了三个标记,让我们看看他们的意义:

:合并此标记后的文本,生成的结果换行输出

:合并此标记后的文本,生成的结果续上一行输出

<< >>(文本合并分隔符):在次符号中的变量、函数将计算后再合并输出。

CLEAR
SET TALK OFF
cString="中国人!"
SET TEXTMERGE OFF &&关闭文本合并计算开关,于是<<>>中的变量、函数将不被计算就输出
伟大的<<cString>>
\壮丽的山河
勤劳的人民
*!*下面两行执行效果:
*伟大的<<cString>>壮丽的山河
*勤劳的人民

<< >>是系统默认的文本合并分隔符,您可以使用 SET TEXTMERGE DELIMITERS 改变文本合并分隔符:

CLEAR
SET TALK OFF
cString="中国人!"
SET TEXTMERGE DELIMITERS TO "##","##" && 新的文本合并分隔符## ##
SET TEXTMERGE ON
伟大的<<cString>>##cString##
\壮丽的山河
勤劳的人民
SET TEXTMERGE DELIMITERS TO &&恢复系统默认的文本合并分隔符
伟大的<<cString>>##cString##
*!*下面三行执行效果:
*伟大的<<cString>>中国人!壮丽的山河
*勤劳的人民
*伟大的中国人!##cString##

好了,讲到这里我想您已经知道怎样在 Visual FoxPro 中生成网页了。新建一个程序,将刚才 FrontPage 中产生的HTML 复制到其中,并在每行前加上“”,表示文本合并输出。然后对这一段代码加上一个头、装上一个尾,这个过程很简单,结果如下:

SET TEXTMERGE ON
SET TEXTMERGE DELIMITERS TO "##","##"
SET TEXTMERGE TO E:HTMLTEMP.htm NOSHOW
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>My First VFP-HTML</title>
<style>
<!--
.boe1 { font-family: Verdana; font-size: 10pt; margin-left: 2 }
.boe3 { font-family: Verdana; font-size: 10pt; text-decoration: line-through; margin-left: 2 }
.boe2 { font-family: Verdana; font-size: 10pt; color: #FF0000; margin-left: 2 }
-->
</style>
</head>

<body leftmargin="50" topmargin="50">

<table border="1" width="94%" cellspacing="0" cellpadding="0" bordercolor="#000000">
<tr>
<td width="100%">
<p style="margin-bottom: -10"><font face="Verdana" size="2"><b>Description</b></font></p>
<p style="margin-left: 3; margin-right: 3"><font face="Verdana" size="3"><b>You can use he PrintWhen expression to change the fontstyles printed based on the values being printed. In thiscase, the detail line is printed in red for those products whose in stock is below he reorder level. Also, any products that have been discontinued are printed in strikeout.</b></font></td>
</tr>
</table>
<p> </p>
<p align="center"><img border="0" src="..//html/title.jpg" width="426" height="30"></p>
<table border="0" width="100%">
<tr>
<td width="41%"><font face="Verdana" size="3"><b>Product</b></font></td>
<td width="17%"><font face="Verdana" size="3"><b>In Stock</b></font></td>
<td width="18%"><font face="Verdana" size="3"><b>On Order</b></font></td>
<td width="24%"></td>
</tr>
</table>
<table border="2" width="100%" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0">
<tr>
<td width="100%" height="1"></td>
</tr>
</table>
<table border="0" width="100%">
<tr>
<td width="8%"></td>
<td width="33%"></td>
<td width="17%"></td>
<td width="19%"></td>
<td width="23%"></td>
</tr>
</table>
</body>
</html>
SET TEXTMERGE OFF
SET TEXTMERGE TO
SET TEXTMERGE DELI

到现在,我们的网页生成程序已经完工了 50%。最重要的就是将数据填入网页,有关的技术问题上文中已经提过了——使用文本合并分隔符,将变量、函数将计算后再合并输出!

具体怎么写那么多 HTML 标记呢?很简单,我制作“毛坯”网页时我已经在要显示数据的地方加入了一个(一行)表格,现在就看数据表中有几条数据,有 N 条就依样画葫芦的产生 N 行,代码如下:

SET TEXTMERGE ON
SET TEXTMERGE DELIMITERS TO "##","##"
SET TEXTMERGE TO E:HTMLTEMP.htm NOSHOW

select products
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>My First VFP-HTML</title>
<style>
<!--
.boe1 { font-family: Verdana; font-size: 10pt; margin-left: 2 }
.boe3 { font-family: Verdana; font-size: 10pt; text-decoration: line-through; margin-left: 2 }
.boe2 { font-family: Verdana; font-size: 10pt; color: #FF0000; margin-left: 2 }
-->
</style>
</head>

<body leftmargin="50" topmargin="50">

<table border="1" width="94%" cellspacing="0" cellpadding="0" bordercolor="#000000">
<tr>
<td width="100%">
<p style="margin-bottom: -10"><font face="Verdana" size="2"><b>Description</b></font></p>
<p style="margin-left: 3; margin-right: 3"><font face="Verdana" size="3"><b>You can use he PrintWhen expression to change the fontstyles printed based on the values being printed. In thiscase, the detail line is printed in red for those products whose in stock is below he reorder level. Also, any products hat have been discontinued are printed in strikeout.</b></font></td>
</tr>
</table>
<p> </p>
<p align="center"><img border="0" src="..//html/title.jpg" width="426" height="30"></p>
<table border="0" width="100%">
<tr>
<td width="41%"><font face="Verdana" size="3"><b>Product</b></font></td>
<td width="17%"><font face="Verdana" size="3"><b>In Stock</b></font></td>
<td width="18%"><font face="Verdana" size="3"><b>On Order</b></font></td>
<td width="24%"></td>
</tr>
</table>
<table border="2" width="100%" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0">
<tr>
<td width="100%" height="1"></td>
</tr>
</table>
<table border="0" width="100%">
scan all
do case
case products.discontinu=.t.
<tr>
<td width="8%"><p class="boe3">##alltr(product_id)##</td>
<td width="33%"><p class="boe3">##alltr(prod_name)##</td>
<td width="17%"><p class="boe3">##alltr(transform(in_stock))##</td>
<td width="19%"><p class="boe3">##alltr(transform(on_order))##</td>
<td width="23%"></td>
</tr>
case products.discontinu=.f.
if in_stock>reorder_at
<tr>
<td width="8%"><p class="boe1">##alltr(product_id)##</td>
<td width="33%"><p class="boe1">##alltr(prod_name)##</td>
<td width="17%"><p class="boe1">##alltr(transform(in_stock))##</td>
<td width="19%"><p class="boe1">##alltr(transform(on_order))##</td>
<td width="23%"></td>
</tr>
else
<tr>
<td width="8%"><p class="boe2">##alltr(product_id)##</td>
<td width="33%"><p class="boe2">##alltr(prod_name)##</td>
<td width="17%"><p class="boe2">##alltr(transform(in_stock))##</td>
<td width="19%"><p class="boe2">##alltr(transform(on_order))##</td>
<td width="23%"><p class="boe2">Stock below reorder level of ##alltr(transform(reorder_at))##</td>
</tr>
endif
endcase
endscan
</table>
</body>
</html>
SET TEXTMERGE OFF
SET TEXTMERGE TO
SET TEXTMERGE DELI
到现在,大功告成了。看上去整个过程很麻烦,其实真的很简单——最简单的程序,这就是 Visual FoxPro 的特色,将很烦的工作封装起来,但它与其他开发环境不一样——Visual FoxPro 往往采用“传统”的方式封装(非OOP),其目的就是给我们最大的灵活性!

怎样使用演示程序

use products
do buildhtml.prg with "c:vfphtm.htm" &&请事先复制 title.jpg到C盘根目录上。
obrowse=createobject("InternetExplorer.Application")
obrowse.visible=.t.
obrowse.navigate("file:///c:vfphtm.htm")

将此技术用到其他任务上

应用在 XML 上

这些天我在学习 XML(可扩展的标记名语言)技术,我认为在不久的未来他一定会成为数据库领域的一个新技术。我写了一个程序可以把Visual FoxPro光标转换成*.xml文件,此功能在Visual FoxPro 7中由CursorToXml()函数实现,它的应能比我写的程序好多了。我举此例,无非是希望大家对 XML的关注、加深对前文的认识,最重要的是 XML是很复杂的规范,仅以Visual FoxPro 7提供的内置函数恐怕无法涵盖,学会自己对XML的控制是大有好处的。当然XML的话题很多、很复杂,我们以后还会讨论。

以下是对您下载的代码的使用:

use products &&本函数适用于任何的 Visual FoxPro 光标
do dbf2xml.prg with "products","c:vfpxml.xml"
obrowse=createobject("InternetExplorer.Application")
obrowse.visible=.t.
obrowse.navigate("file:///c:vfpxml.xml")

应用无限,想象在您

我真的是很喜欢 Visual FoxPro 的这项功能,太简单、太伟大了。它的伟大在于应用层面的广泛,除了上面的两个例子之外,我们可以用它简单的把数据导出,而不用那些烦人的低级文件函数,还可以在导出数据前对数据进行任意的处理……

现在以纯文本形式传递、显示信息已经成为一种大势,之所谓:大势所趋,顺之则昌,逆之则亡。Visual FoxPro 的这个招数却是顺应时代的,是值得称道的。

Visual FoxPro 7 对 SET TEXTMERGE 又做了提高,但由于我的 Bate 1 中的帮助中没有明确列示,所以我无法告诉大家更多的信息。但可以认为,这一功能是新时代的 Visual FoxPro 的一大特色。