Java
The Java connector uses java.net.http.HttpClient with no external dependencies.
It needs Java 17+ to compile. Render methods return byte[].
Add the connector
There's no Maven/Gradle artifact to depend on (yet) — the client is a single,
dependency-free class. Copy CalcoClient.java into your source tree under
com/calco/, keeping its package com.calco; declaration, then import it:
java
import com.calco.CalcoClient;Quick start
java
import com.calco.CalcoClient;
import java.nio.file.Path;
import java.time.Duration;
// With API key and custom timeout
var client = new CalcoClient(
"http://localhost:8080",
"dc_live_...",
Duration.ofMinutes(5));The key is sent as Authorization: Bearer <key> on every request. Pass null
for no key.
Converting a file
java
byte[] pdf = client.convert(
Path.of("report.xlsx"),
"pdf",
"{\"company\": \"Acme\"}", // dataJson
"Summary", // sheet
"Q4 Report"); // title
java.nio.file.Files.write(Path.of("report.pdf"), pdf);Extract the placeholder map with scaffold:
java
String scaffold = client.scaffold(Path.of("spreadsheet.xlsx"));Managing templates
java
// Create
String template = client.createTemplate(
Path.of("template.xlsx"), "Invoice", "finance", "billing,monthly");
// List
String templates = client.listTemplates();
// Update metadata (null = unchanged)
client.updateTemplate("42", "Invoice v2", "accounting", null);
// Add a new version
client.createTemplateVersion("42", Path.of("template_v2.xlsx"));
// Delete
client.deleteTemplate("42");Rendering a stored template
java
byte[] html = client.renderTemplateVersion(
"42", // id
"2", // version
"html", // format
"{\"customer\": \"Jane\"}", // dataJson
null, // sheet
"Invoice #1001"); // title
java.nio.file.Files.write(Path.of("invoice.html"), html);Batch rendering
Pass a JSON array of records and receive a ZIP archive:
java
String records = "[{\"name\":\"Alice\",\"amount\":100},{\"name\":\"Bob\",\"amount\":200}]";
byte[] zip = client.batchRender(
records,
"42", // templateId
"1", // version
"pdf", // format
"invoice_{{name}}", // titleTemplate
"Sheet1"); // sheet
java.nio.file.Files.write(Path.of("invoices.zip"), zip);By-hash workflow
Every stored version exposes a content hash (sha256 of the file). Address a
version directly by hash:
java
String meta = client.getTemplateByHash("3c9f...d1ab");
byte[] pdf = client.renderByHash("3c9f...d1ab", "pdf", "{\"customer\":\"Jane\"}", null, null);
byte[] xlsx = client.downloadByHash("3c9f...d1ab", "xlsx", null, null, null);Error handling
API errors throw CalcoClient.CalcoException, which carries the HTTP status code:
java
try {
client.convert(Path.of("missing.xlsx"), "pdf", null, null, null);
} catch (CalcoClient.CalcoException e) {
System.out.println("Status: " + e.getStatusCode());
System.out.println("Message: " + e.getMessage());
}Spring Boot integration
Bean configuration
java
import com.calco.CalcoClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
@Configuration
public class CalcoConfig {
@Bean
public CalcoClient calcoClient(
@Value("${calco.url}") String url,
@Value("${calco.api-key:}") String apiKey) {
return new CalcoClient(url, apiKey.isEmpty() ? null : apiKey, Duration.ofSeconds(120));
}
}Service and controller
java
@Service
public class ReportService {
private final CalcoClient dc;
public ReportService(CalcoClient dc) {
this.dc = dc;
}
public byte[] convertToPdf(MultipartFile upload) throws IOException, InterruptedException {
Path temp = Files.createTempFile("upload-", ".xlsx");
try {
upload.transferTo(temp);
return dc.convert(temp, "pdf", null, null, null);
} finally {
Files.deleteIfExists(temp);
}
}
}
@RestController
@RequestMapping("/api/reports")
public class ReportController {
private final ReportService reportService;
public ReportController(ReportService reportService) {
this.reportService = reportService;
}
@PostMapping("/convert")
public ResponseEntity<byte[]> convert(@RequestParam("file") MultipartFile file) throws Exception {
byte[] pdf = reportService.convertToPdf(file);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=report.pdf")
.contentType(MediaType.APPLICATION_PDF)
.body(pdf);
}
}Configuration options
| Parameter | Default | Description |
|---|---|---|
baseUrl | — | Root URL of the service (required) |
apiKey | null | Bearer token for authentication |
timeout | 120 seconds | HTTP connect/request timeout |