使用Java更改Crystal Reports中的多个表的Databaseconnection

时间:2012-01-23 07:44:33

标签: java crystal-reports

我们正在使用Crystal Reports XI,并且我使用一个表生成了一个简单的报告。在创建报告期间,我使用ODBC连接到我们的开发数据库。 现在我想在Java中运行时更改数据源,以便连接到我们的另一个数据库。

所以我创建了一个更改数据源的方法。因为我们使用不同的数据库系统(infomix,oracle和mysql)。

private ReportClientDocument replaceDatabaseConnection(ReportClientDocument doc,  Database database, String ip, String port, String dbname, String dbservername, String username, String passwort, String userOrSchemaName) {
    StopWatch sw = new StopWatch();
    try {       

        for (int i = 0; i < doc.getDatabaseController().getDatabase().getTables().size(); i++) {
            ITable table = doc.getDatabaseController().getDatabase().getTables().get(i);
            sw.start(table.getName());


            System.out.println("processing table : " + table.getName());

            // dbane.owner.tablename
            String original_qualifiedName = table.getQualifiedName();
            String new_qualifierName = original_qualifiedName;

            switch (database) {
            case ORACLE:
                // SCHEMA.TABLENAME
                String tableName = StringUtils.substringAfterLast(original_qualifiedName, ".").toUpperCase();
                new_qualifierName = userOrSchemaName.toUpperCase()+"."+tableName;
                break;
            case INFORMIX:
                // DATABASE.OWNER.TABLENAME
                new_qualifierName = dbname + ":" + userOrSchemaName + "." + StringUtils.substringAfterLast(original_qualifiedName, ".");                    

                break;
            case MYSQL:
                // DATABASE.OWNER.TABLENAME
                new_qualifierName = dbname + "." + userOrSchemaName + "." + StringUtils.substringAfterLast(original_qualifiedName, ".");                    
                break;
            default:
                break;
            }

            String jdbcConnectionString = null;
            String preQEServerName = null;
            String driver = null;

            switch (database) {
            case INFORMIX:
                // !com.informix.jdbc.IfxDriver!jdbc:informix-sqli://localhost:40421/export:INFORMIXSERVER=cargool1!user={userid}!password={password}
                jdbcConnectionString = "!com.informix.jdbc.IfxDriver!jdbc:informix-sqli://"+ip+":"+port+"/"+dbname+":INFORMIXSERVER="+dbservername+"!user={userid}!password={password}";
                // jdbc:informix-sqli://localhost:40421/export:INFORMIXSERVER=cargool1
                preQEServerName      = "jdbc:informix-sqli://"+ip+":"+port+"/"+dbname+":INFORMIXSERVER="+dbservername;
                // com.informix.jdbc.IfxDriver
                driver = "com.informix.jdbc.IfxDriver";
                break;
            case MYSQL:
                // !com.mysql.jdbc.Driver!jdbc:mysql://172.20.9.170:3306/hego
                jdbcConnectionString = "!com.mysql.jdbc.Driver!jdbc:mysql://"+ip+":"+port+"/"+dbname;
                // jdbc:mysql://172.20.9.170:3306/customer
                preQEServerName      = "jdbc:mysql://"+ip+":"+port+"/"+dbname;
                // com.mysql.jdbc.Driver
                driver = "com.mysql.jdbc.Driver";
                break;
            case ORACLE:
                // !oracle.jdbc.driver.OracleDriver!jdbc:oracle:thin:@//localhost:50000/tmsddb2
                jdbcConnectionString = "!oracle.jdbc.driver.OracleDriver!jdbc:oracle:thin:@//"+ip+":"+port+"/"+dbname;
                // jdbc:oracle:thin:@//localhost:50000/tmsddb2
                preQEServerName      = "jdbc:oracle:thin:@//"+ip+":"+port+"/"+dbname;
                // "oracle.jdbc.driver.OracleDriver"
                driver = "oracle.jdbc.driver.OracleDriver";
                break;
            default:
                break;
            }



    System.out.println("Qualfied Name : "+ table.getQualifiedName());
    table.setQualifiedName(new_qualifierName);

    ConnectionInfo newConnectionInfo = new ConnectionInfo();

    PropertyBag boPropertyBag1 = new PropertyBag();

    boPropertyBag1.put("JDBC Connection String", jdbcConnectionString);
    boPropertyBag1.put("PreQEServerName",   preQEServerName);
    boPropertyBag1.put("Server Type", "JDBC (JNDI)");
    boPropertyBag1.put("Database DLL", "crdb_jdbc.dll");
    boPropertyBag1.put("Database", dbname);
    boPropertyBag1.put("Database Class Name", driver);
    boPropertyBag1.put("Use JDBC", "true");
    boPropertyBag1.put("Database Name", dbname);
    boPropertyBag1.put("Server Name", preQEServerName);
    boPropertyBag1.put("Connection URL", preQEServerName);
    boPropertyBag1.put("Server", null);

    newConnectionInfo.setAttributes(boPropertyBag1);
    newConnectionInfo.setUserName(username);
    newConnectionInfo.setPassword(passwort);

    table.setConnectionInfo(newConnectionInfo);

            doc.getDatabaseController().setTableLocation(table, doc.getDatabaseController().getDatabase().getTables().get(i));
            System.out.println("***************************DONE********************************");
            sw.stop();
        }
        return doc;

    } catch (Exception ex) {
        System.out.println(ExceptionUtils.getFullStackTrace(ex));
    }


    System.out.println(sw.prettyPrint());

    return doc;

}

