历史版本7 :SAP的RFC接口调用 返回文档
编辑时间:
内容长度:图片数:目录数:
修改原因:
SAP作为独立的系统,与其它系统进行交互的时候,主要是两种方式:1:底层数据库直接交互;2:通过SAP专门的RFC接口进行数据调用。
SAP现在主要的数据库平台有两种关系型数据库,Oracle和DB2,第一种方式FineReport通过JDBC的方式直连SAP数据库来解决,详细请查看数据库连接,但是使用这种方式,制作人员需要对SAP数据库了解比较深,并且数据库可以对其他软件开放。下面主要介绍第二种方式。
1. 设计思路编辑
首先通过java类文件建立和SAP的连接,然后通过程序数据集接口,将RFC调出来的数据进行虚拟二维表封装,调用虚拟二维表,进行报表的制作。
2. 实现步骤编辑
2.1 建立连接
通过ConnectSAPServer类实现与SAP的连接,类文件的代码如下:
package com.fr.function;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
public class ConnectSAPServer {
static String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
static {
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST,
"SAP服务器IP地址");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "系统编号");
connectProperties
.setProperty(DestinationDataProvider.JCO_CLIENT, "客户端编号(SAP中的,和客户端没关系)");
connectProperties.setProperty(DestinationDataProvider.JCO_USER,
"用户名");
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,
"密码");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ZH");
connectProperties.setProperty(
DestinationDataProvider.JCO_POOL_CAPACITY, "10");
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,
"10");
createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
}
static void createDataFile(String name, String suffix, Properties properties) {
File cfg = new File(name + "." + suffix);
if (!cfg.exists()) {
try {
FileOutputStream fos = new FileOutputStream(cfg, false);
properties.store(fos, "SAP连接配置文件");
fos.close();
} catch (Exception e) {
throw new RuntimeException(
"Unable to create the destination file "
+ cfg.getName(), e);
}
}
}
public static JCoDestination Connect() {
JCoDestination destination = null;
try {
destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
} catch (JCoException e) {
e.getCause();
}
return destination;
}
}
注:最新的代码链接fine-help。
2.2 程序数据集调用
- 定义程序数据集
数据库连接上之后,定义程序数据集,通过我们的程序数据源接口将数据转换成虚拟表,类文件具体代码如下:
package com.fr.data;
import com.fr.base.FRContext;
import com.fr.base.Parameter;
import com.fr.data.AbstractTableData;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoTable;
public class ParamSAPDataTest extends AbstractTableData
{
private String[] columnNames = null;
private int columnNum = 3;
private String[][] rowData;
private static JCoDestination jCoDestination;
public ParamSAPDataTest()
{
this.parameters = new Parameter[] { new Parameter("LIFNR"),
new Parameter("NAME1") };
this.columnNames = new String[this.columnNum];
this.columnNames[0] = "供应商编码";
this.columnNames[1] = "供应商名称";
this.columnNames[2] = "供应商地址";
}
public int getColumnCount() {
return this.columnNum;
}
public String getColumnName(int columnIndex) {
return this.columnNames[columnIndex];
}
public int getRowCount() {
try {
init();
}
catch (JCoException e) {
FRContext.getLogger().info("失败");
}
return this.rowData.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
try {
init();
}
catch (JCoException e) {
FRContext.getLogger().info("失败");
}
if (columnIndex >= this.columnNum) {
return null;
}
return this.rowData[rowIndex][columnIndex];
}
public void init() throws JCoException {
if (this.rowData != null) {
return;
}
try
{
jCoDestination = ConnectSAPServer.Connect();
}catch (Exception e) {
FRContext.getLogger().info("失败");
}
JCoFunction function = jCoDestination.getRepository().getFunction("Z_LFA3_QUERY");
if (function == null)
throw new RuntimeException(
"Function not found in SAP.");
function.getImportParameterList().setValue("LIFNR", "%"+this.parameters[0].getValue().toString().toUpperCase().trim()+"%");
function.getImportParameterList().setValue("NAME1", "%"+this.parameters[1].getValue().toString().toUpperCase().trim()+"%");
function.execute(jCoDestination);
JCoTable returnTable = function.getTableParameterList().getTable(
"ZLFA1S3");
rowData=new String[20][3];
if (returnTable.getNumRows() > 0) {
returnTable.firstRow();
for (int i = 0; i < 20; )
{
String[] objArray = new String[this.columnNum];
objArray[0] = returnTable.getString("LIFNR");
objArray[1] = returnTable.getString("NAME1");
objArray[2] = returnTable.getString("STRAS");
this.rowData[i]=objArray;
i++; returnTable
.nextRow();
}
FRContext.getLogger().info(
"Query SQL of ParamSAPDataTest: \n" + this.rowData.length +
" rows selected");
}
}
public void release() throws Exception {
super.release();
this.rowData = null;
}
}
注:最新的代码链接fine-help。
- 配置程序数据集
详细配置步骤请查看:简单程序数据集。
3. 总结编辑
通过RFC接口这种方式避免了直连数据库的问题,而这些RFC参数和调用表结构网上或者SAP供应商都会提供,不过缺点在于需要写类文件来获取数据,报表多的时候比较麻烦,如果要达到一些图表联动等效果,需要在类里面写参数,修改起来不是很方便,需要技术人员进行报表制作,业务人员比较困难。