Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CxReports Java API Client

Overview

The CxReports Java API Client provides a comprehensive, easy-to-use interface for interacting with the CxReports API. This library allows developers to preview reports, download reports as PDFs, manage workspaces, handle temporary data, perform asynchronous document exports, and execute batch job workflows with full Java 11+ support.

Features

  • Authentication with API tokens and nonce tokens
  • Asynchronous operations using CompletableFuture
  • Preview reports by ID or type
  • Download reports as PDF, HTML documents, PowerPoint slides, Excel sheets or Word documents (sync and async)
  • Fetch workspaces, reports, and report types
  • Temporary data storage for report export
  • Background document export with status monitoring
  • Job management and batch processing workflows
  • Job run execution, monitoring, and delivery
  • Built-in error handling and URI management
  • Timezone support for date/time operations

Requirements

  • Java 11 or higher
  • HTTP Client with set up permissions and certificates

Installation

Add the dependency to your project:

Maven:

<dependency>
    <groupId>com.cx-reports</groupId>
    <artifactId>api-client</artifactId>
    <version>0.1.0</version>
</dependency>

Usage

Initializing the Client

import com.cxreports.api.v1.CxReportsClient;
import java.net.http.HttpClient;
import java.time.Duration;

// Create HTTP client with custom configuration
HttpClient httpClient = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(10))
    .build();

// Initialize the CxReports client
CxReportsClient client = new CxReportsClient(
    "https://your-cxreports-server.com",  // Base URL
    "your-personal-access-token",         // Auth Token
    123,                                  // Default Workspace ID
    "DEFAULT_WS",                        // Default Workspace Code
    "UTC",                               // Default Timezone
    httpClient                           // HTTP Client
);

Working with the Client

Getting reports visible to the authorized user

import com.cxreports.api.v1.models.*;

// Get all reports from default workspace
Report[] allReports = client.getReportsAsync(null, null).get();

// Get reports filtered by report type
WorkspaceKey workspace = new WorkspaceKey(456); // or new WorkspaceKey("WS_CODE")
CompletableFuture<Report[]> filteredReports = client.getReportsAsync(
    workspace,    // Workspace (null for default)
    "invoice"     // Report type filter (null or blank for all types)
);

Getting report types

Report types represent categories of reports and can be used for report discovery and UI organization.

// Get all report types from default workspace
ReportType[] reportTypes = client.getReportTypes(null).get();

// Get report types from specific workspace
WorkspaceKey workspace = new WorkspaceKey(456);
ReportType[] workspaceTypes = client.getReportTypes(workspace).get();

// Each ReportType includes:
// - code: unique identifier
// - name: human-readable name
// - description: type description
// - defaultReport: associated default report metadata

Getting themes and report templates

Themes and report templates can be used as optional theme and template values when exporting or generating PDFs.

// Get all themes from default workspace
Theme[] themes = client.getThemes(null).get();

// Get themes from specific workspace
Theme[] workspaceThemes = client.getThemes(new WorkspaceKey(456)).get();
// Each Theme has: id (int), code (String), name (String)

// Get all report templates
ReportTemplate[] templates = client.getReportTemplates(null).get();
ReportTemplate[] workspaceTemplates = client.getReportTemplates(new WorkspaceKey("WS_CODE")).get();
// Each ReportTemplate has: id (int), code (String), name (String)

Report export

var objectMapper = ObjectMapperUtility.getInstance();

String reportData = """
{
  "sales": [
    { "region": "North America", "quarter": "Q1", "revenue": 1250000, "expenses": 830000 },
    { "region": "Europe", "quarter": "Q1", "revenue": 980000, "expenses": 640000 },
    { "region": "Asia", "quarter": "Q1", "revenue": 1520000, "expenses": 910000 }
  ],
  "totals": {
    "revenue": 3750000,
    "expenses": 2380000,
    "profit": 1370000
  }
}
""";

String reportParams = """
{
  "reportTitle": "Q1 Financial Overview",
  "currency": "USD",
  "preparedBy": "Finance Department",
  "generatedOn": "2024-05-10T14:30:00Z",
  "includeCharts": true
}
""";

// Convert the raw strings to JsonNodes
var dataJson = objectMapper.readTree(reportData);
var paramsJson = objectMapper.readTree(reportParams);

// Create a nonce token if generating a download link that will be accessed 
// from an unauthorized client or sending a preview url to an iframe
String nonce = client.createNonceAuthToken().get().getNonce();


// The data can optionally be pushed to the server, using the tempDataService,  
// where it will be stored temporarily and can be used as a datasource for the exported reports


var queryParams = new ReportQueryParams.Builder()
                .params(paramsNode)
                .data(dataNode)
                .nonce(nonce) //optional
                .theme("DARK")      // optional: theme code for export styling
                .template("INVOICE") // optional: report template code
                .build();

