报表打印技术深入探讨集锦

      数据库学习笔记 2008-11-27 17:5

 

转贴坛中一位大侠的总结:
------------

下面是好多前辈以及各版主以前发的文章,我找了一宿,匆匆浏览了一下,觉得掌握了这些技巧,应该和雪心的终极打印比较接近了吧?是不是啊?若不是,老兵   centch 你们一定要批判我,可不能看着兄弟出洋相而置之不理啊。  :)

另外,近来有好多狐友问关于报表打印的问题,我想,看了下面的几个例程会很有帮助的。

概述
在以编程方式创建报表时, 可以使用以下公式来计算报表中对象的宽度:


625/6
每象素报表单位

更多信息
FONTMETRIC
函数返回指定字体的不同属性. 例如, FONTMETRIC(6) 返回当前字体的平均字符象素宽.

因此, 要计算报表中五个字符需要的平均宽度, 可用以下公式:

reportwidth = 625/6 * ;
(FONTMETRIC(6, , , ) * ;
nNumCharacters)


nNumCharacters
指定字符数.
以下代码将保存 5 个字符宽的 Times New Roman 字体, 12 号字,普通字型在报表中所需要的平均宽度到变量 reportwidth .


reportwidth = 625/6 * (FONTMETRIC(6, "Times New Roman", 12, "N") * 5)


打印系统变量简单介绍:

  当打印报表时,常会在每一页的上端印上页眉,但是如何取得某一页已打印完并进一张新纸的信息呢?方法是利用ON PAGE命令:
  ON PAGE[AT LINE<第几行>][<命令>]
  如:
  ON PAGE AT LINE 56 DO print_foot
  PROC print_foot
  ?'本表由建设银行制作'
  ENDPROC
  行号可以从_PLINENO系统变量取得,_PLINENO这个系统变量可以返回或设定当前打印的行号,其范围可以从0_PLENGTH-1(即打印纸长度减1)_PLENGTH这个系统变量用于设定或返回打印纸的页长,普通的打印纸是66行长,范围值从132767,这个变量的设定会影响_PLINENO及跳页的频率。
  打印系统变量简单介绍:
  _PADVANCE
  语法:_PADVANCE=cAdvanceMethod
  类型:字符
  默认值:FORMFEED
  说明:本系统变量用于设定打印进纸的方式,其值分为以下两种:
  FOEMFEED 以整张打印纸进纸
  LINEFEED 表示进了数行后的位置作为一页的开始
  注意:
  计算进纸的行数的方法有以下两种:
  当执行EJECT PAGEPRINTJOB...ENDPRINTJOB命令时,使用公式(_PLENGTH-_PLINENO)
  当执行EJECT命令或输出到打印机后执行@...SAY命令时,使用公式(_PLENGTH-MOD(PROW(),_PLENGTH))
  参阅:_PLENGTH,_PLINENO,_PEJECT
  _PAGENO
  语法:_PAGENO=cAdvanceMethod
  类型:数值
  默认值:1
  说明:本系统变量保存或设定当前的打印页号,在打印报表时,可以在报表上打印出页号。
  注意:范围从1-32767
  参阅:_PBPAGE,_PEPAGE,ON PAGE
  _PBPAGE
  语法:_PBPAGE=nBeginningPage
  类型:数值
  默认值:1
  说明:本系统变量用于设定或返回印的起始页号,当_PBPAGE的值大于_PAGENO的值,将不会打印任何数据。
  注意:范围从1-32767
  参阅:_PAGENO,_PEPAGE
  _PCOLNO
  语法:_PCOLNO=nCloumn
  类型:数值
  默认值:当前列位置
  说明:本系统变量可以设定或当前打印头的列位置,使用本变量的效果与使用?命令的AT参数相同。
  注意:如果_WRAP设定为.T.,而本变量的设定值小于当前打印头的列位置,则打印缓冲区的内容会被覆盖而且也不会打印出来。
  参阅:PCOL()
  _PCOPIES
  语法:_PCOPIES=nCopies
  类型:数值
  默认值:1
  说明:本系统变量用于返回或设定打印份数。
  注意:必须在执行PRINJOB...ENDPRINTJOB命令之前将打印份数保存在_PCOPIES
  参阅:无
  _PEJECT
  语法:_PEJECT=cPageEjectvalue
  类型:字符
  默认值:BEFORE
  说明:本系统变量用于控制跳页的方式,其设定值如下:
  BEFORE     在打印前跳页
  AFTER     在打印后跳页
  BOTH      打印前后都跳页
  NONE      打印前后都不跳页
  注意:
  本变量在FoxPro for DOS中的默认值是BEFORE,在Visaul FoxPro中的默认值是NONE,本变量只有在PRINTJOB...ENDPRINTJOB命令块中才有效
  参阅:_PECODE,PRINTJOB...ENDPRINTJOB
  _PEPAGE
  语法:_PEPAGE=nLastPageNumber
  类型:数值
  默认值:32767
  说明:本系统变量用于返回或设定打印的终止页号。
  注意:_PEPAGE必须大于_PBPAGE
  参阅:_PAGENO,_PBPAGE
  _PLENGTH
  语法:_PLENGTH=nLinesPerPage
  类型:数值
  默认值:66
  说明:本系统变量用于返回或设定打印纸的页长。普通的打印纸是66行长,数值范围从132767
  注意:本变量的值会影响_PLINENO及跳页的频率
  参阅:EJECTON PAGE
  _PLINENO
  语法:_PLINENO=nCurrentline
  类型:数值
  默认值:0
  说明:本系统变量用于返回或设定打印的行号。数值范围从0_PLENGTH-1(即打印纸长度减1)
  注意:本变量与PROW()函数功能相似,他们的出不同在于:
  PROW()函数返回打印头的位置
  只有在SET PRINTER被设定为ON时,PROW()函数才有效
  _PLINENO会自动增加,不论输出设备是文件、打印机或屏幕
  参阅:PROW()
  _PPITCH
  语法:_PPITCH=cExpression
  类型:字符
  默认值:DEFAULT
  说明:本系统变量用于设定打印机的分辨率,设定值如下:
  PICA     每英寸10个字符
  ELITE     每英寸12个字符
  CONDENSED   每英寸17个字符
  DEFAULT    使用默认值
  注意:如果打印机本身无法打印出太高的密度,进行设定也是无效的。
  参阅:无
  _PQUALITY
  语法:_PQUALITY=lExpression
  类型:逻辑
  默认值:.F.
  说明:本系统变量用于控制打印质量,如果设置为.t.,打印的速度会下降,但打印的质量比较好。
  _PSPACING
  语法:_PSPACING=nLineSpacing
  类型:数值
  默认值:1
  说明:本系统变量用于控制打印行距,数值范围界于1-3之间,默认值是1
  _PWAIT
  语法:_PWAIT=lExpression
  类型:逻辑
  默认值:.F.
  说明:本系统变量用于打印换页时是否暂停,.t.为暂停。
  

             关于报表打印
                    江苏 常州 老王 99.11.30

                      E-mail:cfyns@163.net


  VFP所提供的报表设计器虽说功能强大,并能提供所见所得的报表预览,
