Skip to content

Commit 7278200

Browse files
authored
Merge pull request #36 from dsl-builders/feat/spreadsheet-cli
feat: add spreadsheet builder CLI
2 parents 1593851 + 15649df commit 7278200

7 files changed

Lines changed: 1108 additions & 0 deletions

File tree

README.adoc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,73 @@ Google Sheets are also supported indirectly (native Excel <=> Google conversion)
77

88
See the link:http://spreadsheet.dsl.builders/[Full Documentation]
99

10+
== Command Line
11+
12+
The `spreadsheet-builder-cli` project provides a small command line wrapper around
13+
`spreadsheet-builder-data` and `spreadsheet-builder-poi`.
14+
15+
Create an Excel workbook from JSON/YAML data:
16+
17+
[source,bash]
18+
----
19+
spreadsheet-builder-cli create people.yml people.xlsx
20+
----
21+
22+
Query an Excel workbook with serialized JSON/YAML criteria:
23+
24+
[source,bash]
25+
----
26+
spreadsheet-builder-cli query people.xlsx query.yml
27+
----
28+
29+
The query file mirrors the criteria DSL tree, so it can express workbook,
30+
sheet, row, cell, page, and style criteria instead of a one-off filter shape:
31+
32+
YAML criteria:
33+
34+
[source,yaml]
35+
----
36+
sheets:
37+
- name: People
38+
rows:
39+
- from: 2
40+
to: 10
41+
cells:
42+
- column: C
43+
value: Prague
44+
----
45+
46+
The same query as JSON criteria:
47+
48+
[source,json]
49+
----
50+
{
51+
"sheets": [
52+
{
53+
"name": "People",
54+
"rows": [
55+
{
56+
"from": 2,
57+
"to": 10,
58+
"cells": [
59+
{
60+
"column": "C",
61+
"value": "Prague"
62+
}
63+
]
64+
}
65+
]
66+
}
67+
]
68+
}
69+
----
70+
71+
A JSON Schema for query files is packaged with the CLI at
72+
link:libs/spreadsheet-builder-cli/src/main/resources/builders/dsl/spreadsheet/cli/query.schema.json[`query.schema.json`]
73+
and published in the website docs at link:https://spreadsheet.dsl.builders/schema/query.schema.json[`schema/query.schema.json`].
74+
It describes the same structure for both JSON and YAML query files.
75+
76+
The query command returns matching `sheets`, `rows`, and `cells` as JSON.
77+
1078
== Acknowledgement
1179
This project is inspired by http://www.craigburke.com/document-builder/[Groovy Document Builder]

