CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-alibaba--easyexcel

High-performance Java library for reading and writing Excel files with minimal memory usage

Pending
Overview
Eval results
Files

data-conversion.mddocs/

Data Conversion

Type conversion system for transforming between Java objects and Excel cell values. EasyExcel provides a pluggable converter system that handles automatic type detection and custom conversion logic for complex data transformations.

Capabilities

Core Converter Interface

Primary interface for implementing custom data converters.

/**
 * Interface for converting between Java objects and Excel cell values
 * @param <T> Java type that this converter handles
 */
public interface Converter<T> {
    /**
     * Get the Java type that this converter supports
     * @return Class of supported Java type
     */
    Class<?> supportJavaTypeKey();
    
    /**
     * Get the Excel cell data type that this converter supports
     * @return CellDataTypeEnum of supported Excel type
     */
    CellDataTypeEnum supportExcelTypeKey();
    
    /**
     * Convert Excel cell data to Java object (for reading)
     * @param cellData Cell data from Excel
     * @param contentProperty Content property configuration
     * @param globalConfiguration Global configuration settings
     * @return Converted Java object
     * @throws Exception if conversion fails
     */
    T convertToJavaData(ReadCellData<?> cellData, 
                       ExcelContentProperty contentProperty, 
                       GlobalConfiguration globalConfiguration) throws Exception;
    
    /**
     * Convert Java object to Excel cell data (for writing)
     * @param value Java object to convert
     * @param contentProperty Content property configuration
     * @param globalConfiguration Global configuration settings
     * @return Cell data for Excel
     * @throws Exception if conversion fails
     */
    WriteCellData<?> convertToExcelData(T value, 
                                       ExcelContentProperty contentProperty, 
                                       GlobalConfiguration globalConfiguration) throws Exception;
}

Built-in Converter Classes

Pre-built converters for automatic type handling.

/**
 * Automatic converter that detects appropriate converter based on type
 */
public class AutoConverter implements Converter<Object> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return null; // Supports all types
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return null; // Supports all cell types
    }
    
    @Override
    public Object convertToJavaData(ReadCellData<?> cellData, 
                                   ExcelContentProperty contentProperty, 
                                   GlobalConfiguration globalConfiguration) throws Exception {
        // Automatic type detection and conversion
        return null; // Implementation handles detection
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(Object value, 
                                              ExcelContentProperty contentProperty, 
                                              GlobalConfiguration globalConfiguration) throws Exception {
        // Automatic type detection and conversion
        return null; // Implementation handles detection
    }
}

/**
 * Converter for handling null values
 */
public class NullableObjectConverter implements Converter<Object> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return Object.class;
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.EMPTY;
    }
    
    @Override
    public Object convertToJavaData(ReadCellData<?> cellData, 
                                   ExcelContentProperty contentProperty, 
                                   GlobalConfiguration globalConfiguration) {
        if (cellData == null || cellData.getData() == null) {
            return null;
        }
        // Delegate to appropriate converter
        return cellData.getData();
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(Object value, 
                                              ExcelContentProperty contentProperty, 
                                              GlobalConfiguration globalConfiguration) {
        if (value == null) {
            return new WriteCellData<>("");
        }
        // Delegate to appropriate converter
        return new WriteCellData<>(value);
    }
}

Converter Management

Classes for loading and managing converters.

/**
 * Default converter loader and registry
 */
public class DefaultConverterLoader {
    /**
     * Load all default converters
     * @return Map of converter configurations
     */
    public static Map<String, Converter<?>> loadDefaultReadConverter() {
        // Returns map of all built-in read converters
        return null; // Implementation loads converters
    }
    
    /**
     * Load all default write converters
     * @return Map of converter configurations
     */
    public static Map<String, Converter<?>> loadDefaultWriteConverter() {
        // Returns map of all built-in write converters
        return null; // Implementation loads converters
    }
    
    /**
     * Load converters for specific type
     * @param clazz Java class to load converters for
     * @return Map of converters for the class
     */
    public static Map<String, Converter<?>> loadConverter(Class<?> clazz) {
        // Returns converters specific to the class
        return null; // Implementation loads converters
    }
}

/**
 * Converter holder for managing converter instances
 */
public class ConverterHolder {
    /**
     * Register a custom converter
     * @param converter Converter to register
     */
    public void registerConverter(Converter<?> converter);
    
