The main purpose of the SCell API is to make the xlsx-spreadsheets embeddable. In this article we’ll show you how to use the SCell to create an application that integrates and shows the xlsx-spreadsheets with their full functionality. Using this API you will be able to integrate xlsx-spreadsheets into your app quickly and easily.
To demonstrate this, we are going to create the App as follows:
The App uses basic functionality of the SCell API, opening and saving an xlsx-file, editing, searching, undo/redo commands. The left panel contains commands for opening predefined files. Command panels are created on the user side, the rest of the layout is the SCell UI Control.
The application architecture looks like this:
Now let’s look at some details of the implementation step by step (Full source code available on GitHub)
Step 1. Integrating an xlsx-spreadsheet into the JavaFX application
As was described in the previous articles (How to read Exel files with Java using the IDEA plugin and Work and create Excel files in Java, unleashing SCell), after adding the SCell API dependencies to the project, you can get access to the ScellApiEntryPoint. Then you resolve IScellUiFxApiBuilder and IScellCoreApiFactory which can create the UI control with the required IWorkbook object. Here is the code example:
ScellApiEntryPoint.getApiResolverAsync().thenApplyAsync(resolver -> { IScellCoreApiFactory coreFactory = IScellCoreApiFactory.resolve(resolver); CompletableFuture<IWorkbook> workbookFuture = CompletableFuture.supplyAsync(coreFactory::createNew); IScellUiApi<Node> uiApi = IScellUiFxApiBuilder.resolve(resolver) .readOnly(false) .create(workbookFuture); return uiApi.getControl(); }, Platform::runLater)
The IWorkbook has full control over the xlsx-spreadsheet document. The IWorkbook instance is required to create the UI control.
IScellUiApiBuilder creates the IScellUiApi with the desired parameters. Descriptions of the parameters can be found in the JavaDoc. The IScellUiApi provides the key object (getControl() call) – JavaFX control with embedded xlsx-spreadsheet which is ready to interact. Then the node can be added to the application layout.
Step 2. Interacting with an xlsx-spreadsheet embedded into JavaFX application
All SCell API calls in the application are encapsulated in the ScellWrapper class (see the full code on GitHub, to make it more clear, the code in this article has differences from the GitHub code). As mentioned above, we are going to implement the following features:
- Load an xlsx-file
- Save an xlsx-file
- Create a new xlsx-file
- Undo/Redo
- Search
- Dialog with information of the SCell API version
To implement the required features we will need the following SCell API services (uiManager and selectionManager) and version data (versionData):
// private class members private IUiContentManager uiManager; private IUiSelectionManager selectionManager; private IProductInfo versionData; // ... // Constructor or other init method content ScellApiEntryPoint.getApiResolverAsync().thenApplyAsync(resolver -> { IScellCoreApiFactory coreFactory = IScellCoreApiFactory.resolve(resolver); CompletableFuture<IWorkbook> workbookFuture = CompletableFuture.supplyAsync(coreFactory::createNew); IScellUiApi<Node> uiApi = IScellUiFxApiBuilder.resolve(resolver) .readOnly(false) .create(workbookFuture); this.uiManager = uiApi.getContentManager(); this.selectionManager = uiApi.getSelectionManager(); this.versionData = coreFactory.getProductInfo(); return uiApi.getControl(); }, Platform::runLater)
Now let’s show SCell API calls in the ScellWrapper class.
As mentioned, to create a JavaFX node that contains an xlsx-spreadsheet, SCell API requires an instance of the IWorkbook interface that has the full control over an xlsx-spreadsheet document. IWorkbook belongs to the core API and can be obtained in several ways: create a new one, load from an existing file or load programmatically from a user-created stream. All these methods are provided by the core API (with the help of IScellCoreApiFactory service). But to load or save a file in our application, we need to call the existing spreadsheet which is displayed by the SCell JavaFX node. The corresponding methods are provided by the IUiContentManager which was obtained in the previous example. Taking into account the above-mentioned, implementations of desired features will look like this (full code is here):
Load a file
// to load local file public CompletableFuture<Void> loadSpreadsheet(File file) { if (file == null) { return CompletableFuture.completedFuture(null); } return this.uiManager.load(file); } // to load predefined xlsx from app resources public CompletableFuture<Void> loadSpreadsheet(InputStream content, String name) { return this.uiManager.load(content, name); }
Save a file
public CompletableFuture<Void> saveAs(File target) { if (target == null) { return CompletableFuture.completedFuture(null); } return this.uiManager.getWorkbook().thenAccept(workbook -> workbook.getWriter().fileName(target.getAbsolutePath()).save()); }
Create a new file
public void createNew() { this.uiManager.clear(); }
In this example, we are simply clearing contents of a JavaFX UI control that displays an xlsx-spreadsheet. This action creates a new xlsx-file, independent of the previous one
Undo/Redo
public void undo() { this.uiManager.undoLastAction(); } public void redo() { this.uiManager.redoLastAction(); }
About info
public String getApiVersionsInfo() { return String.join("\n", "SCell API Core Interfaces: \t\t\t" + this.versionData.coreInterfaces(IProductInfo.ProductInfo.VERSION_WITH_BUILD_NUMBER), "SCell API Core Implementation: \t" + this.versionData.coreImpl(IProductInfo.ProductInfo.VERSION_WITH_BUILD_NUMBER), "SCell API UI Interfaces: \t\t\t" + this.versionData.uiInterfaces(IProductInfo.ProductInfo.VERSION_WITH_BUILD_NUMBER), "SCell API UI Implementation: \t\t" + this.versionData.uiImpl(IProductInfo.ProductInfo.VERSION_WITH_BUILD_NUMBER)); } public String getPlatformVersionsInfo() { return "JavaFX: " + this.versionData.getJavaFxVersion() + "\n" + "Java Runtime Version: " + this.versionData.getJavaVersionInfo(); }
To describe how the search works, more detailed explanations are needed, worthy of a separate article, so you can see its implementation on GitHub.
Step 3. Putting it all together
The ScellWrapper is bound to the view with the help of simple factories (ButtonsFactory and ToolbarsFactory) which incapsulate the creation of buttons with their events.
As a result, the main application class looks like this:
public class App extends Application { @Override public void start(Stage primaryStage) { BorderPane root = new BorderPane(); root.setVisible(false); ScellWrapper scell = new ScellWrapper(); scell.getScellControlFuture().thenAccept(scellControl -> { root.setCenter(scellControl); root.setStyle("-fx-background-color: #28a87d;"); root.setVisible(true); }); ButtonsFactory buttonsFactory = new ButtonsFactory(scell, primaryStage, App.class.getClassLoader()); ToolbarsFactory toolbarsFactory = new ToolbarsFactory(buttonsFactory); root.setTop(toolbarsFactory.createTopToolbar()); root.setLeft(toolbarsFactory.createLeftToolbar()); primaryStage.setScene(new Scene(root, 800, 600)); primaryStage.show(); }
In the highlighted lines the JavaFX node containig a xlsx-spreadsheet and toolbars were added to the JavaFX scene.
SCell can do a lot more than just integrate, open or save xlsx-spreadsheets. It has a wide range of tools that will help you manage xlsx-spreadsheets. We hope that this article was useful to you. For any additional information visit our official website and JavaDoc. Also, feel free to reach out to us on our contact page.