An open API service indexing awesome lists of open source software.

https://github.com/gautric/excel-as-a-service

Excel Quarkus Service
https://github.com/gautric/excel-as-a-service

Last synced: 4 months ago
JSON representation

Excel Quarkus Service

Awesome Lists containing this project

README

          

= Excel Engine by Quarkus

== Introduction

Excel-as-a-Service (EaaS) is a modern, distributed Excel computation engine that exposes Excel workbook calculations through multiple protocols including REST, gRPC, Kafka, and AWS Lambda.
It enables organizations to leverage existing Excel business logic as scalable microservices without modifying the original spreadsheets.

image::https://github.com/gautric/excel-as-a-service/actions/workflows/eaas-ci.yml/badge.svg[]

== Dependencies

* Java
** 21

* POI
** 5.4

* Quarkus
** 3.19.4

== Repository Structure

```
excel-app/
├── excel-engine/ # Core Excel computation engine with Apache POI integration
├── excel-cdi/ # CDI implementation of the Excel engine components
├── excel-rest/ # REST API implementation with OpenAPI documentation
├── excel-grpc/ # gRPC service implementation
├── excel-kafka/ # Kafka integration with WebSocket and SSE support
├── excel-lambda/ # AWS Lambda implementation
└── sample/ # Sample Excel files and API definitions
```

== Run Application

To run application

mvn clean install
cd excel-rest
mvn quarkus:dev -Dexcel.static.resouces.uri=../sample

== Call REST API

=== The OpenAPI URL

open -a Firefox http://localhost:8080/q/swagger-ui/

=== Retrieve all Excel resources available

curl http://localhost:8080/eaas/api

=== Retrieve all Sheet of the Excel resources

curl http://localhost:8080/eaas/api/{resource}

=== Download the Excel resource

curl -J -O http://localhost:8080/eaas/api/{resource}/_download

=== Retrieve all Formula from a Sheet of the Excel resources

curl http://localhost:8080/eaas/api/{resource}/{sheet}

=== Compute or Retrieve a Cell Value

curl http://localhost:8080/eaas/api/{resource}/{sheet}/{cell}

== Sample Test

curl 'http://localhost:8080/eaas/api'

```
{
"_links" : [ {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api",
"type" : "application/json"
} ],
"_count" : 1,
"resources" : [ {
"_links" : [ {
"rel" : "list-of-resource",
"href" : "http://localhost:8080/eaas/api",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "download",
"href" : "http://localhost:8080/eaas/api/KYC/_download",
"type" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}, {
"rel" : "list-of-sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheets",
"type" : "application/json"
} ],
"name" : "KYC",
"file" : "KYC.xlsx"
}]
}
```

curl 'http://localhost:8080/eaas/api/KYC'

```
{
"_links" : [ {
"rel" : "list-of-resource",
"href" : "http://localhost:8080/eaas/api",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "download",
"href" : "http://localhost:8080/eaas/api/KYC/_download",
"type" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}, {
"rel" : "list-of-sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheets",
"type" : "application/json"
} ],
"name" : "KYC",
"file" : "KYC.xlsx"
}
```

with a KYC sample :

curl 'http://localhost:8080/eaas/api/KYC/sheets'

```
{
"_links" : [ {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheets",
"type" : "application/json"
} ],
"_count" : 3,
"sheets" : [ {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "list-of-cell",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cells",
"type" : "application/json"
}, {
"rel" : "list-of-template",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/compute",
"type" : "application/json"
} ],
"name" : "ComputeKYC"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/COUNTRY",
"type" : "application/json"
}, {
"rel" : "list-of-cell",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/COUNTRY/cells",
"type" : "application/json"
}, {
"rel" : "list-of-template",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/COUNTRY/compute",
"type" : "application/json"
} ],
"name" : "COUNTRY"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/AMOUNT",
"type" : "application/json"
}, {
"rel" : "list-of-cell",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/AMOUNT/cells",
"type" : "application/json"
}, {
"rel" : "list-of-template",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/AMOUNT/compute",
"type" : "application/json"
} ],
"name" : "AMOUNT"
} ]
}
```

curl 'http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC'

```
{
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "list-of-cell",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cells",
"type" : "application/json"
}, {
"rel" : "list-of-template",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/compute",
"type" : "application/json"
} ],
"name" : "ComputeKYC"
}
```

curl 'http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cells'

