U8开发之打印控件.docx

上传人:b****6 文档编号:3326815 上传时间:2022-11-21 格式:DOCX 页数:68 大小:660.91KB
下载 相关 举报
U8开发之打印控件.docx_第1页
第1页 / 共68页
U8开发之打印控件.docx_第2页
第2页 / 共68页
U8开发之打印控件.docx_第3页
第3页 / 共68页
U8开发之打印控件.docx_第4页
第4页 / 共68页
U8开发之打印控件.docx_第5页
第5页 / 共68页
点击查看更多>>
下载资源
资源描述

U8开发之打印控件.docx

《U8开发之打印控件.docx》由会员分享,可在线阅读,更多相关《U8开发之打印控件.docx(68页珍藏版)》请在冰豆网上搜索。

U8开发之打印控件.docx

U8开发之打印控件

U8打印控件

摘要

打印控件是面向单据,列表,报表等多种业务场景的提供预览,打印,输出功能的公共控件。

什么是打印控件?

打印控件PrintControl是一个独立的,但同时又具有一定针对性的报表打印控件,它根据指定的XML格式文件(或字符串)对指定的XML数据文件(或字符串)进行格式化输出,本身基本不做任何数据的处理,不涉及任何业务逻辑,也不与任何数据库进行交互。

也就是说,一旦你对控件指定了源格式XML和数据XML,那么通过控件得到的打印预览输出和打印输出也就唯一确定了。

从这一点来看,本控件类似于IE、Mozilla等浏览器对纯HTML文本进行的解释。

PrintControl的格式化输出依赖与上述的两个XML文件(或字符串,下同,以后不再注明),任何报表或者其他类似文件,如果希望使用本控件来打印的话,都必须先将格式和数据分别组织成满足本控件预定义格式的XML文件。

PrintControl以ocx的形式封装,是一个进程内的COMServer,并支持嵌入到WEB中使用。

目标

本文的目标是介绍使用打印控件进行开发的基本流程已经各个接口,属性,事件的使用方法。

目标人群是使用打印控件的二开人员。

打印控件可以做什么?

如何使用打印控件?

1.环境准备

打印控件的编译和调适,需要安装VC6和2个sdk

1个是MicrosoftSDK(WindowsSDKNovember2001)

1个是FRAMEWORK2.0SDK

安装完后在VC6进行如下设置:

ToolsàOptionsàDirectoriesà选中Includefilesà加入2个sdk的路径:

再在此界面中选中LibraryFilesà加入2个sdk的lib路径:

然后就可以在VC6中打开PrintControl的工程,进行编译了。

打印控件的调试工程一般如下:

在一个文件夹中搁入U8PrintDataXML.log,U8PrintStyleXML.log,logPrintCtlTestor.exe

然后ProjectàSettingsàDebug,指向那个文件夹即可:

然后在工程中找到此函数CPrintControlCtrl:

:

SetDataStyleXML(此为打印控件入口函数)

和longCPrintControlCtrl:

:

PrintPreview()

下断点,然后F5运行。

先点Binddata,再点preview即可看到打印控件运行到断点处。

到时就可以调适了。

2.打印控件的程序流程

打印控件程序流程:

1,CPrintControlCtrl:

:

SetDataStyleXML绑定数据(在CPrintTask:

:

SetDataStyleXML中进行),数据由data和style2个xml串传进来。

组织成一个一个的Cgrid(在CPrintTask:

:

Compose中进行)。

2,CPrintControlCtrl:

:

PrintPreview()是弹出预览窗口的,它主要做2个操作,对数据进行分页运算;在弹出窗口中显示数据。

下面分别讲解这2个操作。

3,分页运算主要在CPrintTask:

:

DoPaginate()中进行。

主要是把Cgrid放在新构建CgridSlice中,然后根据Cgrid中取得的页面大小信息,把CgridSlice放到Cpage中。

这个的意义就是看一页纸(Cpage)中能放多少个表格(CgridSlice)。

然后通过此函数算出需要多少页纸。

并且每页纸上有多少表格的行和列(在此分页运算中找SetBeginRow,SetEndRow,SetHorzPageIndex,然后跟踪此函数即可慢慢体会到怎么算出来的)。

4,显示操作主要在voidCGridSlice:

:

Draw()中进行。

在此下断点可以很清晰地看到每页的各个部分是如何画出来的。

DrawTitle是画标题

DrawFormHeader是画表头

DrawFormBody是画表格

DrawFormBodyHeader画表格里面的表体头

DrawFormDataLine画表格里面的表体行

DrawFormBodyFooter画表格里面的表体尾

DrawFormFooter画表尾

5,分析下CGridSlice:

:

DrawFormHeader是怎样画表头的。

voidCGridSlice:

:

DrawFormHeader(CDC*pDC,constIAdapter&adapter)

{

//先得到表头的格式信息

CCommStyle*pHeaderStyle=&m_pGrid->GetPrintParam()->m_FormHeaderStyle;

//在格式信息中有此表头在此页是否打印的信息。

如果是不打印,则函数退出。

if(IsPrintableSlice(pHeaderStyle)==false)

{

return;

}

//得到表头的数据集合,具体数据是些什么,看SEGSTYLEARRAY的定义

LPSEGSTYLEARRAYpSegStyleArray=&m_pGrid->GetPrintParam()->m_HeaderSegStyleArray;

//创建字体

CFontbaseFont;

pHeaderStyle->CreateRatioFont(baseFont,adapter.GetDispRatio());

CFont*pOldFont;

CFontsegFont;

//枚举表头数据集合

for(inti=0;iGetSize();i++)

{

//得到其中一个表头数据

CSegStyle*pSegStyle=pSegStyleArray->GetAt(i);

//通过CsegStyle找到对应的表头字符串CSegment。

CSegment*pSegData;

if(pSegStyle->IsUnnamedSegment())

{

pSegData=m_pGrid->GetHeaderUnnamedSegment(i);

}

else

{

pSegData=m_pGrid->GetHeaderSegmentFormKey(pSegStyle->m_sKey);

}

if(pSegData==NULL)continue;

//创建字体

if(!

(pSegStyle->m_sFontName.IsEmpty()))

{

pSegStyle->CreateRatioFont(segFont,adapter.GetDispRatio());

pDC->SetTextColor(pSegStyle->m_color);

pOldFont=pDC->SelectObject(&segFont);

}

else

{

pDC->SetTextColor(pHeaderStyle->m_color);

pOldFont=pDC->SelectObject(&baseFont);

}

//得到表头数据的框的大小

CRectsegRect=pSegStyle->GetSegRect();

if(pSegStyle->m_bPageRightAlign==false&&pHeaderStyle->m_emAlignment==centeralign)

{

segRect.OffsetRect(m_pGrid->GetHeaderCenterOffsetX(),0);

}

//算出表头数据框的对应屏幕框

segRect=adapter.CalcScreenRect(segRect);

//有框,有字符串,则在对应的框中画出那个字符串

DrawSegment(pDC,pSegStyle,pSegData->m_sValue,segRect,adapter);

pDC->SelectObject(pOldFont);

}

}

6,分析下DrawFormDataLine画表格里面的表体行

在CGridSlice:

:

DrawDataLineCell下断点即可得到以下堆栈

CGridSlice:

:

DrawFormDataLine

CGridSlice:

:

DrawWithPolicy

CDataDrawerPolicy:

:

DrawCell

CGridSlice:

:

DrawDataLineCell

画表体行主要是通过上面的函数执行到此的。

此函数讲点重点的骨架即可:

//得到表体行的格式信息

CTableLineStyle*pStyle=&m_pGrid->GetPrintParam()->m_FormBodyStyle.m_DataLineStyle;

//得到表体行的数据信息(主要就是此单元格内的字符串是啥)