现在,如果我使用只有一个表的报表,那么stange行为是正常的。我可以毫无问题地连接到每个数据库,并且工作非常快。

但是如果报告有多个表,我会收到奇怪的数据库连接错误,即用户名/密码不正确。来自异常的用户名是完全错误的(它不是我传递给方法的用户名)。

  

com.crystaldecisions.sdk.occa.report.lib.ReportSDKLogonException:Fehler bei der Anmeldung:密码不正确或用户com.informix.asf.IfxASFRemoteException:数据库服务器上不知道username @ employee-nb1 .--- - 错误代码:-2147217393错误代码名称:dbLogonFailed

首先,我不想连接到informix数据库。我向方法传递了一个mysql参数。例外来自informix,它是我在创建报告期间连接到的数据库(通过ODBC)。

下一个奇怪的是用户名@ employee-nb1 用户名是我在创建报告时登录到数据库的用户名,最令人恼火的是emplyee-nb1。这是我们公司的一个笔记本的名称,但它与我无关。该报告从未在计算机上打开/创建,并且java进程也未在该计算机上运行。

就像我说的,如果我只使用一个表使用报告(以相同的方式创建),一切正常。有多个表,我收到此错误。我还没有使用任何子报告。

有人有想法吗?

这就是我调用方法的方法

    private void createReport8() {
    ReportClientDocument doc = new ReportClientDocument();

    try {
        doc.setReportAppServer(ReportClientDocument.inprocConnectionString);
        doc.open("C:\\dev\\reports\\003_jdbc_informix_3_tabellen.rpt",OpenReportOptions._openAsReadOnly);

        changeDataSource(doc, null, null, "username", "******", "!com.mysql.jdbc.Driver!jdbc:mysql://172.20.9.170:3306/customerdb", "com.mysql.jdbc.Driver", null);

        PDFExportFormatOptions outputOptions = new PDFExportFormatOptions();
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.PDF);
        exportOptions.setFormatOptions(outputOptions);

        InputStream stream = doc.getPrintOutputController().export(
                exportOptions);
        byte[] bytes = StreamUtils.getBytes(stream);

        FileUtils.writeByteArrayToFile(new File("C:\\dev\\reports\\pdf\\Infomix_MultipleTables001.pdf"), bytes);

    }catch (Exception ex) {
        System.out.println(ex);
    }
}

0 个答案:

没有答案