// The download methods return the received HttpResponse<byte[]> and it is up to the user to process it as needed
var pdfResponse = client.downloadPdfAsync(new ReportParams(
                new WorkspaceKey(33),           // Workspace
                new ReportKey(109),             // Report template ID
                queryParams
	            )).get();

Export to a specific filetype

var queryParams = new ReportQueryParams.Builder()
                .params(paramsNode)
                .data(dataNode)
                .theme("DARK")           // optional
                .template("INVOICE")     // optional
                .format(ExportFormat.HTML) // or any other supported format
                ...
                .build();

Working with Workspaces

CompletableFuture<Workspace[]> workspaces = client.getWorkspacesAsync();

Using Temporary Data

String reportData = """
{
  "sales": [
    { "region": "North America", "quarter": "Q1", "revenue": 1250000, "expenses": 830000 },
    { "region": "Europe", "quarter": "Q1", "revenue": 980000, "expenses": 640000 },
    { "region": "Asia", "quarter": "Q1", "revenue": 1520000, "expenses": 910000 }
  ],
  "totals": {
    "revenue": 3750000,
    "expenses": 2380000,
    "profit": 1370000
  }
}
""";

var dataJson = objectMapper.readTree(reportData);
Integer tempDataId = client.pushTemporaryData(
	                 dataNode,
	                 OffsetDateTime.now().plusMinutes(10),  // 10 minute expiration
	                 new WorkspaceKey(33)
	            ).get().getTempDataId();

var queryParams = new ReportQueryParams.Builder()
                .params(paramsNode)
                .tempDataId(tempDataId)
                .build();

Async document export

This is recommended for larger reports which take a long time to export and can cause a connection timeout. This way, the export is being prepared in the background and once it is complete, the document can be fetched.

ExportParams supports optional theme and template (set via setters); they are sent in the request body only, not in the params dictionary.

// 1. Start the export with the configured parameters, workspace and report info
var response =  client.startDocumentExport(workspaceKey, reportKey, params).get();

// 2. Check the export status
var status = client.getExportStatus(workspaceId, response.tempFileId).get();

// 3. If the status returns `completed` you can fetch the document
var documentHttpResponse = client.downloadCompletedFile(workspaceId, tempFileId).get();

Working with Jobs

Jobs represent batch processing workflows that can generate multiple reports or perform automated tasks. Jobs can optionally require review before final delivery.

Listing available jobs
// Get all jobs from default workspace
Job[] jobs = client.getJobs(null).get();

// Get jobs from specific workspace
WorkspaceKey workspace = new WorkspaceKey(456);
Job[] workspaceJobs = client.getJobs(workspace).get();

// Each Job includes:
// - id: unique identifier
// - name: human-readable name
// - code: unique code identifier
// - description: job description
// - reviewRequired: whether review is needed before delivery
// - isActive: whether the job is currently active
// - lastRunTime: timestamp of the most recent execution
Starting a job run

Execute a job with custom parameters and data:

var objectMapper = ObjectMapperUtility.getInstance();

// Prepare job run parameters
String jobRunParams = """
{
  "fiscalYear": 2024,
  "department": "Sales",
  "includeProjections": true
}
""";

String jobRunData = """
{
  "employees": [
    { "id": 101, "name": "John Doe", "email": "john@example.com" },
    { "id": 102, "name": "Jane Smith", "email": "jane@example.com" }
  ]
}
""";

var paramsJson = objectMapper.readTree(jobRunParams);
var dataJson = objectMapper.readTree(jobRunData);

// Create job run request
JobRunRequest request = new JobRunRequest(paramsJson, dataJson);

// Start the job run
JobParams jobParams = new JobParams(
    new WorkspaceKey(456),  // Workspace
    "MONTHLY_REPORT"        // Job code or ID
);

JobRun jobRun = client.startNewJobRun(jobParams, request).get();
Integer jobRunId = jobRun.getJobRunId();
Monitoring job run status

Poll the job run status to track progress:

// Add job run ID to params
JobParams statusParams = new JobParams(
    new WorkspaceKey(456),
    "MONTHLY_REPORT",
    jobRunId
);

// Check status
JobRunStatus status = client.getJobRunStatus(statusParams).get();

if (status.isFinished()) {
    System.out.println("Job run completed!");
    System.out.println("Status: " + status.getStatus());
    System.out.println("Entries processed: " + status.getEntries().length);
} else {
    System.out.println("Job run still in progress...");
}
Generating a review document

For jobs that require review, generate a consolidated document containing all job run entries:

JobParams reviewParams = new JobParams(
    new WorkspaceKey(456),
    "MONTHLY_REPORT",
    jobRunId
);