CDataCell*pData=m_pGrid->GetData(row,col);

//得到表体行的框位置(主要是通过Cgrid先前的计算分页信息所存贮信息运算得到)

CRectrect=m_pGrid->GetDataLineRect(row,col);

//有框,有字符串,就开始画这个单元格里面的字符串了

DrawCellWithStyle(pStyle,pDC,sCellData,rect,alignment);

7,画自定义表体

此运算主要是在CGridSlice:

:

Draw()函数中判断style这个xml串中是否有如下属性

<自定义表体是否启用="是">

if(pUDBodyStyle->m_bIsUsing==TRUE)

DrawFormUserDefineBody(pDC,*pAdapter);

else

DrawFormBody(pDC,*pAdapter);

如果有,则进行DrawFormUserDefineBody函数,它就是画自定义表体的。

此函数跟DrawFormBody类似,看懂前面1个,再看这个即可。

它最大的不同就是常规表体取框是通过m_pGrid->GetDataLineRect(row,col)的方式,而自定义表体的框的大小是在style这个xml串中自己指定的。

例如,如下一个

<自定义表体是否启用="是"行宽="1000"行高="325"打印表头="是">

<字段关键字="0"名字="业务类型"打印="是"字体名="Tahoma"字体大小="11"粗体="否"下划线="否"斜体="否"左顶点="0,0"宽="339"高="45"颜色="#000000"边框="15"/>

所以取框的大小是由这个函数搞定的:

CRectrect=m_pGrid->GetUDFormBodyHeaderRect(row,col,iUDLineindex);

看懂这里其它的就一起自然了。

无外乎取了框,再取了字符串,就可以画框,画字符串了。

8,关于那些style对应的数据结构。

在PrnParam.h中有很多对应表体头,表体行的数据结构。

有的是一层包一层。

不过其本质都是对style那个xml中的数据属性进行封装,这样那些属性就可以拿到控件里面用了。

可以先阅读PrnParam.h,里面注释很多,至少能告诉你那些数据结构的组成。

然后这些数据结构,大部分在SetDataStyleXML绑定数据时生成。

在ContentHandler.cpp随便找个解析xml的函数下断点,(比如CXMLStyleHandler:

:

parseFormBodyStyle)即可看到这个过程。

3.在VB中引用打印控件

VB中点击主菜单中的“工程->部件”或者直接按Ctrl+T热键,随后出现的“部件”对话框中选中“PrintControlActiveXControlmodule”,然后点击“确定”,左侧的工具条中将出现该控件的图标,如下图所示:

如下图:

需要注意的是,基于特定的理由,本控件取消了“运行时不显示”的特性,因此,为了防止运行时显示出控件本身的窗口,应该在控件的属性窗口中设定Visible为FALSE,如图:

OCX文件的方法函数图例如下

(vs2005的对象浏览器添加PrintControl.ocx即可)

4.打印控件接口介绍

1)SetDataStyleXML

为控件绑定格式和数据XML文件(或字符串)。

本方法是使用其他方法的先决条件(AboutBox方法除外)。

语法:

 

longSetDataStyleXML(constVARIANTFAR&varDataXML,

BOOLbDataIsFile,

constVARIANTFAR&varStyleXML,

BOOLbStyleIsFile,

constVARIANTFAR&varModuleID)

参数:

 

varDataXML

字符串

指明数据XML,含义由bDataIsFile决定。

bDataIsFile

布尔值

如果为True,表示varDataXML为数据XML文件的绝对路径或者相对路径;

如果为False,表示varDataXML为数据XML字符串本身。

varStyleXML

字符串指明格式XML,含义由bStyleIsFile决定。

bStyleIsFile

布尔值

如果为True,表示varStyleXML为格式XML文件的绝对路径或者相对路径;

如果为False,表示varStyleXML为格式XML字符串本身。

varModuleID

字符串

模版ID。