    /**
     * Get converter for Java type and Excel type combination
     * @param javaType Java class
     * @param excelType Excel cell data type
     * @return Appropriate converter or null
     */
    public Converter<?> getConverter(Class<?> javaType, CellDataTypeEnum excelType);
    
    /**
     * Get all registered converters
     * @return Map of all converters
     */
    public Map<String, Converter<?>> getAllConverter();
}

Cell Data Classes

Classes representing cell data during conversion.

/**
 * Cell data structure used during reading operations
 * @param <T> Type of data contained in the cell
 */
public class ReadCellData<T> {
    /**
     * Cell data type
     */
    private CellDataTypeEnum type;
    
    /**
     * Cell data value
     */
    private T data;
    
    /**
     * Cell formula (if applicable)
     */
    private String formula;
    
    /**
     * String representation of cell value
     */
    private String stringValue;
    
    /**
     * Number representation of cell value
     */
    private BigDecimal numberValue;
    
    /**
     * Boolean representation of cell value
     */
    private Boolean booleanValue;
    
    /**
     * Date representation of cell value
     */
    private Date dateValue;
    
    // Getters and setters...
}

/**
 * Cell data structure used during writing operations
 * @param <T> Type of data to write to the cell
 */
public class WriteCellData<T> {
    /**
     * Cell data type
     */
    private CellDataTypeEnum type;
    
    /**
     * Cell data value
     */
    private T data;
    
    /**
     * Cell formula (if applicable)
     */
    private String formula;
    
    /**
     * Data format for the cell
     */
    private String dataFormat;
    
    /**
     * Data format index
     */
    private Short dataFormatIndex;
    
    // Constructors
    public WriteCellData();
    public WriteCellData(T data);
    public WriteCellData(String formula, T data);
    
    // Getters and setters...
}

Content Property Classes

Classes providing configuration context for converters.

/**
 * Excel content property containing field configuration
 */
public class ExcelContentProperty {
    /**
     * Field information
     */
    private Field field;
    
    /**
     * Date format configuration
     */
    private DateTimeFormatProperty dateTimeFormatProperty;
    
    /**
     * Number format configuration
     */
    private NumberFormatProperty numberFormatProperty;
    
    /**
     * Custom converter class
     */
    private Class<? extends Converter<?>> converter;
    
    /**
     * Column index
     */
    private Integer index;
    
    /**
     * Column order
     */
    private Integer order;
    
    // Getters and setters...
}

/**
 * Date/time format property
 */
public class DateTimeFormatProperty {
    /**
     * Date format pattern
     */
    private String format;
    
    /**
     * Use 1904 date windowing
     */
    private Boolean use1904windowing;
    
    // Getters and setters...
}

/**
 * Number format property
 */
public class NumberFormatProperty {
    /**
     * Number format pattern
     */
    private String format;
    
    /**
     * Number format index
     */
    private Short index;
    
    // Getters and setters...
}

Usage Examples

Custom Enum Converter

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

// Enum definition
public enum UserStatus {
    ACTIVE("Active"),
    INACTIVE("Inactive"),
    PENDING("Pending"),
    SUSPENDED("Suspended");
    
    private final String displayName;
    
    UserStatus(String displayName) {
        this.displayName = displayName;
    }
    
    public String getDisplayName() {
        return displayName;
    }
    
    public static UserStatus fromDisplayName(String displayName) {
        for (UserStatus status : values()) {
            if (status.displayName.equals(displayName)) {
                return status;
            }
        }
        throw new IllegalArgumentException("Unknown status: " + displayName);
    }
}

// Custom converter implementation
public class UserStatusConverter implements Converter<UserStatus> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return UserStatus.class;
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }
    
    @Override
    public UserStatus convertToJavaData(ReadCellData<?> cellData, 
                                       ExcelContentProperty contentProperty,
                                       GlobalConfiguration globalConfiguration) throws Exception {
        String cellValue = cellData.getStringValue();
        if (cellValue == null || cellValue.trim().isEmpty()) {
            return null;
        }
        
        try {
            return UserStatus.fromDisplayName(cellValue.trim());
        } catch (IllegalArgumentException e) {
            throw new ExcelDataConvertException(
                "Cannot convert '" + cellValue + "' to UserStatus", e);
        }
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(UserStatus value, 
                                              ExcelContentProperty contentProperty,
                                              GlobalConfiguration globalConfiguration) throws Exception {
        if (value == null) {
            return new WriteCellData<>("");
        }
        return new WriteCellData<>(value.getDisplayName());
    }
}

