1、 XML Publisher数据引擎:
XML Publisher数据引擎是由Java并发程序实现的,其实现类为:oracle.apps.xdo.oa.cp. JCP4XDODataEngine。通过这个数据引擎,我们制作报表的时候只需要传入一个xml的数据模板和一个rtf的模板就可以实现报表打印。
1、 XML Publisher数据引擎:
XML Publisher数据引擎是由Java并发程序实现的,其实现类为:oracle.apps.xdo.oa.cp. JCP4XDODataEngine。通过这个数据引擎,我们制作报表的时候只需要传入一个xml的数据模板和一个rtf的模板就可以实现报表打印。
通过XML Publisher数据引擎输出报表过程如下:
(1)、制作数据模板(下文有介绍)并上传
(2)、制作rtf模板并上传
(3)、定义并发程序(注:这里并发程序简称必须跟数据定义的简称相同。)
并发可执行选XDODTEXE,这个是XML Publisher数据引擎的入口。
参数如下:(注意:此处的变量跟数据模板中定义的变量名一样)
数据引擎实现逻辑如下:
从数据引擎的实现流程中我们可以看到,主要用到两个类CpContext、DataTemplate。关于CpContext的介绍参见报告提交平台上面我的另外一篇文章《Oracle.apps.fnd.cp.request包常用java类分析》。DataTemplate的介绍本文后面有介绍。
2、 数据模板
介绍:XML Publisher的数据引擎能够让你以可扩展、高效率的方式从任何数据库中生成任何类型的XML数据。数据模板就是你请求的数据和数据引擎之间通信的方法。数据模板是一个XML文件,它定义了数据引擎怎样通过数据模板生成XML数据文件。
其结构如下图:
(1)、标签有属性:name、description、version、defaultPackage、dataSourceRef。
name属性对应生成xml文件的顶层标签
description属性为数据模板名的描述
version版本,一般给1.0
defaultPackage可以让数据模板和PL/SQL进行通信
dataSourceRef可以指定数据来源,这个数据来源可以是xml文件,其他的数据库数据等。
(2)、标签有属性:include_parameters、include_null_Element、xml_tag_case、db_fetch_size、scalable_mode、include_rowsettag、debug_mode。
include_parameters属性定义xml输出中是否包含参数信息,默认为true
include_null_Element属性定义xml输出中是否包含空元素,默认为true
xml_tag_case属性定义xml输出的标签大小写(upper,lower,as_are),默认为upper
db_fetch_size属性定义一次jdbc连接取出多少行数据,默认为500。如果是包含很多列数据量大的查询,设置这个值为20,否则内存占用量会明显增加。
scalable_mode属性指定数据引擎采用scalable模式执行。当处理大量数据的时候这个是需要设置成on,默认情况是off
include_rowsettag属性允许在输出中包含或者执行Rowset标签。默认为true
debug_mode属性指定是否开启调试,默认off。
(3)、标签有属性:name、dataType、defaultValue、include_in_output。
name属性定义了参数的名字,这个参数可以在下面的sqlStatement中引用,引用方式”:参数名”。
dataType属性定义了参数类型,支持3种:"character","date", "number"。默认为"character"。
defaultValue属性给定参数的默认值
include_in_output属性设置参数是否在xml输出文件中出现。可选true或者false
另外可以直接访问PL/SQL包里面定义的变量,访问方式”&变量名”
(4)、标签有属性:name、dataSourceRef。
name属性给sql语句执行一个唯一的名字来标识
dataSourceRef属性同标签的dataSourceRef属性,如果这里有定义,则其优先级高于标签dataSourceRef所定义的数据来源引用
标签有属性name、expressionPath和子标签。
name属性定义唯一性标识
expressionPath属性可以把SQL查询和xml数据连接起来进行操作
指定访问的xml文件的路径
例如:
password="">file:///d:/dttest/employee.xml
(5)、标签有属性:name、parentQuery、parentColumn、childQuery、childColumn、condition。
name属性定义连接的唯一性标识
link标签指定parentQuery的parentColumn和childQuery的childColumn按照condition条件进行连接。
condition条件包括=, , >=
标签有属性name、source。
name属性定义了什么事件出发:beforeReportTrigger、afterReportTrigger
source属性定义了出发代码:.
(6)、标签有属性:name、source
name属性定义xml输出的第三层标签标签的name属性值>,第二层标签为标签的name属性值>。
source属性定义了来源于哪个sqlStatement,必须为sqlStatement的name属性。
(7)、标签有属性:name、value
name属性即为xml输出的标签名字
value属性即为xml输出的标签的值
对element标签还支持统计、有属性name、source、函数(SUM(), AVG(), COUNT(), MAX(),
and MIN())
例如:
表示对G_EMP这个dataSource(某个sqlStatement的name)的SALARY字段进行SUM()。
(8)、另外在>标签支持弹性域的用法(没仔细研究过,不敢乱写)。
(9)、下面以采购订单打印为例来说明数据模板的使用:
需求:开发一个并发请求,打印采购订单头、行信息,传入参数有:采购订单从、采购订单至、采购员、供应商。
开发步骤:
①、准备好参数定义:
<parameters>
name="in_header_id_from" dataType = "number">
name="in_header_id_to" dataType = "number">
name="iv_buyer_id" dataType = "number">
name="iv_supplier_id" dataType = "number">
parameters>
②、准备好sql语句:
采购订单头:
SELECT poh.ROWID row_id,
poh.segment1 po_number,
pv.vendor_name vendor_name,
hrl.location_code bill_to,
poh.attribute1 attribute1,
poh.attribute2 attribute2,
poh.comments description,
poh.attribute3 attribute3,
poh.attribute4 attribute4,
poh.attribute5 attribute5,
poh.attribute6 attribute6,
poh.attribute7 attribute7,
poh.attribute8 attribute8,
poh.attribute9 attribute9,
poh.attribute10 attribute10,
poh.attribute11 attribute11,
poh.attribute12 attribute12,
pvs.address_line1 vendor_address,
pvs.zip vendor_zip,
poh.vendor_contact_id vendor_contact_id,
poh.terms_id term_id
FROM po_headers_all poh,
po_vendors pv,
po_vendor_sites_all pvs,
hr_locations_all_tl hrl
WHERE poh.vendor_id = pv.vendor_id
AND poh.vendor_id = pvs.vendor_id
AND hrl.location_id = poh.ship_to_location_id
AND poh.org_id = pvs.org_id
AND poh.agent_id = nvl(:iv_buyer_id, poh.agent_id)
AND pvs.purchasing_site_flag = 'Y'
AND poh.type_lookup_code = 'STANDARD'
AND hrl.LANGUAGE = userenv('LANG')
AND poh.po_header_id >= nvl(:in_header_id_from, poh.po_header_id)
AND poh.po_header_id <= nvl(:in_header_id_to, poh.po_header_id)
AND pv.vendor_id = nvl(:iv_supplier_id, pv.vendor_id)
AND poh.org_id = nvl(mo_global.get_current_org_id(), poh.org_id)
ORDER BY poh.po_header_id
采购订单行:
SELECT (SELECT segment1
FROM mtl_system_items_b
WHERE inventory_item_id = pol.item_id
AND organization_id = poh.org_id) item_num,
pol.item_description item_name,
to_char(pol.quantity) quantity,
to_char(pol.unit_price) unit_price,
to_char(pol.quantity * pol.unit_price) line_sum,
pol.note_to_vendor line_remarks
FROM po_headers_all poh, po_lines_all pol
WHERE poh.ROWID = :row_id -- 这个row_id为PO采购行的row_id
AND poh.po_header_id = pol.po_header_id
③、定义xml输出的标签
<group name="G_PO_HEADERS" source="Q_PO_HEADERS">
<element name="PO_NUMBER" value="po_number"/>
<element name="VENDOR_NAME" value="vendor_name"/>
<element name="BILL_TO" value="bill_to"/>
<element name="ATTRIBUTE1" value="attribute1"/>
<element name="ATTRIBUTE2" value="attribute2"/>
<element name="DESCRIPTION" value="description"/>
<element name="ATTRIBUTE3" value="attribute3"/>
<element name="ATTRIBUTE4" value="attribute4"/>
<element name="PAYMENT_TERM" value="term_id"/>
<element name="ATTRIBUTE5" value="attribute5"/>
<element name="ATTRIBUTE6" value="attribute6"/>
<element name="ATTRIBUTE7" value="attribute7"/>
<element name="VENDOR_ADDRESS" value="vendor_address"/>
<element name="VENDOR_ZIP" value="vendor_zip"/>
<element name="VENDOR_PHONE" value="vendor_contact_id"/>
<element name="VENDOR_FAX" value="vendor_contact_id"/>
<group name="G_PO_LINES" source="Q_PO_LINES">
<element name="ITEM_NUM" value="item_num"/>
<element name="ITEM_NAME" value="item_name"/>
<element name="QUANTITY" value="quantity"/>
<element name="UNIT_PRICE" value="unit_price"/>
<element name="LINE_SUM" value="line_sum"/>
<element name="LINE_REMARKS" value="line_remarks"/>
group>
group>
④、将这三部分按照数据模板定义的要求组合起来就是下面这个数据模板文件:
<?xml version="1.0" encoding="UTF-8" ?>
name="CUXPOTEST" version="1.0" description="cux abc test">
<parameters>
name="in_header_id_from" dataType = "number">
name="in_header_id_to" dataType = "number">
name="iv_buyer_id" dataType = "number">
name="iv_supplier_id" dataType = "number">
name="iv_date_from" dataType = "date">
name="iv_date_to" dataType = "date">
parameters>
name="Q_PO_HEADERS">
SELECT poh.ROWID row_id,
poh.segment1 po_number,
pv.vendor_name vendor_name,
hrl.location_code bill_to,
poh.attribute1 attribute1,
poh.attribute2 attribute2,
poh.comments description,
poh.attribute3 attribute3,
poh.attribute4 attribute4,
poh.attribute5 attribute5,
poh.attribute6 attribute6,
poh.attribute7 attribute7,
poh.attribute8 attribute8,
poh.attribute9 attribute9,
poh.attribute10 attribute10,
poh.attribute11 attribute11,
poh.attribute12 attribute12,
pvs.address_line1 vendor_address,
pvs.zip vendor_zip,
poh.vendor_contact_id vendor_contact_id,
poh.terms_id term_id
FROM po_headers_all poh,
po_vendors pv,
po_vendor_sites_all pvs,
hr_locations_all_tl hrl
WHERE poh.vendor_id = pv.vendor_id
AND poh.vendor_id = pvs.vendor_id
AND hrl.location_id = poh.ship_to_location_id
AND poh.org_id = pvs.org_id
AND poh.agent_id = nvl(:iv_buyer_id, poh.agent_id)
AND pvs.purchasing_site_flag = 'Y'
AND poh.type_lookup_code = 'STANDARD'
AND hrl.LANGUAGE = userenv('LANG')
AND poh.po_header_id >= nvl(:in_header_id_from, poh.po_header_id)
AND poh.po_header_id <= nvl(:in_header_id_to, poh.po_header_id)
AND pv.vendor_id = nvl(:iv_supplier_id, pv.vendor_id)
AND poh.org_id = nvl(mo_global.get_current_org_id(),poh.org_id)
ORDER BY poh.po_header_id
]]>
name="Q_PO_LINES">
SELECT (SELECT segment1
FROM mtl_system_items_b
WHERE inventory_item_id = pol.item_id
AND organization_id = poh.org_id) item_num,
pol.item_description item_name,
to_char(pol.quantity) quantity,
to_char(pol.unit_price) unit_price,
to_char(pol.quantity * pol.unit_price) line_sum,
pol.note_to_vendor line_remarks
FROM po_headers_all poh, po_lines_all pol
WHERE poh.ROWID = :row_id
AND poh.po_header_id = pol.po_header_id
]]>
<group name="G_PO_HEADERS" source="Q_PO_HEADERS">
<element name="PO_NUMBER" value="po_number"/>
<element name="VENDOR_NAME" value="vendor_name"/>
<element name="BILL_TO" value="bill_to"/>
<element name="ATTRIBUTE1" value="attribute1"/>
<element name="ATTRIBUTE2" value="attribute2"/>
<element name="DESCRIPTION" value="description"/>
<element name="ATTRIBUTE3" value="attribute3"/>
<element name="ATTRIBUTE4" value="attribute4"/>
<element name="PAYMENT_TERM" value="term_id"/>
<element name="ATTRIBUTE5" value="attribute5"/>
<element name="ATTRIBUTE6" value="attribute6"/>
<element name="ATTRIBUTE7" value="attribute7"/>
<element name="VENDOR_ADDRESS" value="vendor_address"/>
<element name="VENDOR_ZIP" value="vendor_zip"/>
<element name="VENDOR_PHONE" value="vendor_contact_id"/>
<element name="VENDOR_FAX" value="vendor_contact_id"/>
<group name="G_PO_LINES" source="Q_PO_LINES">
<element name="ITEM_NUM" value="item_num"/>
<element name="ITEM_NAME" value="item_name"/>
<element name="QUANTITY" value="quantity"/>
<element name="UNIT_PRICE" value="unit_price"/>
<element name="LINE_SUM" value="line_sum"/>
<element name="LINE_REMARKS" value="line_remarks"/>
group>
group>
⑤、接下来定义rtf模板,然后按照本文开始的数据引擎的介绍那样上传文件,定义并发程序就ok了。
3、 XML Publisher相关API
Oracle XML Publisher 主要 OA Java API
oracle.apps.xdo.oa.schema.server.DataSource
数据定义基本信息类。
通过静态方法DataSource.createInstance(oracle.apps.fnd.common.AppsContext pContext, java.lang.String pAppName, java.lang.String pCode)创建DataSource实例,其实例可以通过如下方法取得和设置数据定义基本信息:
getAppName:取得应用简称
getCode:取得数据定义代码
set/getDescription:设置/取得数据定义说明
set/getEndDate:设置/取得数据定义终止日期
getLanguage:取得当前会话的语言
set/getName:设置/取得数据定义名称
set/getStartDate:设置/取得数据定义开始日期
set/getStatus:设置/取得数据定义状态。
oracle.apps.xdo.oa.schema.server.DataSourceHelper
对数据定义操作的类的容器、该类的方法全部是静态方法,通过类直接调用。其方法主要实现了对数据模板文件、xml模式文件、数据定义实体的基本操作。
addSchemaFile/SampleFile、createDataSource:添加操作
deleteSchemaFile/SampleFile、deleteDataSource:删除操作
getSchemaFile/SampleFile、getDataSource:获取操作
updateSchemaFile/SampleFile、updateDataSource/DataSourceStatus:更新操作。
oracle.apps.xdo.oa.util.DataTemplate
数据模板处理类
DataTemplate dataTemplate = new DataTemplate(oracle.apps.fnd.common.AppsContext pContext,java.lang.String pApplicationShortName,java.lang.String pDataSourceCode, boolean scalableMode)
DataTemplate对象有如下方法:
set/getParameters:获取设置数据模板的xml文件中定义的参数
setOutput:设置数据模板文件处理后生成的xml文件
processData:处理数据模板,生成xml文件。
oracle.apps.xdo.oa.schema.server.Template
模板基本信息类
通过静态方法createInstance(oracle.apps.fnd.common.AppsContext pContext, java.lang.String pAppName, java.lang.String pCode, java.lang.String pType, java.lang.String pDsAppName, java.lang.String pDsCode)创建Template实例,其实例可以通过如下方法取得和设置模板基本信息:
getAppId:返回模板所在的应用的app id
getAppName:取得模板所在应用的应用简称
getCode:模板code
set/getDefaultLanguage:获取/设置默认语言
set/getDefaultTerritory:获取/设置默认地区
set/getDependencyFlag:获取/设置是否有子模板
set/getDescription:获取/设置描述
set/getDsAppName:获取/设置模板的数据定义的应用所在的简称
set/getDsCode:获取/设置模板的数据定义的code
set/getEndDate:获取/设置终止日期
set/getLanguage:获取/设置当前session的语言code(FND_LANGUAGES表中定义的)
set/getName:获取/设置模板名称
set/getStartDate:获取/设置开始日期
set/getStatus:获取/设置状态
getType:返回模板类型中的一种
TypeDefinitions.TEMPLATE_TYPE_PDF,
TypeDefinitions.TEMPLATE_TYPE_XSL_FO,
TypeDefinitions.TEMPLATE_TYPE_RTF,
TypeDefinitions.TEMPLATE_TYPE_XSL_HTML,
TypeDefinitions.TEMPLATE_TYPE_XSL_TEXT,
TypeDefinitions.TEMPLATE_TYPE_XSL_XML,
TypeDefinitions.TEMPLATE_TYPE_XLS
oracle.apps.xdo.oa.schema.server.TemplateHelper
对模板操作的类的容器、该类的方法全部是静态方法,通过类直接调用。其方法主要实现了对模板的基本操作。
add/copy/create/delete/update/TemplateFile:模板文件的操作
add/copy/create/delete/process/updateTemplate:模板容器对模板的操作。
Oracle XML Publisher 主要 Core Java API
oracle.apps.xdo.dataengine.DataProcessor
将数据模板转换成xml数据的数据处理。主要方法如下:
set/getParameters:设置获取xml数据模板参数
set/getDataTemplate:设置获取xml数据模板文件
setConnection/setDistributedConnections:设置jdbc连接和分布式查询jdbc连接
setOutput:设置xml输出输出
processData:处理数据模板文件生成xml输出文件
oracle.apps.xdo.dataengine.Parameter
数据模板中参数处理。主要方法如下:
getDataType:获取参数数据类型
set/getDefaultValue:设置/获取参数默认值
set/getName:设置/获取参数名称
set/getValue:设置/获取参数值
oracle.apps.xdo.template.RTFProcessor
将rtf模板文件转换成xsl文件。主要方法如下:
构造方法RTFProcessor processor = new RTFProcessor("rtf文件名/输入流")
getUserParameters:获取rtf模板中的参数
process:将rtf模板转换成xsl文件
setOutput:设置xsl文件输出
oracle.apps.xdo.template.FOProcessor
组合xsl和xml生成AWT、EXCEL、FO、HTML、PDF等格式的文件。主要方法如下:
setData:设置xml数据
setOutput:设置输出文件
setOutputFormat:设置输出文件格式,包括如下格式:
FOProcessor.FORMAT_AWT
FOProcessor.FORMAT_EXCEL
FOProcessor.FORMAT_FO
FOProcessor.FORMAT_HTML
FOProcessor.FORMAT_PDF
setTemplate:设置xsl文件
generate:结合xml数据和模板生成指定输出文件格式的文件。
下面结合上面知识来实现分布式查询的报表打印。
业务需求:某公司部门信息存放在数据库A中,人员信息存放在数据库B中,开发一个并发程序实现按部门打印公司人员。(这里并发程序就不能使用标准数据引擎,需要自己结合现有的XML Publisher的API来实现分布式查询报表的打印)
这里数据库B为MySQL,数据库A为EBS的Oracle数据库。开发工具我选用Eclipse。
1、创建数据表脚本如下:
(Oracle)部门表:
DROP TABLE cux.cux_test_dept;
CREATE TABLE cux.cux_test_dept
(
dept_id NUMBER,
dept_name VARCHAR2(200),
dept_phone VARCHAR2(100)
);
DROP SYNONYM cux_test_dept;
CREATE SYNONYM cux_test_dept FOR cux.cux_test_dept;
插入初始数据:
(MySQL)员工表:
DROP TABLE IF EXISTS `test`.`employee`;
CREATE TABLE `test`.`employee` (
`id` int(10) unsigned NOT NULL auto_increment,
`dept_id` int(10) unsigned NOT NULL,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`full_name` varchar(45) NOT NULL,
`age` int(10) unsigned NOT NULL,
`sex` varchar(1) NOT NULL,
`emp_no` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
插入初始数据:
2、编写数据模板文件
<?xml version="1.0" encoding="UTF-8" ?>
SELECT
dept_id DEPT_ID,
dept_name DEPT_NAME,
dept_phone DEPT_PHONE
from
cux_test_dept
]]>
SELECT
emp_no EMPLOYEE_NUMBER,
first_name FIRST_NAME,
last_name LAST_NAME,
full_name FULL_NAME,
age AGE,
sex SEX
FROM
test.employee
where dept_id = EPT_ID
]]>
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21704144/viewspace-1060907/,如需转载,请注明出处,否则将追究法律责任。
<%=items[i].content%>
<%if(items[i].items.items.length) { %><%=items[i].items.items[j].username%> 回复 <%=items[i].items.items[j].tousername%>: <%=items[i].items.items[j].content%>
转载于:http://blog.itpub.net/21704144/viewspace-1060907/