██ ██ ██ ▄█████ ██ ██ ██ ▄█████ ▄████▄ ███ ██ ▄█████ ██████ ██████ ████▄
████ ██ ▀▀▀▄▄▄ ████ ██ ▀▀▀▄▄▄ ██ ██ ██ ▀▄██ ▀▀▀▄▄▄ ██▄▄ ██▄▄ ██ ██
██ ██ ██████ █████▀ ██ ██ ████▀ █████▀ ▀████▀ ██ ██ █████▀ ██▄▄▄▄ ██▄▄▄▄ ████▀
A Blazingly Fast, Nitro-Boosted tool for processing and automating Excel (.xlsx) data for database schema purposes (including Firestore) using a simple YAML instruction file.
Can be used together with json-firestore-seed to process firestore data entry.
Built in C++, powered by OpenXLSX, and yaml-cpp.
See at OpenXLSX's repo https://github.com/troldal/OpenXLSX (since it may be updated at anytime)
OpenXLSX version used in this project is (aral-matrix) 14 July 2025.
- Supports Firestore timestamps (works with json-firestore-seed)
- Read
.xlsxExcel files your client (customer) gives and convert to json for database schema - Export to JSON, CSV or back to XLSX
- Automate via YAML scripting
- Add, remove, group-as-array, renumbering, fill, split, uppercase, replace, and more
- Dynamic value support
- Blazingly Fast native runtime
- Easy to extend with new operations
git clone https://github.com/shayyz-code/xlsx-json-seed
cd xlsx-json-seedvcpkg install openxlsx yaml-cppOr with manifest mode:
vcpkg installcmake -B build -DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg.cmake
cmake --build build --config ReleaseCLI binary will be at:
build/xlsx_json_seed
./build/xlsx_json_seed --script script.yaml
or
./build/xlsx_json_seed --s script.yaml
script.yaml and input.xlsx can be found in ./example.
input: "example/input.xlsx"
output: "example/result"
header-row: 1
first-data-row: 2
export-csv: true
operations:
- type: split-column
column: B
delimiter: "-"
split-to: [E, F, G]
new-headers: ["Code", "Size", "Color"]
proper-positions: [1, 2, 3]
# - type: uppercase-column
# column: G
# - type: replace-in-column
# column: C
# find: "-"
# replace: ","
- type: fill-column
column: H
fill-with: "firestore-random-past-date-n-year-2"
new-header: "Created At"
- type: add-column
at: "end"
fill-with: "firestore-now"
new-header: "Updated At"
- type: add-column
at: "start"
fill-with: "${ifcol F == GH ? 'gh and' : } ${col H}" # fill with values from column F
new-header: "Dynamic Value"
- type: sort-rows-by-column
column: F
ascending: true
- type: group-collect
group-by: F # column with BN (type column)
to-array-columns: [H, G] # Colors and Sizes
mark-unique-items: true # colors will not duplicate
to-array-output-columns: [H, G] # write array back to color and size column
do-maths-columns: [E]
do-maths-operations: ["sum"]
- type: reassign-numbering
column: B
prefix: ""
suffix: "."
start-from: 1
step: 1
- type: remove-column
column: C
# - type: transform-row
# row: 1
# to: "camelCase"
# delimiter: " "
- type: rename-header
column: G
new-name: "Colors"
- type: transform-header
to: "snake_case"
delimiter: " "
JSON:
[
{
"dynamic_value": " PURPLE",
"no": "1.",
"product_name": "B Necklace",
"price": 2000.0,
"code": "BN",
"size": [
"XS",
"S"
],
"colors": [
"PURPLE",
"RED"
],
"created_at": {
"__fire_ts_from_date__": "2025-01-02T21:10:29Z"
},
"updated_at": "__fire_ts_now__"
},
{
"dynamic_value": "gh and BLUE",
"no": "2.",
"product_name": "G Handbag",
"price": 700.0,
"code": "GH",
"size": [],
"colors": [
"BLUE",
"BROWN",
"RED"
],
"created_at": {
"__fire_ts_from_date__": "2024-09-01T11:34:29Z"
},
"updated_at": "__fire_ts_now__"
},
{
"dynamic_value": " WHITE",
"no": "3.",
"product_name": "V Shirt",
"price": 60.0,
"code": "VG",
"size": [
"XS"
],
"colors": [
"WHITE"
],
"created_at": {
"__fire_ts_from_date__": "2024-11-13T12:00:28Z"
},
"updated_at": "__fire_ts_now__"
}
]CSV:
| dynamic_value | no | product_name | price | code | size | colors | created_at | updated_at |
|:----------------|-----:|:---------------|--------:|:-------|:-----------|:-----------------------|:----------------------------------------------------|:----------------|
| PURPLE | 1 | B Necklace | 2000 | BN | ["XS","S"] | ["PURPLE","RED"] | { "__fire_ts_from_date__": "2025-01-02T21:10:29Z" } | __fire_ts_now__ |
| gh and BLUE | 2 | G Handbag | 700 | GH | [] | ["BLUE","BROWN","RED"] | { "__fire_ts_from_date__": "2024-09-01T11:34:29Z" } | __fire_ts_now__ |
| WHITE | 3 | V Shirt | 60 | VG | ["XS"] | ["WHITE"] | { "__fire_ts_from_date__": "2024-11-13T12:00:28Z" } | __fire_ts_now__ || Operation Type | Description | Required Fields | Optional Fields |
|---|---|---|---|
split-column |
Splits a column into multiple parts by a delimiter. | column, delimiter, split-to, new-headers, proper-positions |
— |
replace-in-column |
Replaces occurrences of a substring within a column. | column, find, replace |
— |
fill-column |
Fills a column with a constant or dyanmic value and optionally renames the header. | column, fill-with // Dynamic -> ${col F} |
new-header |
add-column |
Adds a column at the start, end, before, or after another column. | at, fill-with, new-header |
— |
uppercase-column |
Converts the entire column to uppercase. | column |
— |
sort-rows-by-column |
Sorts rows by a given column (ascending/descending). | column |
ascending (default true) |
group-collect |
Groups rows as array and do math operations at the same time in a row. | group-by, to-array-column, to-array-output-column, mark-unique-items, do-maths-column, do-maths-operation |
— |
reassign-numbering |
Replaces a numeric column with a new sequence number format. | column, prefix, suffix |
start-from (default 1), step (1) |
remove-column |
Deletes a column entirely. | column |
— |
rename-header |
Renames a column header. | column, new-name |
— |
transform-row |
Transforms one row into another format (camelCase, snake_case, etc.). | row, to |
delimiter |
transform-header |
Transforms all headers (camelCase, snake_case, etc.). | to |
delimiter |
Pull requests and feature suggestions are welcome! Feel free to open an issue to discuss ideas.
MIT License — free for personal & commercial use.
Copyright (c) 2025 shayyz-code.