# litexl
**Repository Path**: ApeCoder/litexl
## Basic Information
- **Project Name**: litexl
- **Description**: Pure Java library for reading and writing Excel XLSX files. Lightweight, fast, with no external dependencies beyond the Java standard library.
搬运自 https://github.com/beingidly/litexl,支持java17
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-06
- **Last Updated**: 2026-03-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# litexl
Pure Java library for reading and writing Excel XLSX files. Lightweight, fast, with no external dependencies beyond the Java standard library.
## Features
- **Read/Write XLSX files** - Full support for reading and writing Excel 2007+ format
- **Object Mapping** - Annotation-based mapping between Java objects and Excel sheets
- **Styling** - Fonts, borders, fills, number formats, alignment
- **Formulas** - Write formula expressions to cells
- **Cell merging** - Merge ranges of cells
- **Data validation** - List, number range, text length, custom formula validations
- **Conditional formatting** - Apply conditional styles based on cell values
- **AutoFilter** - Add filter dropdowns to data ranges
- **Document encryption** - AES-128/256 encryption with password protection (ECMA-376 Agile)
- **Sheet protection** - Protect sheets with password and permission options
- **Type-safe API** - Sealed interfaces for cell values with pattern matching
- **GraalVM Native Image compatible**
## Requirements
- Java 17+
## Installation
### Maven
```xml
com.beingidly
litexl-17
0.1.7
```
## Quick Start
### Creating a Workbook
```java
import com.beingidly.litexl.*;
import java.nio.file.Path;
try (Workbook wb = Workbook.create()) {
Sheet sheet = wb.addSheet("My Sheet");
// Set cell values
sheet.cell(0, 0).set("Name");
sheet.cell(0, 1).set("Age");
sheet.cell(0, 2).set("Active");
sheet.cell(1, 0).set("Alice");
sheet.cell(1, 1).set(30);
sheet.cell(1, 2).set(true);
sheet.cell(2, 0).set("Bob");
sheet.cell(2, 1).set(25);
sheet.cell(2, 2).set(false);
// Save to file
wb.save(Path.of("output.xlsx"));
}
```
### Reading a Workbook
```java
try (Workbook wb = Workbook.open(Path.of("input.xlsx"))) {
Sheet sheet = wb.getSheet(0);
for (var row : sheet.rows().values()) {
for (var cell : row.cells().values()) {
System.out.println(cell.type() + ": " + cell.rawValue());
}
}
}
```
## Object Mapping with LitexlMapper
LitexlMapper provides annotation-based object mapping for Excel files. Define Java records with annotations and let litexl handle the conversion.
### Basic Mapping
```java
import com.beingidly.litexl.mapper.*;
import java.util.List;
// Define a row record
@LitexlRow
public record Person(
@LitexlColumn(index = 0, header = "Name")
String name,
@LitexlColumn(index = 1, header = "Age")
int age,
@LitexlColumn(index = 2, header = "Email")
String email
) {}
// Define a workbook record
@LitexlWorkbook
public record PeopleReport(
@LitexlSheet(name = "People")
List people
) {}
// Write to Excel
List people = List.of(
new Person("Alice", 30, "alice@example.com"),
new Person("Bob", 25, "bob@example.com")
);
LitexlMapper.write(new PeopleReport(people), Path.of("people.xlsx"));
// Read from Excel
PeopleReport report = LitexlMapper.read(Path.of("people.xlsx"), PeopleReport.class);
```
### Custom Type Converters
Convert between Excel values and domain types:
```java
// Custom domain type
public record Money(String currency, double amount) {}
// Custom converter
public class MoneyConverter implements LitexlConverter {
@Override
public Money fromCell(CellValue value) {
return switch (value) {
case CellValue.Text(String text) -> {
String[] parts = text.split(" ", 2);
yield new Money(parts[0], Double.parseDouble(parts[1]));
}
case CellValue.Number(double num) -> new Money("USD", num);
default -> null;
};
}
@Override
public CellValue toCell(Money value) {
return value != null
? new CellValue.Text(value.currency() + " " + value.amount())
: new CellValue.Empty();
}
}
// Use in row record
@LitexlRow
public record Product(
@LitexlColumn(index = 0, header = "Name")
String name,
@LitexlColumn(index = 1, header = "Price", converter = MoneyConverter.class)
Money price
) {}
```
### Style Providers
Apply styles using annotation-based providers:
```java
public class HeaderStyle implements LitexlStyleProvider {
@Override
public Style provide() {
return Style.builder()
.bold(true)
.fill(0xFF4472C4)
.color(0xFFFFFFFF)
.align(HAlign.CENTER, VAlign.MIDDLE)
.build();
}
}
@LitexlRow
public record SalesRecord(
@LitexlColumn(index = 0, header = "Product")
@LitexlStyle(HeaderStyle.class)
String product,
@LitexlColumn(index = 1, header = "Revenue")
double revenue
) {}
```
### Auto Region Detection
Read data that doesn't start at A1:
```java
@LitexlWorkbook
public record Report(
@LitexlSheet(name = "Data", regionDetection = RegionDetection.AUTO)
List rows
) {}
```
### Mapper Configuration
```java
LitexlMapper mapper = LitexlMapper.builder()
.dateFormat("yyyy-MM-dd")
.nullStrategy(NullStrategy.EMPTY_CELL)
.build();
Report report = mapper.readFile(path, Report.class);
mapper.writeFile(report, outputPath);
```
## Styling Cells
```java
import com.beingidly.litexl.style.*;
try (Workbook wb = Workbook.create()) {
Sheet sheet = wb.addSheet("Styled");
// Create styles
int headerStyle = wb.addStyle(Style.builder()
.bold(true)
.fill(0xFF4472C4) // Blue background
.color(0xFFFFFFFF) // White text
.align(HAlign.CENTER, VAlign.MIDDLE)
.build());
int numberStyle = wb.addStyle(Style.builder()
.format("#,##0.00")
.align(HAlign.RIGHT, VAlign.BOTTOM)
.border(BorderStyle.THIN, 0xFF000000)
.build());
// Apply styles
sheet.cell(0, 0).set("Revenue").style(headerStyle);
sheet.cell(1, 0).set(1234567.89).style(numberStyle);
wb.save(Path.of("styled.xlsx"));
}
```
## Formulas
```java
sheet.cell(0, 0).set(10);
sheet.cell(0, 1).set(20);
sheet.cell(0, 2).setFormula("A1+B1");
sheet.cell(1, 0).setFormula("SUM(A1:B1)");
```
## Merging Cells
```java
sheet.cell(0, 0).set("Merged Header");
sheet.merge(0, 0, 0, 5); // Merge A1:F1
```
## Data Validation
```java
import com.beingidly.litexl.format.DataValidation;
// Dropdown list
sheet.addValidation(DataValidation.list(
CellRange.of(1, 0, 100, 0), // A2:A101
"Yes", "No", "Maybe"
));
// Number range
sheet.addValidation(DataValidation.wholeNumber(
CellRange.of(1, 1, 100, 1), // B2:B101
1, 100
));
```
## AutoFilter
```java
sheet.setAutoFilter(0, 0, 100, 5); // A1:F101
```
## Encryption
```java
import com.beingidly.litexl.crypto.EncryptionOptions;
// Save with encryption
wb.save(Path.of("encrypted.xlsx"),
EncryptionOptions.aes256("password123"));
// Open encrypted file
try (Workbook wb = Workbook.open(
Path.of("encrypted.xlsx"), "password123")) {
// ...
}
```
## Sheet Protection
Protect sheets with passwords and configurable permissions:
```java
import com.beingidly.litexl.crypto.SheetProtection;
// Protect without password
sheet.protect(SheetProtection.defaults());
// Protect with password and custom permissions
sheet.protectionManager().protect("password".toCharArray(),
SheetProtection.builder()
.formatCells(true)
.insertRows(true)
.deleteRows(true)
.sort(true)
.autoFilter(true)
.build());
// Unprotect
sheet.protectionManager().unprotect("password".toCharArray());
```
## Type-Safe Cell Values
litexl uses sealed interfaces for type-safe cell values:
```java
CellValue value = cell.value();
String result = switch (value) {
case CellValue.Empty _ -> "empty";
case CellValue.Text t -> "text: " + t.value();
case CellValue.Number n -> "number: " + n.value();
case CellValue.Bool b -> "bool: " + b.value();
case CellValue.Date d -> "date: " + d.value();
case CellValue.Formula f -> "formula: " + f.expression();
case CellValue.Error e -> "error: " + e.code();
};
```
## Building from Source
```bash
git clone https://github.com/beingidly/litexl.git
cd litexl
./gradlew build
```
### Running Tests
```bash
./gradlew test
```
### Running Benchmarks
```bash
./gradlew jmh
```
### Building Native Image
```bash
./gradlew nativeCompile
```
## Architecture
```
litexl
├── com.beingidly.litexl # Public API
│ ├── Workbook # Main entry point
│ ├── Sheet # Worksheet
│ ├── Row # Row container
│ ├── Cell # Cell with value and style
│ ├── CellValue # Sealed interface for values
│ ├── CellRange # Range reference
│ └── CellType # Enum of cell types
├── com.beingidly.litexl.mapper # Object Mapping
│ ├── LitexlMapper # Main mapper class
│ ├── @LitexlWorkbook # Workbook annotation
│ ├── @LitexlSheet # Sheet annotation
│ ├── @LitexlRow # Row annotation
│ ├── @LitexlColumn # Column annotation
│ ├── @LitexlStyle # Style annotation
│ ├── LitexlConverter # Custom type converter
│ └── LitexlStyleProvider # Custom style provider
├── com.beingidly.litexl.style # Styling
│ ├── Style # Cell style
│ ├── Font # Font properties
│ ├── Border # Border properties
│ └── Alignment # Alignment settings
├── com.beingidly.litexl.format # Formatting
│ ├── ConditionalFormat # Conditional formatting
│ ├── DataValidation # Data validation rules
│ └── AutoFilter # AutoFilter settings
├── com.beingidly.litexl.crypto # Encryption
│ ├── EncryptionOptions # Encryption settings
│ └── SheetProtection # Sheet protection settings
└── com.beingidly.litexl.internal # Internal implementation
├── xlsx # XLSX read/write
├── xml # XML processing
├── zip # ZIP handling
└── crypto # Crypto utilities
```
## License
Apache License 2.0