Crystal 报告从 XML 创建报告并将其导出为 PDF 而无需原始 XML 的路径

Crystal reports creating report from XML and exporting it to PDF without needing path to original XML

我有一个 Java 导出 pdf 文件的 Web 应用程序。

我必须使用 Crystal Reports 11。我已经可以导出 pdf,问题是它只能在本地工作,因为 .rpt 文件引用了我机器中的 XML 文件。

因此,当我想要导出报告并且 .rpt 文件找不到该文件时,即使我给它一个新的数据集来处理它仍然会抛出一个未找到的异常。我尝试以编程方式更改文件的连接,但它总是抛出与连接相关的异常。

public InputStream export() throws ReportSDKException, IOException, IllegalArgumentException, IllegalAccessException {
        ReportClientDocument reportClientDoc = new ReportClientDocument();
        reportClientDoc.setLocale(Locale.forLanguageTag(localeTag));
        reportClientDoc.open(reportPath, OpenReportOptions._discardSavedData);
        DatabaseController databaseController = reportClientDoc.getDatabaseController();

        IConnectionInfo oldConn = databaseController.getConnectionInfos(null).get(0);
        IConnectionInfo newConn = resolveConnection(reportClientDoc).get(0);

        int replaceParams = DBOptions._ignoreCurrentTableQualifiers | DBOptions._doNotVerifyDB;
        databaseController.replaceConnection(oldConn, newConn, null,replaceParams);

        reportClientDoc.getDatabaseController().setDataSource(this.dataset);
        ParameterFieldController parameterController = reportClientDoc.getDataDefController()
                .getParameterFieldController();
        for (Param<Double> p : doubleParams) {
            parameterController.setCurrentValue(p.subReportName, p.fieldName, p.value);
        }

        for (Param<Object> p : objectParams) {
            parameterController.setCurrentValue(p.subReportName, p.fieldName, p.value);
        }

        return reportClientDoc.getPrintOutputController().export(this.format);
    }

private ConnectionInfos resolveConnection(ReportClientDocument reportClientDoc) throws ReportSDKException {
        IConnectionInfo oldConnection = new ConnectionInfo();
        DatabaseController dbController = reportClientDoc.getDatabaseController();
        oldConnection = dbController.getConnectionInfos(null).getConnectionInfo(0);

        String xsdPath = Paths.get(this.xsdPath).toAbsolutePath().toString();

        final String SERVER_NAME = dummyXmlPath + " " + xsdPath;
        final String DATABASE_DLL = oldConnection.getAttributes().getStringValue("Database DLL");
        final String LOCAL_SCHEMA_FILE = xsdPath;
        final String SERVER_TYPE = "XML";
        final String PREQESERVERNAME = SERVER_NAME;
        final String PREQESERVERTYPE = "XML";
        final String LOCAL_XML_FILE = dummyXmlPath;

        PropertyBag newAttributes = new PropertyBag();
        newAttributes.put("Server Name", SERVER_NAME);
        newAttributes.put("Database DLL", DATABASE_DLL);
        newAttributes.put("Local Schema File", LOCAL_SCHEMA_FILE);
        newAttributes.put("PreQEServerName", PREQESERVERNAME);
        newAttributes.put("PreQEServerType", PREQESERVERTYPE);
        newAttributes.put("Server Type", SERVER_TYPE);
        newAttributes.put("Local XML File", LOCAL_XML_FILE);

        IConnectionInfo newConnection = (IConnectionInfo) oldConnection.clone(true);
        newConnection.setAttributes(newAttributes);
        newConnection.setKind(oldConnection.getKind());

        ConnectionInfos connectionInfos = new ConnectionInfos();
        connectionInfos.add(newConnection);
        return connectionInfos;
    }

我能够通过将子报表数据添加到子报表来解决这个问题。

SubreportController subreportController = reportClientDoc.getSubreportController();
for (String string : subreportController.querySubreportNames()) {
    subreportController.setDataSource(string, dataset);
}