本参数可由调用者自由定义,用做开始打印时的打印任务名,可以为空,但

建议使用有意义的字符串标识打印任务。

 

返回值:

 

长整形,0表示成功,非0表示错误

调用控件的SetDataStyleXML方法的示例代码如下:

OptionExplicit

PrivateSubbtnBind_Click()

DimlRetAsLong

DimsDataAsString

DimsStyleAsString

DimsModuleIdAsString

sData=txtData.Text

sStyle=txtStyle.Text

sModuleId=txtModuleID.Text

lRet=printer.SetDataStyleXML(sData,True,sStyle,True,sModuleId)

MsgBoxlRet

EndSub

如果使用XML文件作为输入(上例中),那么sData和sStyle为文件的路径(绝对路径和相对路径均可),如果以XML字符串作为输入,那么sData和sStyle为XML字符串本身,同时第2和第四个参数应为False。

sModuleId为单据的模版名(注:

本控件使用该字符串作为打印任务名,并为使用者提供一个区别各类格式XML的标志)。

2)ExportToFileEx

将XML的内容输出到其他格式的文件(一般指文件型数据库),支持输出到rep文件(需要PrnExtension.DLL)。

 

语法:

 

longExportToFileEx(longlJobId,

constVARIANTFAR&varColType,

constVARIANTFAR&varColSize,

constVARIANTFAR&varColName,

constVARIANTFAR&varTempDBPath)

参数:

 

lJobId

长整形

指定需要输出的任务ID,即XML数据文件包含多个任务时的第几个任务,第一个任务ID为0。

varColType

字符串

该参数指定输出时各个字段的类型,各个字段类型之间用英文逗号“,”隔开,组成字段类型字符串,并且中间不能有空格。

例如:

”10,10,5,5”表示总共有4个字段,各字段类型分别为:

字符串(dbText)、字符串、货币(dbCurrency)和货币。

字段类型见“备注”部分。

该参数不能为空。

如果指定的字段类型个数不足,那么余下未指定类型的字段类型被认为是字符串类型(即10)。

注意:

该参数不能写成:

”dbText,dbText,dbCurrency,dbCurrency”。

varColSize

字符串

该参数指定各个字段的大小,同样,各个字段大小之间用英文逗号“,”隔开(中间不允许有空格),组成字段大小字符串,并与字段类型字符串相对应。

对应于前例,字段大小字符串为:

”50,50,8,8”,表示第一个文本型字段的大小为50字节,第二个文本型字段大小也为50字节,后两个货币金额型字段大小均为8个字节。

各字段类型对应的字段大小参见“备注”部分。

该参数不能为空。

如果指定的字段大小个数不足,那么余下未指定大小的字段被认为是254。

注意:

无论本参数或者上一个参数(varColType)是否指定了足够长的字段,两个参数指定的个数应该保持一致,例如都只指定了3项,否则将可能导致不可预知的错误。

varColName

字符串

该参数指定各个字段的字段名用于输出。

各个字段名之间用英文逗号“,”隔开(中间不能有空格,否则空格将被认为是字段名的一部分),组成字段名字符串。

注意各字段名不需要额外的引号。

例如:

”摘要,会计科目,贷方金额,借方金额”。

本参数可以为空字符串。

如果为空,那么控件将使用表体的表格头(即上部固定行)的最后一行个列的列名作为字段名用于输出。

如果本参数为非空字符串,并且指定的列数不足,那么未指定的列使用诸如“NO_NAME1”类似字段名进行输出。

VarTempDBPath

字符串

指定临时数据库(Access文件)的路径。

如果为空串,那么使用缺省数据库:

%System%\UFCOMSQL\UFFormat.mdb。

如果本参数非空,但指定的Access文件不存在,那么函数将创建该数据库(程序退出后并不会删除该库)。

指定的Access文件必须是Access97格式的,否则函数将产生错误。

返回值:

成功返回0,用户取消操作返回3999,其他为错误,参见“错误码”参考。