docs/guide/src/docs/asciidoc/index.adoc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,74 @@ dependencies {
5252
----
5353

5454

55+
== Command Line
56+
57+
The `spreadsheet-builder-cli` module provides a small command line wrapper around
58+
`spreadsheet-builder-data` and `spreadsheet-builder-poi`.
59+
60+
Create an Excel workbook from JSON/YAML data:
61+
62+
[source,bash]
63+
----
64+
spreadsheet-builder-cli create people.yml people.xlsx
65+
----
66+
67+
Query an Excel workbook with serialized JSON/YAML criteria:
68+
69+
[source,bash]
70+
----
71+
spreadsheet-builder-cli query people.xlsx query.yml
72+
----
73+
74+
The query file mirrors the criteria DSL tree, so it can express workbook,
75+
sheet, row, cell, page, and style criteria instead of a one-off filter shape.
76+
77+
YAML criteria:
78+
79+
[source,yaml]
80+
----
81+
sheets:
82+
- name: People
83+
rows:
84+
- from: 2
85+
to: 10
86+
cells:
87+
- column: C
88+
value: Prague
89+
----
90+
91+
The same query as JSON criteria:
92+
93+
[source,json]
94+
----
95+
{
96+
"sheets": [
97+
{
98+
"name": "People",
99+
"rows": [
100+
{
101+
"from": 2,
102+
"to": 10,
103+
"cells": [
104+
{
105+
"column": "C",
106+
"value": "Prague"
107+
}
108+
]
109+
}
110+
]
111+
}
112+
]
113+
}
114+
----
115+
116+
The query command returns matching `sheets`, `rows`, and `cells` as JSON.
117+
118+
The query JSON Schema is published with this guide at
119+
link:schema/query.schema.json[`schema/query.schema.json`] and can be used for
120+
both JSON and YAML query files.
121+
122+
55123
== Writing Spreadsheets
56124

57125
Following example creates the basic spreadsheet with two rows and three columns.
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://spreadsheet.dsl.builders/schema/query.schema.json",
4+
"title": "Spreadsheet Builder CLI Query Criteria",
5+
"description": "Serialized criteria tree accepted by `spreadsheet-builder-cli query`. The same shape can be written as JSON or YAML.",
6+
"$ref": "#/$defs/workbookCriterion",
7+
"$defs": {
8+
"oneOrManySheets": {
9+
"oneOf": [
10+
{ "$ref": "#/$defs/sheetCriterion" },
11+
{
12+
"type": "array",
13+
"items": { "$ref": "#/$defs/sheetCriterion" }
14+
}
15+
]
16+
},
17+
"oneOrManyRows": {
18+
"oneOf": [
19+
{ "$ref": "#/$defs/rowCriterion" },
20+
{
21+
"type": "array",
22+
"items": { "$ref": "#/$defs/rowCriterion" }
23+
}
24+
]
25+
},
26+
"oneOrManyCells": {
27+
"oneOf": [
28+
{ "$ref": "#/$defs/cellCriterion" },
29+
{
30+
"type": "array",
31+
"items": { "$ref": "#/$defs/cellCriterion" }
32+
}
33+
]
34+
},
35+
"oneOrManyWorkbookAlternatives": {
36+
"oneOf": [
37+
{ "$ref": "#/$defs/workbookCriterion" },
38+
{
39+
"type": "array",
40+
"items": { "$ref": "#/$defs/workbookCriterion" }
41+
}
42+
]
43+
},
44+
"oneOrManySheetAlternatives": {
45+
"oneOf": [
46+
{ "$ref": "#/$defs/sheetCriterion" },
47+
{
48+
"type": "array",
49+
"items": { "$ref": "#/$defs/sheetCriterion" }
50+
}
51+
]
52+
},
53+
"oneOrManyRowAlternatives": {
54+
"oneOf": [
55+
{ "$ref": "#/$defs/rowCriterion" },
56+
{
57+
"type": "array",
58+
"items": { "$ref": "#/$defs/rowCriterion" }
59+
}
60+
]
61+
},
62+
"oneOrManyCellAlternatives": {
63+
"oneOf": [
64+
{ "$ref": "#/$defs/cellCriterion" },
65+
{
66+
"type": "array",
67+
"items": { "$ref": "#/$defs/cellCriterion" }
68+
}
69+
]
70+
},
71+
"cellAddress": {
72+
"description": "Excel column name such as A/C/AA, or a one-based numeric column index.",
73+
"oneOf": [
74+
{ "type": "integer", "minimum": 1 },
75+
{ "type": "string", "pattern": "^[A-Za-z]+$" }
76+
]
77+
},
78+
"workbookCriterion": {
79+
"type": "object",
80+
"additionalProperties": false,
81+
"properties": {
82+
"sheets": { "$ref": "#/$defs/oneOrManySheets" },
83+
"sheet": {
84+
"type": "string",
85+
"description": "Shortcut for selecting a sheet by name when sheet criteria live at the root."
86+
},
87+
"or": { "$ref": "#/$defs/oneOrManyWorkbookAlternatives" }
88+
},
89+
"anyOf": [
90+
{ "required": ["sheets"] },
91+
{ "required": ["sheet"] },
92+
{ "required": ["or"] }
93+
]
94+
},
95+
"sheetCriterion": {
96+
"type": "object",
97+
"additionalProperties": false,
98+
"properties": {
99+
"name": { "type": "string" },
100+
"state": {
101+
"type": "string",
102+
"description": "Sheet state. Case-insensitive in the CLI; hyphens are treated as underscores.",
103+
"examples": ["visible", "hidden", "very-hidden", "locked"]
104+
},
105+
"page": { "$ref": "#/$defs/pageCriterion" },
106+
"rows": { "$ref": "#/$defs/oneOrManyRows" },
107+
"or": { "$ref": "#/$defs/oneOrManySheetAlternatives" }
108+
}
109+
},
110+
"pageCriterion": {
111+
"type": "object",
112+
"additionalProperties": false,
113+
"properties": {
114+
"orientation": {
115+
"type": "string",
116+
"description": "Page orientation. Case-insensitive in the CLI.",
117+
"examples": ["landscape", "portrait"]
118+
},
119+
"paper": {
120+
"type": "string",
121+
"description": "Paper name. Case-insensitive in the CLI; hyphens are treated as underscores.",
122+
"examples": ["A4", "letter", "legal", "standard-11-17"]
123+
}
124+
}
125+
},
126+
"rowCriterion": {
127+
"type": "object",
128+
"additionalProperties": false,
129+
"properties": {
130+
"from": { "type": "integer", "minimum": 1 },
131+
"to": { "type": "integer", "minimum": 1 },
132+
"number": { "type": "integer", "minimum": 1 },
133+
"row": { "type": "integer", "minimum": 1 },
134+
"cells": { "$ref": "#/$defs/oneOrManyCells" },
135+
"or": { "$ref": "#/$defs/oneOrManyRowAlternatives" }
136+
}
137+
},
138+
"cellCriterion": {
139+
"type": "object",
140+
"additionalProperties": false,
141+
"properties": {
142+
"from": { "$ref": "#/$defs/cellAddress" },
143+
"to": { "$ref": "#/$defs/cellAddress" },
144+
"column": { "$ref": "#/$defs/cellAddress" },
145+
"value": {
146+
"description": "Exact cell value to match.",
147+
"type": ["string", "number", "integer", "boolean", "null"]
148+
},
149+
"string": { "type": "string" },
150+
"number": { "type": "number" },
151+
"bool": {
152+
"oneOf": [
153+
{ "type": "boolean" },
154+
{ "type": "string", "enum": ["true", "false"] }
155+
]
156+
},
157+
"localDate": { "type": "string", "format": "date" },
158+
"localDateTime": {
159+
"type": "string",
160+
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}(:[0-9]{2}(\\.[0-9]+)?)?$"
161+
},
162+
"localTime": {
163+
"type": "string",
164+
"pattern": "^[0-9]{2}:[0-9]{2}(:[0-9]{2}(\\.[0-9]+)?)?$"
165+
},
166+
"rowspan": { "type": "integer", "minimum": 1 },
167+
"colspan": { "type": "integer", "minimum": 1 },
168+
"name": { "type": "string" },
169+
"comment": { "type": "string" },
170+
"style": { "$ref": "#/$defs/styleCriterion" },
171+
"or": { "$ref": "#/$defs/oneOrManyCellAlternatives" }
172+
}
173+
},
174+
"styleCriterion": {
175+
"type": "object",
176+
"additionalProperties": false,
177+
"properties": {
178+
"background": { "type": "string" },
179+
"foreground": { "type": "string" },
180+
"fill": {
181+
"type": "string",
182+
"description": "Foreground fill. Case-insensitive in the CLI; hyphens are treated as underscores.",
183+
"examples": ["solid-foreground", "fine-dots", "no-fill"]
184+
},
185+
"indent": { "type": "integer", "minimum": 0 },
186+
"rotation": { "type": "integer" },
187+
"format": { "type": "string" }
188+
}
189+
}
190+
}
191+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright 2020-2026 Vladimir Orany.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
apply plugin: 'application'
19+
20+
dependencies {
21+
implementation project(':spreadsheet-builder-data')
22+
implementation project(':spreadsheet-builder-poi')
23+
implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
24+
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${jacksonVersion}"
25+
runtimeOnly 'org.apache.logging.log4j:log4j-core:2.24.3'
26+
27+
testImplementation project(':spreadsheet-builder-poi')
28+
}
29+
30+
application {
31+
mainClass = 'builders.dsl.spreadsheet.cli.SpreadsheetCli'
32+
}
33+
34+
jar {
35+
manifest.attributes 'Main-Class': application.mainClass.get()
36+
}

0 commit comments

Comments
 (0)