// Data class using custom converter
public class UserData {
    @ExcelProperty("Name")
    private String name;
    
    @ExcelProperty(value = "Status", converter = UserStatusConverter.class)
    private UserStatus status;
    
    @ExcelProperty("Email")
    private String email;
    
    // Getters and setters...
}

Custom Date Converter

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeConverter implements Converter<LocalDateTime> {
    private static final DateTimeFormatter FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public Class<?> supportJavaTypeKey() {
        return LocalDateTime.class;
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }
    
    @Override
    public LocalDateTime convertToJavaData(ReadCellData<?> cellData, 
                                          ExcelContentProperty contentProperty,
                                          GlobalConfiguration globalConfiguration) throws Exception {
        String cellValue = cellData.getStringValue();
        if (cellValue == null || cellValue.trim().isEmpty()) {
            return null;
        }
        
        try {
            return LocalDateTime.parse(cellValue.trim(), FORMATTER);
        } catch (Exception e) {
            throw new ExcelDataConvertException(
                "Cannot parse date: " + cellValue, e);
        }
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(LocalDateTime value, 
                                              ExcelContentProperty contentProperty,
                                              GlobalConfiguration globalConfiguration) throws Exception {
        if (value == null) {
            return new WriteCellData<>("");
        }
        return new WriteCellData<>(value.format(FORMATTER));
    }
}

// Usage in data class
public class EventData {
    @ExcelProperty("Event Name")
    private String name;
    
    @ExcelProperty(value = "Event Date", converter = LocalDateTimeConverter.class)
    private LocalDateTime eventDate;
    
    @ExcelProperty("Description")
    private String description;
    
    // Getters and setters...
}

Complex Object Converter

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.fasterxml.jackson.databind.ObjectMapper;

// Complex object to convert
public class Address {
    private String street;
    private String city;
    private String zipCode;
    private String country;
    
    // Constructors, getters, setters...
    
    @Override
    public String toString() {
        return street + ", " + city + ", " + zipCode + ", " + country;
    }
}

// JSON-based converter for complex objects
public class AddressConverter implements Converter<Address> {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public Class<?> supportJavaTypeKey() {
        return Address.class;
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }
    
    @Override
    public Address convertToJavaData(ReadCellData<?> cellData, 
                                    ExcelContentProperty contentProperty,
                                    GlobalConfiguration globalConfiguration) throws Exception {
        String cellValue = cellData.getStringValue();
        if (cellValue == null || cellValue.trim().isEmpty()) {
            return null;
        }
        
        try {
            // Try parsing as JSON first
            if (cellValue.startsWith("{")) {
                return objectMapper.readValue(cellValue, Address.class);
            }
            
            // Fallback to simple comma-separated format
            String[] parts = cellValue.split(",");
            if (parts.length >= 4) {
                Address address = new Address();
                address.setStreet(parts[0].trim());
                address.setCity(parts[1].trim());
                address.setZipCode(parts[2].trim());
                address.setCountry(parts[3].trim());
                return address;
            }
            
            throw new IllegalArgumentException("Invalid address format");
        } catch (Exception e) {
            throw new ExcelDataConvertException(
                "Cannot convert address: " + cellValue, e);
        }
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(Address value, 
                                              ExcelContentProperty contentProperty,
                                              GlobalConfiguration globalConfiguration) throws Exception {
        if (value == null) {
            return new WriteCellData<>("");
        }
        
        // Write as JSON for full fidelity
        try {
            String json = objectMapper.writeValueAsString(value);
            return new WriteCellData<>(json);
        } catch (Exception e) {
            // Fallback to string representation
            return new WriteCellData<>(value.toString());
        }
    }
}

Currency Converter with Localization

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Currency;
import java.util.Locale;

public class CurrencyConverter implements Converter<BigDecimal> {
    private final Currency currency;
    private final Locale locale;
    private final NumberFormat currencyFormat;
    
    public CurrencyConverter() {
        this(Currency.getInstance("USD"), Locale.US);
    }
    
    public CurrencyConverter(Currency currency, Locale locale) {
        this.currency = currency;
        this.locale = locale;
        this.currencyFormat = NumberFormat.getCurrencyInstance(locale);
        this.currencyFormat.setCurrency(currency);
    }
    
    @Override
    public Class<?> supportJavaTypeKey() {
        return BigDecimal.class;
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;  // Handle formatted currency strings
    }
    
    @Override
    public BigDecimal convertToJavaData(ReadCellData<?> cellData, 
                                       ExcelContentProperty contentProperty,
                                       GlobalConfiguration globalConfiguration) throws Exception {
        String cellValue = cellData.getStringValue();
        if (cellValue == null || cellValue.trim().isEmpty()) {
            return null;
        }
        
        try {
            // Remove currency symbols and parse
            String cleanValue = cellValue.replaceAll("[^\\d.,+-]", "");
            return new BigDecimal(cleanValue);
        } catch (Exception e) {
            throw new ExcelDataConvertException(
                "Cannot parse currency: " + cellValue, e);
        }
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(BigDecimal value, 
                                              ExcelContentProperty contentProperty,
                                              GlobalConfiguration globalConfiguration) throws Exception {
        if (value == null) {
            return new WriteCellData<>("");
        }
        
        String formattedValue = currencyFormat.format(value);
        return new WriteCellData<>(formattedValue);
    }
}

// Usage with custom currency
public class SalesData {
    @ExcelProperty("Product")
    private String product;
    
    @ExcelProperty(value = "Price", converter = CurrencyConverter.class)
    private BigDecimal price;
    
    @ExcelProperty("Quantity")
    private Integer quantity;
    
    // Getters and setters...
}

Registering Custom Converters Globally

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;

// Register converters globally for reading
ExcelReaderBuilder readerBuilder = EasyExcel.read("data.xlsx", UserData.class, listener);

// Register custom converter (would be done through configuration in actual implementation)
// readerBuilder.registerConverter(new UserStatusConverter());

// For writing with custom converters
ExcelWriterBuilder writerBuilder = EasyExcel.write("output.xlsx", UserData.class);

// Register custom converter (would be done through configuration in actual implementation)  
// writerBuilder.registerConverter(new UserStatusConverter());

writerBuilder.sheet("Users").doWrite(userData);

Conditional Conversion Logic

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;

public class SmartNumberConverter implements Converter<Number> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return Number.class;
    }
    
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }
    
    @Override
    public Number convertToJavaData(ReadCellData<?> cellData, 
                                   ExcelContentProperty contentProperty,
                                   GlobalConfiguration globalConfiguration) throws Exception {
        String cellValue = cellData.getStringValue();
        if (cellValue == null || cellValue.trim().isEmpty()) {
            return null;
        }
        
        cellValue = cellValue.trim();
        
        try {
            // Detect if it's a percentage
            if (cellValue.endsWith("%")) {
                double value = Double.parseDouble(cellValue.substring(0, cellValue.length() - 1));
                return value / 100.0; // Convert percentage to decimal
            }
            
            // Detect if it contains decimal point
            if (cellValue.contains(".")) {
                return Double.parseDouble(cellValue);
            }
            
            // Try as integer first
            long longValue = Long.parseLong(cellValue);
            if (longValue >= Integer.MIN_VALUE && longValue <= Integer.MAX_VALUE) {
                return (int) longValue;
            }
            return longValue;
            
        } catch (NumberFormatException e) {
            throw new ExcelDataConvertException(
                "Cannot parse number: " + cellValue, e);
        }
    }
    
    @Override
    public WriteCellData<?> convertToExcelData(Number value, 
                                              ExcelContentProperty contentProperty,
                                              GlobalConfiguration globalConfiguration) throws Exception {
        if (value == null) {
            return new WriteCellData<>("");
        }
        
        // Format based on type
        if (value instanceof Double || value instanceof Float) {
            BigDecimal bd = BigDecimal.valueOf(value.doubleValue());
            return new WriteCellData<>(bd.toPlainString());
        }
        
        return new WriteCellData<>(value.toString());
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-com-alibaba--easyexcel

docs

annotations-and-mapping.md

data-conversion.md

event-system.md

exception-handling.md

index.md

reading-operations.md

writing-operations.md

tile.json