备注:

使用本方法之前必须先绑定格式和数据XML。

当控件属性ExportTableOnly被设置成FALSE时,调用本方法不仅输出表体的内容,还将输出表头和表尾的各个字段的内容。

无论是否仅输出表体,本方法的三个参数:

sColTypeList、sColSizeList、sColNameList都仅用于指定表体部分输出的字段类型,大小和字段名,而对于表头和表体的各个字段,输出格式均为字符串类型,255个字节大小,字段名为字段的关键字。

如果没有提供关键字,则自动生成字段名。

所有表头表尾字段输出时,其相应字段名都会增加“(表头)”或者“(表尾)”的后缀,以避免和表体部分的字段名名称冲突。

需要指出的是,输出时指定的数据库类型可能影响到输出是否成功。

这是因为各种类型的数据库对字段名长度,各种数据类型的支持程度和大小限制,单个表所允许的记录条数都有各自的限制。

字段类型定义如下:

♦dbBoolean=1,

♦dbByte=2,

♦dbInteger=3,

♦dbLong=4,

♦dbCurrency=5,

♦dbSingle=6,

♦dbDouble=7,

♦dbDate=8,

♦dbText=10,

♦dbLongBinary=11,(不支持)

♦dbMemo=12,

♦dbGUID=15,(不支持)

对应于以上各字段类型,有如下字段大小列表:

字段类型

字段大小

说明

dbBoolean

1(byte,下同)

Yes/No,同True/False

dbByte

1

Byte

dbInteger

2

Integer

dbLong

4

Long

dbCurrency

8

Currency

dbSingle

4

Single

dbDouble

8

Double

dbDate

8

Date/Time

dbText

1-255

Text(String)

dbLongBinary

0

LongBinary

dbMemo

0

Memo(String)

dbGUID

16

GUID

以上说明可以参看MSDN:

CDaoFieldInfo。

绑定了格式和数据之后,可以使用ExportToFile方法将数据中表体的内容导出到系统中已安装有ISAM驱动的文件型数据库中,例如dBase,Foxpro,Excel,HTML文件,Text文件,Lotus,Paradox,Access等,如以下示例代码:

PrivateSubbtnExport_Click()

DimsTypeListAsString

DimsSizeListAsString

DimiAsLong

DimeAsLong

i=0

sTypeList="10,10,5,5"

sSizeList="50,50,8,8"

e=printer.ExportToFileEx(i,sTypeList,sSizeList,"","")

MsgBoxe

EndSub

该方法将XML数据文件中表体的内容根据指定的字段类型,字段大小和字段名(如果没有提供字段名,将使用表格头固定行最后一行的各列名作为字段名)导出到用户指定的其他格式文件。

该方法将弹出一个文件保存对话框,在这个对话框中,用户可以选择导出文件类型并填写文件名,如下图所示:

3)PageSetup

显示页面设置对话框,允许用户在打印或预览前,以及预览过程中对打印机设置,纸张设置,以及页面各个元素的格式进行调整。

语法:

LongPageSetup()

参数:

返回值:

长整形,0表示成功,-1表示用户点击“取消”按钮返回,非0表示错误,具体请参“错误码”参考。

备注:

使用本方法之前必须先绑定格式和数据XML。

绑定完数据和格式之后可以使用PageSetup方法进行页面设置,如以下示例代码:

PrivateSubbtnPageSetup_Click()

printer.PageSetup

EndSub

以上方法将显示如下所示的对话框:

在本对话框中可以设置各种打印格式。

4)PrintPreview

显示打印预览窗口。

语法:

longPrintPreview();

参数:

返回值:

长整形,0表示成功,非0表示错误,参见“错误码”参考。

备注:

使用本方法之前必须先绑定格式和数据XML。

绑定了格式和数据以后,可以使用PrintPreview方法查看打印预览,如以下示例代码:

PrivateSubbtnPr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1