但我总觉得没有DOS下直接用代码编制的打印程序来得方便和自由,虽然DOS
没有预览功能。也正因为如此,我很少谈及VFP 的打印问题,为了和大家交
流,这次也谈谈VFP的报表打印问题,希望以此和大家共同探讨。
  一、部分与打印有关的系统变量
  VFP本身为我们提供了几个与打印有直接关系的系统变量,它们是:(部分)
_BOX
   是否打印文字边框,.T.=打印
_GETNPD
  指定或保存打印机接口驱动程序的文件名。
_PADVANCE
 设定打印纸进纸方式,=FORMFEED(默认)整张进纸。
_PAGENO
  设定或保存当前的打印页号。
_PBPAGE
  设定或返回打印的起始页号。
_PEPAGE
  设定或返回打印的终止页号。
_PCOLNO
  设定或返回当前打印头的列。
_PLINENO
 设定或返回当前打印头的行。
_PCOPIES
 设定或返回打印份数。
_PLENGTH
 设定或返回打印纸的页长,默认=66行长。
_PPITCH
  设定打印机的打印密度。
_PQUALITY
 设定打印机的打印质量。
... ...
  这些变量在设计报表程序时,有些是很有用的,故在此列出。

  二、一些常用的打印技巧
  1.怎样打印指定的页
REPORT FORM XXXX RANGE 2,5 TO PRINTER
 &&从第2起打至第5页止

  2.如何计算总页数,以实现第?页/总?页
  在打印前根据细节区所打印的记录条数,先进行计算,然后再打印,具体代码:
PUBL mPAGE
SELE XXX
  &&xxx=供打印的数据表
XX=10
    &&XX=细节区所打印的记录条数
mPAGE=IIF(RECCOUNT()%XX=0,INT(RECCOUNT()/XX),INT(RECCOUNT()/XX)+1)

mPAGE
就是总页数,这样在需要总页数的地方就可直接引用mPAGE变量了。

  3.如何使报表打满一页
  如果打印的记录不足一页,页注脚会自动上移,影响报表的美观,解决的
