帆软数据决策平台连接SAPRFC实例-创新互联

一、介绍

由于SAP ABAP开发出来的报表很单一,形式很有限,而且调整报表格式和形式都显得特别的鸡肋,所以现在将SAP系统通过RFC接口模式接入到帆软报表数据决策平台下展示。本文将详细介绍如何将数据从SAP传输到帆软平台上。

创新互联-专业网站定制、快速模板网站建设、高性价比万秀网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式万秀网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖万秀地区。费用合理售后完善,10多年实体公司更值得信赖。二、准备工作
  • 首先得先注册下载一个FineReport模板设计器,下载连接到官网下载就行。下载完之后傻瓜式安装,注意选择好自己的安装目录就行,这里不做介绍,有疑问的可以去帆软的官方文档看看。

  • 准备好编译JAVA文件的工具:JDK8,IDEA编译工具。JDK8去官网下载就行,下载完配置一下环境变量即可,这个教程我相信网上一抓一把,idea破解版网上也一大堆,这里我就不再啰嗦(若无idea编译工具留言博主给你发)

  • 准备java程序连接sap的jar包,没有的话这是链接,所需0积分,直接白嫖,下载解压出来就行。

三、开始整活 SAP模块

在SAP中先创建function接口,接口属性类型必须是 远程启用的模块

这是源码:

创建激活完成之后,重要的步骤来了,许多教程都没写这一步,这也是我为什么要多写这个教程的原因

先找相关管理人员开通RFC权限,首先确保你有RFC权限才能从sap获取数据。然后就是要创建RFC链接,教程如下:

事务码:SM59

创建RFC链接,填写连接名,链接类型选 3 为了搞懂这玩意我还特意去查了相关资料并整理起来(附:有关SAP RFC连接的相关知识点)根据各自需要选择类型,如果是新手练习跟着博主选 3 就行

填写目标主机的ip地址和实例号,这两个信息你在登录是就有,填进去即可,然后保存退出。

至此,SAP这块的工作就完成了

JAVA程序模块

前提:JDK8的配置已完成,有idea编译工具(其他的也行,博主用的是idea)

按照默认创建java项目就行,我们要的是 .class编译文件

然后创建工程目录,如下图:为了避免出错,请大家务必按照以下的目录创建,下面的目录也是帆软FineReport工程的目录,编译完成后我们需要将 .class文件迁移到FineReport工程目录下执行,为了避免包的路径有误,需要根据下面的来创建。

创建完成后,先拿一下连接程序所需的jar包:

红框就是我导进来的JAR包

在你安装FineReport模板设计器的目录下

%FineReport%\lib 全部包

%FineReport%\server\lib 全部包

%FineReport%\webapps\webroot\WBE-INF\lib 全部包

%JDK8%\lib\tools.jar JDK目录下的工具包

sapjco3.jar 这个是刚刚下载的连接sap的jar包,我是在工程目录下创建一个文件夹lib,把sapjco3.jar和sapjco3.dll两个文件都放里边了。

点击APPLY -点击 OK。

完成后,复制下面的代码,将自己的信息填上去,这是连接登录SAP的关键一步:

package com.fr.function;

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;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;

public class ConnectSAPServer
{
    static String ABAP_AS_POOLED = "ZFM_01";
    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,   "???");       //SAP用户名
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "?????");     //密码
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "zh");        //登录语言
        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");  //大连接数
        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,"10");     //大连接线程
//        connectProperties.setProperty(DestinationDataProvider.JCO_SAPROUTER, "");内网直接访问,无需配置SAP路由地址
        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, "for tests only !");
                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;
    }
}

这里说一下这个参数问题ABAP_AS_POOLED这个表示你刚刚创建的RFC连接名 类型为 3,博主刚开始就是傻乎乎的跟着别人填这玩意进去,ABAP_AS_POOLED = "ABAP_AS_POOLED",一直报错😭。其他信息的话照着填就行,DestinationDataProvider.JCO_SAPROUTER这个参数是路由地址,如果你的SAP是内网直连,没经过路由的话就不用配置,如果是走的路由,那就需要找管理人员要路由地址填上去即可。

这个文件是放在刚刚创建的function包下面。package com.fr.function;

还需要注意的是别导错包啦,害怕导错包的直接复制我的导包就行。

这一步完成后,在data包创建一个测试程序ParamSAPDataTestDemo,先测试一下能否能拿到数据

代码如下:

package com.fr.data;

import com.fr.function.ConnectSAPServer;

import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;

public class ParamSAPDataTestDemo  {
    public static void main(String[] args) throws JCoException {
        JCoDestination jCoDestination = ConnectSAPServer.Connect();
        jCoDestination.ping();
        System.out.println("连接sap成功");
        if (jCoDestination == null) System.out.println("jCoDestination is null , the program was end.");
        JCoFunction function = jCoDestination.getRepository().getFunction("ZFM_01"); //这是你在sap创建的函数接口名
        if (function == null) throw new RuntimeException("ZFM_01  not found in SAP.");
        //传入的参数
        function.getImportParameterList().setValue("INPUT_1",12);  // 传入的参数(大写)
        function.getImportParameterList().setValue("INPUT_2",12);  // 
        function.execute(jCoDestination);

        int result = function.getExportParameterList().getInt("RESULT");
        System.out.println("计算结果为:" + result);

    }
}

