Excel Generation & Exporting
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/java/io/github/mojri/hesabyar/domain/usecase/ExportExcelUseCase.kt
- app/src/main/java/io/github/mojri/hesabyar/data/ExcelExporter.kt
- rust/hesabyar-core/src/excel.rs
- app/src/main/java/io/github/mojri/hesabyar/ui/ExportViewModel.kt
- app/src/main/java/io/github/mojri/hesabyar/rust/RustBridge.kt
- rust/hesabyar-core/src/ffi/mod.rs
The Excel Generation and Exporting system in Hesabyar provides users with the ability to export their financial data—including transactions, loans, and installments—into a standardized .xlsx format. This feature utilizes a hybrid architecture where data preparation and UI interactions occur in Kotlin (Android), while the high-performance serialization and workbook construction are offloaded to a native Rust core (hesabyar-core) via UniFFI.
Sources: README.md:129-131, app/src/main/java/io/github/mojri/hesabyar/data/ExcelExporter.kt:12-32, rust/hesabyar-core/src/excel.rs:35-40
Architectural Overview
The export process follows a layered approach, transitioning from the UI layer down to the native Rust implementation.
- UI Layer: The
ExportViewModelmanages the export state and triggers the use case. - Domain Layer:
ExportExcelUseCaseorchestrates data retrieval from the repository. - Data Layer:
ExcelExportertransforms domain entities into a pre-formattedWorkbookDatastructure. - Native Bridge:
RustBridgecommunicates with the native library. - Native Core:
hesabyar-core(Rust) uses therust_xlsxwritercrate to generate the actual byte array for the Excel file.
Sources: app/src/main/java/io/github/mojri/hesabyar/ui/ExportViewModel.kt:25-35, app/src/main/java/io/github/mojri/hesabyar/domain/usecase/ExportExcelUseCase.kt:13-21, app/src/main/java/io/github/mojri/hesabyar/rust/RustBridge.kt:208-208
System Data Flow
The following diagram illustrates the sequence of events from a user request to the final file saving in the Android Downloads folder.
The diagram shows the synchronous/asynchronous flow through the application layers.
Sources: app/src/main/java/io/github/mojri/hesabyar/ui/ExportViewModel.kt:35-45, app/src/main/java/io/github/mojri/hesabyar/data/ExcelExporter.kt:34-45
Data Transformation and Formatting
Before data is sent to Rust, it is localized and formatted in Kotlin. This includes converting timestamps to Jalali dates and formatting currency strings.
Key Data Structures
| Structure | Source | Description |
|---|---|---|
WorkbookData | excel.rs | Root container holding a list of SheetData. |
SheetData | excel.rs | Represents a single tab; contains headers, rows, and an optional summary row. |
Cell | excel.rs | Contains the localized String value and a bold boolean flag for styling. |
ExportResult | ExcelExporter.kt | Metadata returned to the UI, including byte array and summary counts. |
Sources: rust/hesabyar-core/src/excel.rs:6-32, app/src/main/java/io/github/mojri/hesabyar/data/ExcelExporter.kt:13-21
Sheet Mapping Logic
The ExcelExporter builds five specific sheets:
- All Transactions: Every transaction with type, category, amount, description, and Jalali date.
- Incomes: Filtered income transactions with a total summary row.
- Expenses: Filtered expense transactions with a total summary row.
- Loans: List of loans, persons, amounts, and settlement status.
- Installments: List of installments, due dates, and payment status.
Sources: app/src/main/java/io/github/mojri/hesabyar/data/ExcelExporter.kt:47-65
Native Generation (Rust)
The native logic in rust/hesabyar-core/src/excel.rs handles the low-level XLSX creation. It utilizes the rust_xlsxwriter library to define styles and layouts.
Implementation Details
- Right-to-Left (RTL): All sheets are set to RTL mode to accommodate the Persian language.
- Frozen Panes: The first row (headers) is frozen for better navigation.
- Auto-scaling Columns: Column widths are dynamically calculated based on the maximum content length in each column, with a minimum width of 8 and a padding of 4.
- Styling:
- Headers: Bold, size 12 font, dark blue background (
0x1F3864), white text, and centered alignment. - Summary Rows: Bold text with thin borders.
- Data Cells: Thin borders.
- Headers: Bold, size 12 font, dark blue background (
The flow of workbook assembly within the Rust core.
Sources: rust/hesabyar-core/src/excel.rs:41-135
Android File Persistence
The ExportViewModel handles the platform-specific logic for saving the generated bytes to the user's device.
- API >= 29 (Scoped Storage): Uses
MediaStore.Downloadsto insert the file into the public Downloads directory without needing broad storage permissions. - API < 29: Uses
Environment.getExternalStoragePublicDirectorywith direct file writing. - MIME Type:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet. - Filename Pattern: Generated as
hesabyar_report_YYYYMMDD_HHMMSS.xlsxusing the Jalali calendar for the date part.
Sources: app/src/main/java/io/github/mojri/hesabyar/ui/ExportViewModel.kt:80-110, app/src/main/java/io/github/mojri/hesabyar/data/ExcelExporter.kt:145-157
Summary
The Excel Generation & Exporting module bridges high-level financial data management in Kotlin with high-performance XLSX serialization in Rust. By pre-formatting data into a SheetData structure in the JVM layer and utilizing rust_xlsxwriter for the heavy lifting, the system ensures localized, well-styled, and memory-efficient report generation suitable for mobile environments.
Sources: rust/hesabyar-core/README.md:12-12, app/src/main/java/io/github/mojri/hesabyar/ui/ExportViewModel.kt:35-50