办法和上面的差不多,即补足一页中所缺少的记录(补足空白记录):

SELE XXX
   &&xxx=供打印的数据表
XX=10
    &&XX=一页细节区所打印的记录条数
mI=RECCOUNT()%XX
   &&取得缺少的记录条数
FOR I=1 to mI
  APPEND BLANK
ENDF

  4.报表在设计时明明可以打印,可一安装到其他机器或重装系统后,就会出现
“XXX
带区太大不能放入页中等提示,而且无法正常退出(尤其是对自定义纸张
大小的程序),这是为什么呢?
  我们用报表设计器设计的打印程序,保存退出后,磁盘上就会出现 .frx.FRT
文件,我们的所有设计均保存在这两个文件中。在VFP .frx相当于.DBF表,.FRT
相当于.FPT备注型文件,我们用USE XXX.frx 可以象打开.DBF文件一样打开.frx
件,在.frx文件中有个Expr备注型字段名,在这个字段名中有如下内容:其中()内是
我所加的译文
======================================================================
RIVER=winspool
DEVICE=Epson LQ-1600K
OUTPUT=LPT1:
ORIENTATION=0
  
PAPERSIZE=256
      (纸张大小)
PAPERLENGTH=1000
    (纸张长度)
PAPERWIDTH=1600
     (纸张宽度)
DEFAULTSOURCE=8
     (默认来源)
PRINTQUALITY=180
    (打印质量)
COLOR=2
YRESOLUTION=180
TTOPTION=1
======================================================================
从这个Expr备注型字段里可以看出:PAPERSIZE=256 这里的256表示是自定义纸张,
如果:
PAPERSIZE=9
A411A5 具体数据见VFP帮助的Printfo()一节, 而:
PAPERLENGTH=1000
 (纸张长度)
PAPERWIDTH=1600
  (纸张宽度)
则分别代表自定义纸张的长度和宽度。 之所以会出现上面提到的问题,是因为系统重
新安装打印机后,WIN系统一般默认的是A4打印纸,与我们设计时保存在.frx文件里的
纸张不符,因而造成这种情况。 那么如何避免出现这个问题呢?
  下面是一段检测纸张类型的代码,供您参考:
这段代码必须放在执行report form ... 命令前。

use xxx.frx in 0 ALIAS mPrint
   &&在空闲工作区以mPrint别名打开xxx.frx文件
x=atcline('PAPERSIZE',mPrint.Expr)
 &&取得PAPERSIZEExpr字段中的行
sSIZE=subs(mline(mPrint.Expr,x),11) &&
取得设计时保存的纸张类型
mSIZE=allt(str(Prtinfo(2)))
    &&取得当前打印机默认的纸张类型
x=atcline('PAPERLENGTH',mPrint.Expr) &&
取得纸张长度在Expr字段中的行
sLEN=subs(mline(mPrint.Expr,x),13)
 &&取得纸张长度
x=atcline('PAPERWIDTH',mPrint.Expr)
 &&取得纸张宽度在Expr字段中的行
sWIDTH=subs(mline(mPrint.Expr,x),12) &&
取得纸张宽度
use in 'mPrint'
         &&关闭xxx.frx文件
if sSIZE=mSIZE
         &&如果相符,则正常打印
 report form xxx.frx to printer
else
 Messagebox('请设定打印机纸张为自定义:长='+sLEN+',='+sWIDTH,0+48+0,'提示')
 report form xxx.frx to printer prompt &&打印前先打开打印机设置对话窗口
endi

  5.不让打印的结果显示在屏幕上
report form xxx.frx to printer Noconsole

  6.打印或打印预览时,如何使系统打印工具条不出现
  系统提供的打印工具条,我们无法检测其各按钮的事件,不能掌握用户当时操
作的情况,那如何不让它出现呢?
  首先您得做一个表单(最好是模式表单),用于代替系统的预览窗口(Preview),然后:
do form dybd
          &&打开这个表单
report form xxx.frx windows dybd
  这样系统提供的打印工具条就不会出现了。
  当然如果自己再做个类似于打印工具条的类,既可掌握按钮事件又美观就更好了,
注:经查VFP3.0可能没有windows子句。

  很惭愧,我平时很少用VFP的报表设计器来编制打印程序(用其他语言代替的),
所以能谈的体会很少,十分希望这方面的高手能介绍您的经验,谢谢!

===================================

  我所写出的代码可能不是最合理和最精练的,只是提出一种思路或方法
供大家参考,希望能对您有所帮助。
 
------------------------------------------------ END ---------------

 

标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}