// Generate review document (asynchronous)
AsyncReportGenerationResponse response = client.generateReviewDocument(reviewParams).get();
Integer tempFileId = response.getTemporaryFileId();

// Poll for completion
ReportExportStatusResponse exportStatus;
do {
    Thread.sleep(2000); // Wait 2 seconds between checks
    exportStatus = client.getExportStatus(456, tempFileId).get();
} while (!exportStatus.isCompleted());

// Download the completed review document
HttpResponse<byte[]> documentResponse = client.downloadCompletedFile(456, tempFileId).get();
byte[] documentBytes = documentResponse.body();

// Save to file
Files.write(Paths.get("review-document.pdf"), documentBytes);
Delivering job run results

After reviewing and approving the job run, deliver all entries:

JobParams deliveryParams = new JobParams(
    new WorkspaceKey(456),
    "MONTHLY_REPORT",
    jobRunId
);

Boolean delivered = client.jobRunDeliver(deliveryParams).get();

if (delivered) {
    System.out.println("Job run delivered successfully!");
} else {
    System.out.println("Delivery failed.");
}
Complete job workflow example

Here's a complete workflow combining all job operations:

// 1. List available jobs
Job[] jobs = client.getJobs(new WorkspaceKey(456)).get();
Job targetJob = Arrays.stream(jobs)
    .filter(j -> j.getCode().equals("MONTHLY_REPORT"))
    .findFirst()
    .orElseThrow();

System.out.println("Starting job: " + targetJob.getName());
System.out.println("Review required: " + targetJob.isReviewRequired());

// 2. Start job run
JobRunRequest request = new JobRunRequest(paramsJson, dataJson);
JobParams jobParams = new JobParams(new WorkspaceKey(456), targetJob.getCode());
JobRun jobRun = client.startNewJobRun(jobParams, request).get();

// 3. Monitor progress
JobParams statusParams = new JobParams(
    new WorkspaceKey(456),
    targetJob.getCode(),
    jobRun.getJobRunId()
);

JobRunStatus status;
do {
    Thread.sleep(5000); // Poll every 5 seconds
    status = client.getJobRunStatus(statusParams).get();
    System.out.println("Status: " + status.getStatus());
} while (!status.isFinished());

// 4. If review is required, generate review document
if (targetJob.isReviewRequired()) {
    AsyncReportGenerationResponse reviewResponse = 
        client.generateReviewDocument(statusParams).get();
    
    // Wait for document generation
    ReportExportStatusResponse exportStatus;
    do {
        Thread.sleep(2000);
        exportStatus = client.getExportStatus(456, reviewResponse.getTemporaryFileId()).get();
    } while (!exportStatus.isCompleted());
    
    // Download review document
    HttpResponse<byte[]> document = 
        client.downloadCompletedFile(456, reviewResponse.getTemporaryFileId()).get();
    Files.write(Paths.get("review.pdf"), document.body());
    
    System.out.println("Review document saved. Please review and approve.");
    
    // After manual review and approval...
    Boolean delivered = client.jobRunDeliver(statusParams).get();
    System.out.println("Delivered: " + delivered);
} else {
    // No review required, directly deliver
    Boolean delivered = client.jobRunDeliver(statusParams).get();
    System.out.println("Delivered: " + delivered);
}

Export types

The CxReports API supports exporting reports in multiple formats depending on the use case.
Choose the format using the ExportFormat enum in the ReportQueryParams.

Format Enum Value Typical Use Case
PDF ExportFormat.PDF Printable reports, invoices, contracts
HTML ExportFormat.HTML Embedding reports inside a web page or portal
Excel (XLSX) ExportFormat.XLSX Tabular data for financials, KPIs, or further analysis
Word (DOCX) ExportFormat.DOCX Narrative reports, proposals, documentation
PowerPoint ExportFormat.PPTX Slide-based presentations, board reports

Common Workflows

Single Report Generation

For generating individual reports on-demand:

  1. Prepare report data and parameters
  2. Use downloadPdfAsync() or other format-specific methods
  3. Process the returned HttpResponse<byte[]>

Batch Report Processing with Jobs

For generating multiple reports in a single operation:

  1. List available jobs with getJobs()
  2. Start a job run with startNewJobRun()
  3. Monitor progress with getJobRunStatus()
  4. If review is required:
    • Generate review document with generateReviewDocument()
    • Download and review the consolidated document
    • Approve and deliver with jobRunDeliver()
  5. If no review is required, directly call jobRunDeliver()

Asynchronous Large Report Export

For reports that may timeout due to size or complexity:

  1. Start export with startDocumentExport()
  2. Poll status with getExportStatus()
  3. Download when complete with downloadCompletedFile()

License

This library is licensed under the MIT License.

Support

For any issues or questions, contact support@cx-reports.com or visit our documentation at https://docs.cx-reports.com.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages