Limitations and API Differences
Introduction
Aspose Cells provides powerful spreadsheet manipulation capabilities across multiple platforms. While the Java library is the original implementation, the Python via Java package (aka Aspose.Cells for Python via Java) simply wraps the Java API to enable Python developers to leverage the same functionality.
Although both libraries share the same core engine, there are noticeable limitations and API differences that developers need to be aware of when moving code between the two environments or when writing cross‐platform examples. This article highlights the most important differences and demonstrates how to achieve the same tasks in Java, Python (via Java) code.
Note
The examples below are stand‐alone, runnable snippets. All file paths are relative (e.g.,./Data/Sample.xlsx) so they work out‐of‐the‐box when placed in a typical project folder structure.
1. Namespace & Package Structure
| Platform | Core Namespace / Package |
|---|---|
| Java | com.aspose.cells |
| Python via Java | asposecells (The wrapper – the Java classes are accessed through asposecells.api) |
Example
Java
import com.aspose.cells.*;
public class NamespaceDemo {
public static void main(String[] args) throws Exception {
// Create a workbook using the Java namespace
Workbook workbook = new Workbook();
System.out.println("Java API: Workbook created.");
}
}Python via Java
import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook
# Create a workbook using the Python wrapper
workbook = Workbook()
print("Python via Java API: Workbook created.")
jpype.shutdownJVM()2. Object Instantiation & Constructors
| Feature | Java | Python via Java |
|---|---|---|
| Default constructor | new Workbook() |
Workbook() |
| Load from file | new Workbook("file.xlsx") |
Workbook("file.xlsx") |
| Load from stream | new Workbook(stream) |
Workbook(stream) |
| Memory stream handling | Uses java.io.InputStream |
Uses java.io.ByteArrayInputStream (wrapped) |
Example – Loading from a stream
Java
import com.aspose.cells.*;
import java.io.FileInputStream;
public class LoadFromStream {
public static void main(String[] args) throws Exception {
try (FileInputStream fis = new FileInputStream("./Data/Sample.xlsx")) {
Workbook wb = new Workbook(fis);
System.out.println("Loaded workbook with " + wb.getWorksheets().getCount() + " sheets.");
}
}
}Python via Java
import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook
def load_workbook_from_bytes(data: bytes):
from jpype import JClass, JArray
from jpype.types import JByte
ByteArrayInputStream = JClass("java.io.ByteArrayInputStream")
JByteArray = JArray(JByte)
byte_array = JByteArray(data)
stream = ByteArrayInputStream(byte_array)
return Workbook(stream)
with open("./Data/Sample.xlsx", "rb") as f:
workbook = load_workbook_from_bytes(f.read())
jpype.shutdownJVM()3. Data Types & Collections
| Concept | Java | Python via Java | |
|---|---|---|---|
| List of Worksheets | WorksheetCollection (indexer get(int)) |
Same as Java (wrapper) | |
| Cell value type | Object (auto‐converted) |
Object (auto‐converted) |
|
| Enums | com.aspose.cells.FileFormatType |
Same enum accessed via wrapper: asposecells.api.FileFormatType |
|
| Nullable types | Not applicable (Java uses primitives) | Same as Java |
Example – Accessing a cell value
Java
import com.aspose.cells.*;
public class CellValue {
public static void main(String[] args) throws Exception {
Workbook wb = new Workbook("./Data/Sample.xlsx");
Worksheet sheet = wb.getWorksheets().get(0);
Cell cell = sheet.getCells().get("A1");
System.out.println("Java: A1 = " + cell.getStringValue());
}
}Python via Java
import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook
wb = Workbook("./Data/Sample.xlsx")
sheet = wb.getWorksheets().get(0)
cell = sheet.getCells().get("A1")
print(f"Python via Java: A1 = {cell.getStringValue()}")
jpype.shutdownJVM()sheet.Cells["A1"]). You must use the Java‐style get method or the generic get("A1") method provided by the wrapper.
4. Memory Management & Garbage Collection
| Aspect | Java | Python via Java |
|---|---|---|
| Garbage collection | JVM GC | JVM GC (via JPype) + Python GC |
| Explicit disposal | Not required (but you can call dispose() on Workbook to free native resources) |
Same method exists: workbook.dispose() |
Example – Releasing native resources
Java
import com.aspose.cells.*;
public class DisposeDemo {
public static void main(String[] args) throws Exception {
Workbook wb = new Workbook("./Data/Sample.xlsx");
// Perform operations...
wb.dispose(); // Explicitly release native memory
}
}Python via Java
import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook
wb = Workbook("./Data/Sample.xlsx")
# Perform operations...
wb.dispose() # Releases native memory used by the Java engine
jpype.shutdownJVM()dispose() when processing many large files in a loop to avoid native memory leaks.
5. Exception Types & Handling
| Exception | Java | Python via Java |
|---|---|---|
| File format error | com.aspose.cells.Exception (Message contains “File format not supported”) |
Same Java exception wrapped as a generic Exception in Python |
| License not set | com.aspose.cells.LicenseException |
Same wrapper exception |
| Out‐of‐memory | java.lang.OutOfMemoryError (or com.aspose.cells.Exception) |
Propagates as JavaException in JPype |
Example – Handling a missing license
Java
import com.aspose.cells.*;
public class LicenseDemo {
public static void main(String[] args) {
try {
License lic = new License();
lic.setLicense("./License/Aspose.Cells.Java.lic");
} catch (Exception ex) {
System.err.println("Java: License error – " + ex.getMessage());
}
}
}Python via Java
import jpype
import asposecells
jpype.startJVM()
from asposecells.api import License
try:
lic = License()
lic.setLicense("./License/Aspose.Cells.Python.lic")
except Exception as e: # Java exception is wrapped
print(f"Python via Java: License error - {e}")
jpype.shutdownJVM()6. Feature Availability Gaps
| Feature | Java | Python via Java | Remarks |
|---|---|---|---|
| Chart rendering to image | Full support (Chart.toImage()) |
Supported via same method | No gap |
| PDF/A‐3b export | Available from v22.12 | Available (requires Java 8+) | No gap |
Saving as SpreadsheetML (XLSX‐XML) |
Supported | Not exposed in the Python wrapper (requires manual Java call) | |
| Thread‐safe usage | Documented as not thread‐safe without external sync | Same limitation | Must synchronize access when using from multiple Python threads |
7. Build & Deployment Considerations
| Aspect | Java | Python via Java |
|---|---|---|
| Runtime | JRE 8+ (or JDK) | JPype + JRE 8+ (bundled in the wheel) |
| Native libraries | libaspose-cells-java.so / .dll inside the JAR |
Same native binaries extracted to a temp folder at runtime |
| Distribution | JAR file (≈ 60 MB) | Wheel (aspose-cells-xx.xx-py3-none-any.whl) that bundles the JAR |
| Platform‐specific issues | Need to set java.library.path for native lib on some OSes |
Same requirement; wrapper attempts to set it automatically |
8. Migrating Code: From Python via Java to .NET
Below is a complete end‐to‐end example that reads a workbook, modifies a cell, and saves it as PDF. The same logical steps are shown for all three platforms, making the migration path crystal clear.
Java
// ./Examples/Java/ConvertToPdf.java
import com.aspose.cells.*;
public class ConvertToPdf {
public static void main(String[] args) throws Exception {
// Load workbook
Workbook wb = new Workbook("./Data/Sample.xlsx");
Worksheet ws = wb.getWorksheets().get(0);
// Change a cell value
Cell cell = ws.getCells().get("B2");
cell.putValue("Converted from Java");
// Save as PDF
wb.save("./Output/Result.pdf", SaveFormat.Pdf);
System.out.println("PDF saved at ./Output/Result.pdf");
}
}Python via Java
# ./Examples/Python/ConvertToPdf.py
import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook, SaveFormat
# Load workbook
wb = Workbook("./Data/Sample.xlsx")
ws = wb.getWorksheets().get(0)
# Change a cell value
cell = ws.getCells().get("B2")
cell.putValue("Converted from Python")
# Save as PDF
wb.save("./Output/Result.pdf", SaveFormat.PDF)
print("PDF saved at ./Output/Result.pdf")
jpype.shutdownJVM()All three snippets compile and run as‐is (provided the relative folders exist). This demonstrates how the API surface remains consistent, while language‐specific syntactic differences are isolated to object creation, method calls, and exception handling.