|
1 | | -This is a Kotlin Multiplatform project targeting Android, iOS, Web, Desktop (JVM). |
2 | | - |
3 | | -* [/composeApp](./composeApp/src) is for code that will be shared across your Compose Multiplatform applications. |
4 | | - It contains several subfolders: |
5 | | - - [commonMain](./composeApp/src/commonMain/kotlin) is for code that’s common for all targets. |
6 | | - - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. |
7 | | - For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, |
8 | | - the [iosMain](./composeApp/src/iosMain/kotlin) folder would be the right place for such calls. |
9 | | - Similarly, if you want to edit the Desktop (JVM) specific part, the [jvmMain](./composeApp/src/jvmMain/kotlin) |
10 | | - folder is the appropriate location. |
11 | | - |
12 | | -* [/iosApp](./iosApp/iosApp) contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, |
13 | | - you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project. |
14 | | - |
15 | | -### Build and Run Android Application |
16 | | - |
17 | | -To build and run the development version of the Android app, use the run configuration from the run widget |
18 | | -in your IDE’s toolbar or build it directly from the terminal: |
19 | | -- on macOS/Linux |
20 | | - ```shell |
21 | | - ./gradlew :composeApp:assembleDebug |
22 | | - ``` |
23 | | -- on Windows |
24 | | - ```shell |
25 | | - .\gradlew.bat :composeApp:assembleDebug |
26 | | - ``` |
27 | | - |
28 | | -### Build and Run Desktop (JVM) Application |
29 | | - |
30 | | -To build and run the development version of the desktop app, use the run configuration from the run widget |
31 | | -in your IDE’s toolbar or run it directly from the terminal: |
32 | | -- on macOS/Linux |
33 | | - ```shell |
34 | | - ./gradlew :composeApp:run |
35 | | - ``` |
36 | | -- on Windows |
37 | | - ```shell |
38 | | - .\gradlew.bat :composeApp:run |
39 | | - ``` |
40 | | - |
41 | | -### Build and Run Web Application |
42 | | - |
43 | | -To build and run the development version of the web app, use the run configuration from the run widget |
44 | | -in your IDE's toolbar or run it directly from the terminal: |
45 | | -- for the Wasm target (faster, modern browsers): |
46 | | - - on macOS/Linux |
47 | | - ```shell |
48 | | - ./gradlew :composeApp:wasmJsBrowserDevelopmentRun |
49 | | - ``` |
50 | | - - on Windows |
51 | | - ```shell |
52 | | - .\gradlew.bat :composeApp:wasmJsBrowserDevelopmentRun |
53 | | - ``` |
54 | | -- for the JS target (slower, supports older browsers): |
55 | | - - on macOS/Linux |
56 | | - ```shell |
57 | | - ./gradlew :composeApp:jsBrowserDevelopmentRun |
58 | | - ``` |
59 | | - - on Windows |
60 | | - ```shell |
61 | | - .\gradlew.bat :composeApp:jsBrowserDevelopmentRun |
62 | | - ``` |
63 | | - |
64 | | -### Build and Run iOS Application |
65 | | - |
66 | | -To build and run the development version of the iOS app, use the run configuration from the run widget |
67 | | -in your IDE’s toolbar or open the [/iosApp](./iosApp) directory in Xcode and run it from there. |
68 | | - |
69 | | ---- |
70 | | - |
71 | | -Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html), |
72 | | -[Compose Multiplatform](https://github.com/JetBrains/compose-multiplatform/#compose-multiplatform), |
73 | | -[Kotlin/Wasm](https://kotl.in/wasm/)… |
74 | | - |
75 | | -We would appreciate your feedback on Compose/Web and Kotlin/Wasm in the public Slack channel [#compose-web](https://slack-chats.kotlinlang.org/c/compose-web). |
76 | | -If you face any issues, please report them on [YouTrack](https://youtrack.jetbrains.com/newIssue?project=CMP). |
| 1 | +# FileMapper KMP |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +A lightweight, powerful **Kotlin Multiplatform (KMP)** library designed to seamlessly map files (XLSX, JSON) to Kotlin Data Classes. Supporting Android, iOS, Desktop, and Web (Wasm/JS), it provides both Compose-ready UI triggers and pure logic-based APIs. |
| 13 | + |
| 14 | +----- |
| 15 | + |
| 16 | +## 🚀 Features |
| 17 | + |
| 18 | +| Feature | Description | |
| 19 | +| :--- | :--- | |
| 20 | +| **Multi-Format** | Support for `.xlsx` and `.json` file types. | |
| 21 | +| **Type-Safe Mapping** | Automatically converts file rows/objects into Kotlin Data Classes. | |
| 22 | +| **Platform-Agnostic** | Unified API for Android, iOS, Desktop (JVM), and Web (Wasm/JS). | |
| 23 | +| **Compose Integration** | Pre-built Composable controller for easy state management. | |
| 24 | +| **Flexible Logic** | Pure `suspend` functions for Use Cases and ViewModels. | |
| 25 | +| **Excel Control** | Use annotations to map specific columns or ignore unmapped data. | |
| 26 | + |
| 27 | +----- |
| 28 | + |
| 29 | +## 📦 Setup |
| 30 | + |
| 31 | +Add the dependency to your `commonMain` source set in `build.gradle.kts`: |
| 32 | + |
| 33 | +```kotlin |
| 34 | +kotlin { |
| 35 | + sourceSets { |
| 36 | + commonMain.dependencies { |
| 37 | + implementation("io.github.mamon-aburawi:filemapper-kmp:{last_version}") |
| 38 | + } |
| 39 | + } |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +----- |
| 44 | + |
| 45 | +## 🛠 Implementation |
| 46 | + |
| 47 | +### 1\. Define your Data Model |
| 48 | + |
| 49 | +Ensure your data class is annotated with `@Serializable` (from `kotlinx.serialization`) and use `@ColumnName` to link Excel headers. |
| 50 | + |
| 51 | +```kotlin |
| 52 | +import kotlinx.serialization.Serializable |
| 53 | +import io.mamon.filemapper.ColumnName |
| 54 | + |
| 55 | +@Serializable |
| 56 | +data class Employee( |
| 57 | + @ColumnName("Full Name") // Matches Excel Header |
| 58 | + val name: String, |
| 59 | + |
| 60 | + @ColumnName("Email Address") |
| 61 | + val email: String, |
| 62 | + |
| 63 | + val age: Int |
| 64 | +) |
| 65 | +``` |
| 66 | + |
| 67 | +### 2\. Usage in Compose (UI) |
| 68 | + |
| 69 | +Use the `rememberFileMapper` controller for a seamless UI experience. It handles picking, importing, and exporting in one place. |
| 70 | + |
| 71 | +```kotlin |
| 72 | +val fileMapperController = rememberFileMapper<Employee>( |
| 73 | + fileType = selectedFileType, |
| 74 | + onImportSuccess = { employeeList -> |
| 75 | + mEmployees = employeeList |
| 76 | + statusMessage = "Successfully imported ${employeeList.size} employees." |
| 77 | + }, |
| 78 | + onExportSuccess = { savedPath -> |
| 79 | + statusMessage = "Successfully exported to $savedPath" |
| 80 | + }, |
| 81 | + onImportFailed = { error -> |
| 82 | + statusMessage = error.getLocalizedMessage() |
| 83 | + }, |
| 84 | + onExportFailed = { error -> |
| 85 | + statusMessage = "Export Error: ${error.getLocalizedMessage()}" |
| 86 | + } |
| 87 | +) |
| 88 | + |
| 89 | +// Trigger the picker |
| 90 | +Button(onClick = { fileMapperController.import() }) { |
| 91 | + Text("Import Employees") |
| 92 | +} |
| 93 | + |
| 94 | +// Trigger the export |
| 95 | +Button(onClick = { fileMapperController.export(mEmployees, "YourFileName") }) { |
| 96 | + Text("Export to Excel") |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +### 3\. Usage in Non-Compose (Logic) |
| 101 | + |
| 102 | +Trigger picking and mapping from a ViewModel or shared logic using the `FileMapperPicker` and `importData` API. |
| 103 | + |
| 104 | +```kotlin |
| 105 | +scope.launch { |
| 106 | + // 1. Pick the file using the platform picker |
| 107 | + val file = FileMapperPicker.pickFile(type = selectedFileType) |
| 108 | + |
| 109 | + if (file != null) { |
| 110 | + // 2. Read bytes and import data |
| 111 | + fileMapper.importData<Employee>( |
| 112 | + bytes = file.readBytes(), |
| 113 | + ignoreColumns = emptySet(), |
| 114 | + onSuccess = { employeeList -> |
| 115 | + mEmployees = employeeList |
| 116 | + statusMessage = "Successfully imported ${employeeList.size} employees." |
| 117 | + }, |
| 118 | + onFailed = { error -> |
| 119 | + statusMessage = error.getLocalizedMessage() |
| 120 | + } |
| 121 | + ) |
| 122 | + } |
| 123 | +} |
| 124 | +``` |
| 125 | + |
| 126 | +----- |
| 127 | + |
| 128 | +## 📑 Annotations & Configuration |
| 129 | + |
| 130 | +| Annotation / Property | Description | |
| 131 | +| :--- | :--- | |
| 132 | +| `@Serializable` | Required for the engine to parse the data class structure. | |
| 133 | +| `@ColumnName("Name")` | Maps a specific Excel header string to a Kotlin property. | |
| 134 | +| `ignoreUnmappedColumns` | used if you want to ignore the columns in the excel file that does not mapped in data class. | |
| 135 | +| `ignoreColumns` | Set of strings to skip during the export/import process. | |
| 136 | + |
| 137 | +----- |
| 138 | + |
| 139 | +## ⚠️ Errors & Exceptions |
| 140 | + |
| 141 | +The library uses a specialized `FileMapperException` to provide localized feedback. |
| 142 | + |
| 143 | +| Error Code | Meaning | |
| 144 | +| :--- | :--- | |
| 145 | +| `EMPTY_FILE` | The selected file is empty. | |
| 146 | +| `INVALID_FORMAT` | Invalid file format. Expected XLSX or JSON. | |
| 147 | +| `READ_FAILED` | Failed to read the selected file. | |
| 148 | +| `EXPORT_FAILED` | An error occurred during export. | |
| 149 | +| `NO_DATA_ROWS` | The file contains no data rows. | |
| 150 | +| `ALL_COLUMNS_IGNORED` | All columns for the target data class are ignored. | |
| 151 | +| `MISSING_COLUMNS` | Missing Required Columns. | |
| 152 | +| `UNEXPECTED_COLUMNS` | Unexpected Columns found. | |
| 153 | +| `UNEXPECTED_ERROR` | An unexpected error occurred. | |
| 154 | + |
| 155 | +### Localized Messages |
| 156 | + |
| 157 | +Retrieve error messages in the user's system language (English/Arabic) automatically: |
| 158 | + |
| 159 | +```kotlin |
| 160 | +// Works in both Compose and Non-Compose (Suspend) contexts |
| 161 | +val message = exception.getLocalizedMessage() |
| 162 | +``` |
| 163 | + |
| 164 | +----- |
| 165 | + |
| 166 | +## 🌟 Support the Project |
| 167 | + |
| 168 | +If this library helped you save time on your KMP project, please consider giving it a star\! It helps more developers find the project. |
| 169 | + |
| 170 | +**[ ⭐ Star this Repository ]** |
| 171 | + |
| 172 | +----- |
| 173 | + |
| 174 | +*Developed by [Mamon Aburawi](https://github.com/mamon-aburawi) — 2026* |
0 commit comments