```
{
"_links" : [ {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cells",
"type" : "application/json"
} ],
"_count" : 15,
"cells" : [ {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/A1",
"type" : "application/json"
} ],
"address" : "ComputeKYC!A1",
"value" : "",
"type" : "BLANK"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/B1",
"type" : "application/json"
} ],
"address" : "ComputeKYC!B1",
"value" : "INPUT",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C1",
"type" : "application/json"
} ],
"address" : "ComputeKYC!C1",
"value" : " SCORE",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/A2",
"type" : "application/json"
} ],
"address" : "ComputeKYC!A2",
"value" : "PEP",
"metadata" : "@input",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/B2",
"type" : "application/json"
} ],
"address" : "ComputeKYC!B2",
"value" : "false",
"type" : "BOOLEAN"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C2",
"type" : "application/json"
} ],
"address" : "ComputeKYC!C2",
"value" : "IF(B2,50,0)",
"type" : "FORMULA"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/A3",
"type" : "application/json"
} ],
"address" : "ComputeKYC!A3",
"value" : "COUNTRY",
"metadata" : "@input",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/B3",
"type" : "application/json"
} ],
"address" : "ComputeKYC!B3",
"value" : "FR",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C3",
"type" : "application/json"
} ],
"address" : "ComputeKYC!C3",
"value" : "VLOOKUP(B3,COUNTRY!A1:B5,2,FALSE)",
"type" : "FORMULA"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/A4",
"type" : "application/json"
} ],
"address" : "ComputeKYC!A4",
"value" : "AMOUNT",
"metadata" : "@input",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/B4",
"type" : "application/json"
} ],
"address" : "ComputeKYC!B4",
"value" : 0.0,
"type" : "NUMERIC"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C4",
"type" : "application/json"
} ],
"address" : "ComputeKYC!C4",
"value" : "VLOOKUP(B4,AMOUNT!A1:B5,2,TRUE)",
"type" : "FORMULA"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/A5",
"type" : "application/json"
} ],
"address" : "ComputeKYC!A5",
"value" : "",
"type" : "BLANK"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/A6",
"type" : "application/json"
} ],
"address" : "ComputeKYC!A6",
"value" : "FINAL",
"type" : "STRING"
}, {
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C6",
"type" : "application/json"
} ],
"address" : "ComputeKYC!C6",
"value" : "SUM(C2:C4)",
"metadata" : "@output",
"type" : "FORMULA"
} ]
}
```

curl 'http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C6?B2=TRUE&B3=CY&B4=1000000'

```
{
"_links" : [ {
"rel" : "resource",
"href" : "http://localhost:8080/eaas/api/KYC",
"type" : "application/json"
}, {
"rel" : "sheet",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC",
"type" : "application/json"
}, {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C6",
"type" : "application/json"
}, {
"rel" : "query",
"href" : "http://localhost:8080/eaas/api/KYC/sheet/ComputeKYC/cell/C6?B2=TRUE&B3=CY&B4=1000000",
"type" : "application/json"
} ],
"address" : "ComputeKYC!C6",
"value" : 125.0,
"metadata" : "@output",
"type" : "NUMERIC"
}
```

You can use also POST

curl -X POST -H "Content-Type: application/json" -d @sample/api_post_ComputeKYC.json http://localhost:8080/eaas/api/KYCAPI/sheet/ComputeKYC/compute

```
{
"_links" : [ {
"rel" : "self",
"href" : "http://localhost:8080/eaas/api/KYCAPI/sheet/ComputeKYC/compute",
"type" : "application/json"
} ],
"_count" : 1,
"cells" : [ {
"address" : "ComputeKYC!C6",
"value" : 125.0,
"metadata" : "@output(SCORE)",
"type" : "NUMERIC"
} ]
}

```

You can use also POST

curl -X POST -H "Content-Type: application/json" -d @sample/kafka_ComputeKYC.json http://localhost:8080/eaas/kafka

== Tips for Excel dev

* Include a default value into all Excel cells
** client can retrieve the value
** Excel engine can deal with the type of the cell

* Use only POI implemented functions
** https://poi.apache.org/components/spreadsheet/eval-devguide.html#Appendix+A+%E2%80%94+Functions+supported+by+POI[POI function available list]

== Configuration

.Configuration property
[%header,cols=4*]
|===

|Properties
|Type
|Default
|Comments

| `excel.static.resouces.uri`
| String
| `.`
| `classpath://` or _directory_ or _file_

| `excel.return.list.or.map`
| String/Enum
| `MAP`
| Return result into List (`LIST`) or Map(`MAP`)

| `excel.static.readonly`
| boolean
| `false`
| if `true` you cannot use POST method to add new file

|===