点击执行

输出如下结果:

至此,java程序连接SAP函数接口已实现。

帆软模块

对于以RFC连接SAP,帆软官网也有给出教程,但是太潦草了,对我来说用处不大,给大家奉上官网的教程连接,但是对于整合数据集还是挺有帮助的,下面是我整合数据集的代码实例,与上面的数据无关,仅供参考,有需要留言我再出一期教程详细说一下

package com.fr.data;

import com.fr.base.FRContext;
import com.fr.function.ConnectSAPServer;
import com.fr.stable.ParameterProvider;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoTable;

import java.util.ArrayList;

public class SAPParamDataTest extends AbstractTableData {
    private String[] columnNames = null;
    private int columnNum = 3;
    private String[][] rowData;
    private static JCoDestination jCoDestination;
    public SAPParamDataTest() {
        ArrayListarrayList = new ArrayList<>();
//        arrayList.add(new Parameter("LIFNR"));
//        arrayList.add(new Parameter("NAME1"));
//        this.parameters = new XmlColConf<>(arrayList, ParameterProvider.class);
        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("ZFM_01");
        if (function == null)
            throw new RuntimeException(
                    "Function not found in SAP.");
        function.execute(jCoDestination);
        JCoTable returnTable = function.getTableParameterList().getTable(
                "GT_ITAB");
        rowData = new String[returnTable.getNumRows()][3];
        if (returnTable.getNumRows() >0) {
            returnTable.firstRow();
            for (int i = 0; i< returnTable.getNumRows(); returnTable.nextRow()) {
                String[] objArray = new String[this.columnNum];
                objArray[0] = returnTable.getString("MATNR");
                objArray[1] = returnTable.getString("WERKS");
                objArray[2] = returnTable.getString("BESKZ");
                this.rowData[i] = objArray;
            }
            FRContext.getLogger().info(
                    "Query SQL of ParamSAPDataTest: \n" + this.rowData.length +
                            " rows selected");
        }
    }
    public void release() throws Exception {
        super.release();
        this.rowData = null;
    }

}

或者这样:

package com.fr.data;

import java.util.ArrayList;
import java.util.List;

import com.fr.function.ConnectSAPServer;

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 ParamSAPDataTestDemo extends SimpleTableData {
    @Override
    public String[] initColumnNames() {
        return new String[] {"物料编号","工厂","采购类型"};
    }

    @Override
    public ListloadData() {
        JCoDestination jCoDestination = ConnectSAPServer.Connect();
        if (jCoDestination == null) System.out.println("jCoDestination is null , the program was end.");
        JCoFunction function = null;
        try {
            function = jCoDestination.getRepository().getFunction("ZFM_01");
            function.execute(jCoDestination);
        } catch (JCoException e) {
            e.printStackTrace();
        }
        JCoTable returnTable = function.getTableParameterList().getTable("GT_ITAB");
        ArrayListvalueList = new ArrayList();
        if (returnTable.getNumRows() >0) {
            returnTable.firstRow();
            for (int i = 0; i< returnTable.getNumRows(); i++, returnTable.nextRow()) {
                String matnr = returnTable.getString("MATNR"); //物料编号
                String werks = returnTable.getString("WERKS"); //工厂
                String beskz = returnTable.getString("BESKZ"); //采购类型
                valueList.add(new Object[]{matnr,werks, beskz});
            }
        }
        return valueList;
    }

}

以上两个例子无需运行,编译一下就行,然后去工程目录下找.class文件

工程目录下的out文件夹下面的都是编译文件(.class)

找到对应路径下的文件即可

接下来打开FineReport模板设计器和目录,进入目录

%FineReport%\webapps\webroot\WEB-INF\classes\com\fr

在这个目录下可以找到data文件夹和function文件夹

把刚刚编译好的.class文件直接复制粘贴进来,若文件名重复点击覆盖就行

接下来还要导几个jar包进去FineReport目录下,否则程序报错:

sapjco3.jar 放在%FR_HOME%\lib路径下

sapjco3.dll 放在%FR_HOME%\jre\bin路径下

%JDK8%\lib\tools.jar JDK目录下的工具包 放到 %FR_HOME%\jre\lib

导完包之后,启动FineReport模板设计器,选择本地目录(默认目录)

新建模板

然后点击模板数据集- 程序

选择我们刚刚复制进去的 .class编译文件

点击确定

可以看到左侧已经有我们的数据集了

将数据拖动到模板的单元格里面

点击保存-预览效果

更多的报表展示方式博主还在学习中,请参考帆软的官网去学习如何使用帆软做报表

至此,流程就已经结束啦。总的思路就是,

先给SAP创建一个RFC连接接口和一个函数接口

然后用java程序连接这个RFC接口

最后用帆软去执行java程序的.class文件即可实现数据从SAP到帆软展示。

最后需要提醒一下的是JDK的版本不宜过高,jdk8就行,否则会有版本冲突问题。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文名称:帆软数据决策平台连接SAPRFC实例-创新互联
网页网址:http://csdahua.cn/article/psdej.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流