gridjs-spreadsheet 26.6.1 → 26.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{a08275ef8caf83cc1c2eae91f17663e8.svg → 1f345d060b26fa53bc9d78c36441afd6.svg} +106 -26
- package/angular.d.ts +67 -0
- package/angular.js +174 -0
- package/example/README.md +242 -41
- package/example/angular-gridjs/.nvmrc +1 -0
- package/example/angular-gridjs/angular.json +66 -0
- package/example/angular-gridjs/package.json +31 -0
- package/example/angular-gridjs/proxy.conf.json +12 -0
- package/example/angular-gridjs/src/app/api.ts +7 -0
- package/example/angular-gridjs/src/app/app.component.html +57 -0
- package/example/angular-gridjs/src/app/app.component.ts +153 -0
- package/example/angular-gridjs/src/app/routing.ts +52 -0
- package/example/angular-gridjs/src/favicon.ico +0 -0
- package/example/angular-gridjs/src/index.html +12 -0
- package/example/angular-gridjs/src/main.ts +7 -0
- package/example/angular-gridjs/src/styles.css +37 -0
- package/example/angular-gridjs/tsconfig.app.json +9 -0
- package/example/angular-gridjs/tsconfig.json +29 -0
- package/example/pom.xml +3 -3
- package/example/react-gridjs/index.html +12 -0
- package/example/react-gridjs/package.json +20 -0
- package/example/react-gridjs/src/App.jsx +188 -0
- package/example/react-gridjs/src/api.js +7 -0
- package/example/react-gridjs/src/main.jsx +9 -0
- package/example/react-gridjs/src/routing.js +51 -0
- package/example/react-gridjs/src/styles.css +37 -0
- package/example/react-gridjs/vite.config.js +16 -0
- package/example/src/main/java/com/aspose/gridjs/demo/controller/DataController.java +80 -2
- package/example/src/main/java/com/aspose/gridjs/demo/controller/GridJs2Controller.java +12 -0
- package/example/vanilla-gridjs/npm/index.html +29 -0
- package/example/vanilla-gridjs/npm/main.js +8 -0
- package/example/vanilla-gridjs/npm/package.json +16 -0
- package/example/vanilla-gridjs/npm/vite.config.js +11 -0
- package/example/vanilla-gridjs/script/index.html +32 -0
- package/example/vanilla-gridjs/script/main.js +9 -0
- package/example/vanilla-gridjs/script/package.json +12 -0
- package/example/vanilla-gridjs/script/vite.config.js +11 -0
- package/example/vanilla-gridjs/shared/demo-app.js +205 -0
- package/example/vanilla-gridjs/shared/styles.css +36 -0
- package/example/vue-gridjs/index.html +12 -0
- package/example/vue-gridjs/package.json +19 -0
- package/example/vue-gridjs/src/App.vue +199 -0
- package/example/vue-gridjs/src/api.js +7 -0
- package/example/vue-gridjs/src/main.js +9 -0
- package/example/vue-gridjs/src/routing.js +51 -0
- package/example/vue-gridjs/src/styles.css +37 -0
- package/example/vue-gridjs/vite.config.js +21 -0
- package/index.d.ts +528 -472
- package/index.js +1 -1
- package/package.json +143 -50
- package/react.d.ts +27 -0
- package/react.js +111 -0
- package/readme.md +183 -380
- package/shared.d.ts +66 -0
- package/shared.js +204 -0
- package/vue.d.ts +20 -0
- package/vue.js +125 -0
- package/xspreadsheet.css +365 -1
- package/xspreadsheet.js +5 -5
- package/example/.mvn/wrapper/maven-wrapper.properties +0 -18
- package/example/src/test/java/com/aspose/gridjs/demo/GridjsdemoApplicationTests.java +0 -1441
package/example/README.md
CHANGED
|
@@ -1,71 +1,272 @@
|
|
|
1
|
-
|
|
1
|
+
# Aspose.Cells GridJs Java framework examples
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This directory contains one Spring Boot backend shared by five independent frontend demos:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
| Demo | Directory | Development URL |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| React | `react-gridjs` | `http://127.0.0.1:5173` |
|
|
8
|
+
| Vue 3 | `vue-gridjs` | `http://127.0.0.1:5174` |
|
|
9
|
+
| Angular | `angular-gridjs` | `http://127.0.0.1:4200` |
|
|
10
|
+
| Vanilla HTML with npm | `vanilla-gridjs/npm` | `http://127.0.0.1:5175` |
|
|
11
|
+
| Vanilla HTML with CDN scripts | `vanilla-gridjs/script` | `http://127.0.0.1:5176` |
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
The frontend files are served by Vite or Angular CLI during development. They are not copied into the Java application. Each development server proxies GridJS API requests to the Java backend on port 8080.
|
|
9
14
|
|
|
10
|
-
##
|
|
15
|
+
## Requirements
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
- Java 8 or newer
|
|
18
|
+
- Node.js 18 or newer
|
|
19
|
+
- npm
|
|
20
|
+
- Angular demo: Node.js 18, 20, or 22
|
|
21
|
+
|
|
22
|
+
## Configure the Java backend
|
|
23
|
+
|
|
24
|
+
Edit `src/main/resources/application.properties` when the default local paths do not match your environment:
|
|
13
25
|
|
|
14
|
-
## How to Run the Examples
|
|
15
|
-
###1.edit the properties in src\main\resources\application.properties to meet your local environment
|
|
16
26
|
```properties
|
|
17
|
-
|
|
18
|
-
testconfig.
|
|
27
|
+
testconfig.ListDir=/path/to/workbooks
|
|
28
|
+
testconfig.CachePath=/path/to/grid_cache
|
|
29
|
+
testconfig.UploadPath=/path/to/upload
|
|
30
|
+
testconfig.AsposeLicensePath=/path/to/license
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The repository example already contains local `wb`, `grid_cache`, and `upload` directories for development.
|
|
34
|
+
|
|
35
|
+
## 1. Start the Java backend
|
|
36
|
+
|
|
37
|
+
Open the first terminal in this `example` directory.
|
|
38
|
+
|
|
39
|
+
macOS or Linux:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
./mvnw spring-boot:run -Dmaven.test.skip=true
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Windows:
|
|
46
|
+
|
|
47
|
+
```bat
|
|
48
|
+
mvnw.cmd spring-boot:run -Dmaven.test.skip=true
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Wait until Spring Boot is listening on:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
http://127.0.0.1:8080
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Backend health endpoint:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
http://127.0.0.1:8080/gridjsdemo/api/health
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The legacy server-rendered Java page remains available at:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
http://127.0.0.1:8080/gridjsdemo/list
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 2. Start a frontend
|
|
70
|
+
|
|
71
|
+
Open a second terminal. Install dependencies inside the selected frontend folder, then run its npm development command.
|
|
19
72
|
|
|
20
|
-
|
|
21
|
-
testconfig.CachePath=/app/grid_cache
|
|
73
|
+
### React
|
|
22
74
|
|
|
23
|
-
|
|
24
|
-
|
|
75
|
+
```bash
|
|
76
|
+
cd react-gridjs
|
|
77
|
+
npm install
|
|
78
|
+
npm run dev
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Open `http://127.0.0.1:5173`.
|
|
82
|
+
|
|
83
|
+
The application imports:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import { GridJsSpreadsheet } from 'gridjs-spreadsheet/react';
|
|
87
|
+
import 'gridjs-spreadsheet/xspreadsheet.css';
|
|
88
|
+
```
|
|
25
89
|
|
|
26
|
-
|
|
27
|
-
|
|
90
|
+
### Vue 3
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
cd vue-gridjs
|
|
94
|
+
npm install
|
|
95
|
+
npm run dev
|
|
28
96
|
```
|
|
29
|
-
###2.run src\main\java\com\aspose\gridjs\demo\GridjsdemoApplication.java
|
|
30
97
|
|
|
31
|
-
|
|
98
|
+
Open `http://127.0.0.1:5174`.
|
|
99
|
+
|
|
100
|
+
The application imports:
|
|
32
101
|
|
|
33
|
-
|
|
102
|
+
```js
|
|
103
|
+
import { GridJsSpreadsheet } from 'gridjs-spreadsheet/vue';
|
|
104
|
+
import 'gridjs-spreadsheet/xspreadsheet.css';
|
|
105
|
+
```
|
|
34
106
|
|
|
35
|
-
|
|
107
|
+
### Angular
|
|
36
108
|
|
|
37
|
-
|
|
109
|
+
Use Node.js 18, 20, or 22:
|
|
38
110
|
|
|
39
111
|
```bash
|
|
40
|
-
|
|
112
|
+
cd angular-gridjs
|
|
113
|
+
npm install
|
|
114
|
+
npm run dev
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Open `http://127.0.0.1:4200`.
|
|
118
|
+
|
|
119
|
+
The application imports:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { GridJsSpreadsheetComponent } from 'gridjs-spreadsheet/angular';
|
|
41
123
|
```
|
|
42
124
|
|
|
43
|
-
|
|
44
|
-
|
|
125
|
+
### Vanilla HTML with npm
|
|
126
|
+
|
|
45
127
|
```bash
|
|
46
|
-
|
|
128
|
+
cd vanilla-gridjs/npm
|
|
129
|
+
npm install
|
|
130
|
+
npm run dev
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Open `http://127.0.0.1:5175`.
|
|
134
|
+
|
|
135
|
+
The application imports the GridJS runtime and stylesheet from npm:
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
import Spreadsheet from 'gridjs-spreadsheet';
|
|
139
|
+
import JSZip from 'jszip';
|
|
140
|
+
import 'gridjs-spreadsheet/xspreadsheet.css';
|
|
141
|
+
|
|
142
|
+
window.JSZip = JSZip;
|
|
47
143
|
```
|
|
48
|
-
|
|
49
|
-
3. open browser and enter the url: http://localhost:8080/gridjsdemo/list
|
|
50
144
|
|
|
51
|
-
|
|
52
|
-
|
|
145
|
+
### Vanilla HTML with CDN script tags
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd vanilla-gridjs/script
|
|
149
|
+
npm install
|
|
150
|
+
npm run dev
|
|
151
|
+
```
|
|
53
152
|
|
|
54
|
-
|
|
153
|
+
Open `http://127.0.0.1:5176`.
|
|
55
154
|
|
|
56
|
-
|
|
155
|
+
This project loads GridJS and JSZip directly from CDN script tags. npm installs only the Vite development server.
|
|
57
156
|
|
|
58
|
-
|
|
157
|
+
## Why the frontend can access Java
|
|
59
158
|
|
|
60
|
-
|
|
159
|
+
The frontend applications call relative URLs such as:
|
|
61
160
|
|
|
62
|
-
|
|
161
|
+
```text
|
|
162
|
+
/gridjsdemo/api/files
|
|
163
|
+
/gridjsdemo/api/upload
|
|
164
|
+
/GridJs2/DetailStreamJsonWithUid
|
|
165
|
+
/GridJs2/UpdateCell
|
|
166
|
+
/GridJs2/Download
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Vite and Angular CLI proxy the `/gridjsdemo` and `/GridJs2` prefixes to `http://127.0.0.1:8080`:
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
Browser :5173/:5174/:4200/:5175/:5176
|
|
173
|
+
-> frontend development proxy
|
|
174
|
+
-> Java Spring Boot :8080
|
|
175
|
+
-> Aspose.Cells GridJs service
|
|
176
|
+
-> JSON response
|
|
177
|
+
-> frontend GridJS component
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The browser sees a same-origin request to its frontend server, so separate CORS configuration is not required for local development.
|
|
181
|
+
|
|
182
|
+
## Open a workbook directly
|
|
183
|
+
|
|
184
|
+
After the backend and frontend are running, a workbook can be opened through query parameters:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
http://127.0.0.1:5174/?file=chart.xlsx&demo=permanent&uid=vue-uid-chart-xlsx
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Supported demo modes:
|
|
191
|
+
|
|
192
|
+
- `permanent`: uses a UID-backed GridJS cache.
|
|
193
|
+
- `highlight`: loads the workbook without the persistent UID route.
|
|
194
|
+
|
|
195
|
+
## Upload file names
|
|
196
|
+
|
|
197
|
+
Uploaded files use two names:
|
|
198
|
+
|
|
199
|
+
- `file`: the original name shown in GridJS and used for downloads.
|
|
200
|
+
- `storedFile`: the unique internal filename used by the Java upload directory.
|
|
201
|
+
|
|
202
|
+
The URL retains both values so a refreshed page can reopen the internal file while continuing to display the original filename.
|
|
203
|
+
|
|
204
|
+
## Run multiple demos together
|
|
205
|
+
|
|
206
|
+
Start Java once, then run `npm run dev` in multiple frontend directories. Their ports are different, and their GridJS UIDs use different framework prefixes, so the demos do not conflict.
|
|
207
|
+
|
|
208
|
+
Stopping one frontend does not stop Java or the other frontend demos. Press `Ctrl+C` in each terminal to stop the corresponding process.
|
|
209
|
+
|
|
210
|
+
## Production builds
|
|
211
|
+
|
|
212
|
+
Each frontend can be built independently:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npm run build
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The output is written to that project's `dist` directory. This example intentionally demonstrates separate frontend development servers; it does not copy the frontend output into Spring Boot.
|
|
219
|
+
|
|
220
|
+
## npm package version
|
|
221
|
+
|
|
222
|
+
Each npm-based frontend declares:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
"gridjs-spreadsheet": "latest"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Running `npm install` resolves the npm registry's current latest release. The framework exports used by these demos require `gridjs-spreadsheet` 26.7.0 or newer.
|
|
229
|
+
|
|
230
|
+
Package lock files are intentionally not published with the example. Users may generate their own lock files when installing dependencies.
|
|
231
|
+
|
|
232
|
+
## Troubleshooting
|
|
233
|
+
|
|
234
|
+
### Frontend reports `ECONNREFUSED` or proxy errors
|
|
235
|
+
|
|
236
|
+
Confirm that Java is running on port 8080 and open the health URL:
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
http://127.0.0.1:8080/gridjsdemo/api/health
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### A frontend port is already occupied
|
|
243
|
+
|
|
244
|
+
Stop the existing process using that port. All frontend commands use strict ports to avoid silently opening a different URL.
|
|
245
|
+
|
|
246
|
+
### Angular rejects the current Node.js version
|
|
247
|
+
|
|
248
|
+
Use Node.js 18, 20, or 22. Node.js 23 and newer are outside the supported range of the included Angular 18 project.
|
|
249
|
+
|
|
250
|
+
### Framework import path cannot be resolved
|
|
251
|
+
|
|
252
|
+
Run `npm install` again and verify that the installed `gridjs-spreadsheet` version is 26.7.0 or newer.
|
|
253
|
+
|
|
254
|
+
### Trial warning appears in the workbook
|
|
255
|
+
|
|
256
|
+
Configure `testconfig.AsposeLicensePath` with a valid Aspose.Cells license, or continue using the example in evaluation mode.
|
|
257
|
+
|
|
258
|
+
## Docker
|
|
259
|
+
|
|
260
|
+
The Docker configuration runs the Java backend and legacy server-rendered page. The five framework demos remain separate npm development projects.
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
docker build -t gridjs-demo-java .
|
|
264
|
+
docker run -d -p 8080:8080 gridjs-demo-java
|
|
265
|
+
```
|
|
63
266
|
|
|
64
267
|
## Resources
|
|
65
268
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
+ **Forum:** [Aspose.Cells for Java Forum](http://www.aspose.com/community/forums/aspose.cells-product-family/19/showforum.aspx)
|
|
71
|
-
+ **Blog:** [Aspose.Cells for Java Blog](https://blog.aspose.com/category/aspose-products/aspose-cells-product-family/)
|
|
269
|
+
- [Aspose.Cells for Java](https://products.aspose.com/cells/java/)
|
|
270
|
+
- [Aspose.Cells GridJs documentation](https://docs.aspose.com/cells/java/aspose-cells-gridjs/)
|
|
271
|
+
- [GridJs Java API reference](https://reference.aspose.com/cells/java/com.aspose.gridjs/)
|
|
272
|
+
- [Aspose.Cells support forum](https://forum.aspose.com/c/cells)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
22
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"newProjectRoot": "projects",
|
|
5
|
+
"projects": {
|
|
6
|
+
"gridjs-angular-demo": {
|
|
7
|
+
"projectType": "application",
|
|
8
|
+
"schematics": {},
|
|
9
|
+
"root": "",
|
|
10
|
+
"sourceRoot": "src",
|
|
11
|
+
"prefix": "app",
|
|
12
|
+
"architect": {
|
|
13
|
+
"build": {
|
|
14
|
+
"builder": "@angular-devkit/build-angular:application",
|
|
15
|
+
"options": {
|
|
16
|
+
"outputPath": "dist/gridjs-angular-demo",
|
|
17
|
+
"index": "src/index.html",
|
|
18
|
+
"browser": "src/main.ts",
|
|
19
|
+
"polyfills": ["zone.js"],
|
|
20
|
+
"tsConfig": "tsconfig.app.json",
|
|
21
|
+
"assets": ["src/favicon.ico"],
|
|
22
|
+
"allowedCommonJsDependencies": ["gridjs-spreadsheet", "jszip"],
|
|
23
|
+
"styles": [
|
|
24
|
+
"node_modules/gridjs-spreadsheet/xspreadsheet.css",
|
|
25
|
+
"src/styles.css"
|
|
26
|
+
],
|
|
27
|
+
"scripts": []
|
|
28
|
+
},
|
|
29
|
+
"configurations": {
|
|
30
|
+
"production": {
|
|
31
|
+
"budgets": [
|
|
32
|
+
{
|
|
33
|
+
"type": "initial",
|
|
34
|
+
"maximumWarning": "5mb",
|
|
35
|
+
"maximumError": "8mb"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"outputHashing": "all"
|
|
39
|
+
},
|
|
40
|
+
"development": {
|
|
41
|
+
"optimization": false,
|
|
42
|
+
"extractLicenses": false,
|
|
43
|
+
"sourceMap": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"defaultConfiguration": "production"
|
|
47
|
+
},
|
|
48
|
+
"serve": {
|
|
49
|
+
"builder": "@angular-devkit/build-angular:dev-server",
|
|
50
|
+
"configurations": {
|
|
51
|
+
"production": {
|
|
52
|
+
"buildTarget": "gridjs-angular-demo:build:production"
|
|
53
|
+
},
|
|
54
|
+
"development": {
|
|
55
|
+
"buildTarget": "gridjs-angular-demo:build:development"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"defaultConfiguration": "development"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"cli": {
|
|
64
|
+
"analytics": false
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gridjs-angular-java-demo",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "cross-env NG_BUILD_MAX_WORKERS=1 ng serve --host 127.0.0.1 --port 4200 --proxy-config proxy.conf.json",
|
|
7
|
+
"build": "cross-env NG_BUILD_MAX_WORKERS=1 ng build"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@angular/animations": "18.2.14",
|
|
11
|
+
"@angular/common": "18.2.14",
|
|
12
|
+
"@angular/compiler": "18.2.14",
|
|
13
|
+
"@angular/core": "18.2.14",
|
|
14
|
+
"@angular/platform-browser": "18.2.14",
|
|
15
|
+
"gridjs-spreadsheet": "latest",
|
|
16
|
+
"jszip": "^3.10.1",
|
|
17
|
+
"rxjs": "~7.8.1",
|
|
18
|
+
"tslib": "^2.6.2",
|
|
19
|
+
"zone.js": "~0.14.10"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@angular-devkit/build-angular": "18.2.21",
|
|
23
|
+
"@angular/cli": "18.2.21",
|
|
24
|
+
"@angular/compiler-cli": "18.2.14",
|
|
25
|
+
"cross-env": "^7.0.3",
|
|
26
|
+
"typescript": "~5.5.4"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18 <23"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Small fetch() wrapper that turns non-2xx responses into thrown Errors,
|
|
2
|
+
// so callers can just `await fetchJson(url)` and catch failures in one place.
|
|
3
|
+
export async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
|
|
4
|
+
const response = await fetch(url, options);
|
|
5
|
+
if (!response.ok) throw new Error(response.status + ' ' + response.statusText);
|
|
6
|
+
return response.json() as Promise<T>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!-- A workbook is selected -> render the full-page spreadsheet editor. -->
|
|
2
|
+
<main *ngIf="current; else startPage" class="editor-page">
|
|
3
|
+
<gridjs-spreadsheet
|
|
4
|
+
*ngIf="workbookData; else loadingEditor"
|
|
5
|
+
[data]="workbookData"
|
|
6
|
+
height="100vh"
|
|
7
|
+
[showToolbar]="true"
|
|
8
|
+
[showContextmenu]="true"
|
|
9
|
+
(ready)="onReady($event)"
|
|
10
|
+
(change)="logEvent('changed')"
|
|
11
|
+
(error)="onError($event)"
|
|
12
|
+
(cellSelected)="logEvent('cell selected ' + (($event && $event[1]) ?? '') + ',' + (($event && $event[2]) ?? ''))"
|
|
13
|
+
(cellEdited)="logEvent('cell edited ' + (($event && $event[1]) ?? '') + ',' + (($event && $event[2]) ?? ''))"
|
|
14
|
+
(sheetSelected)="logEvent('sheet ' + (($event && $event[1]) ?? ''))"
|
|
15
|
+
></gridjs-spreadsheet>
|
|
16
|
+
<ng-template #loadingEditor>
|
|
17
|
+
<div class="editor-loading">{{ status }}</div>
|
|
18
|
+
</ng-template>
|
|
19
|
+
</main>
|
|
20
|
+
|
|
21
|
+
<!-- No workbook selected -> render the start page (demo picker + file list + upload). -->
|
|
22
|
+
<ng-template #startPage>
|
|
23
|
+
<div class="demo-shell">
|
|
24
|
+
<header class="demo-navbar">
|
|
25
|
+
<a href="https://docs.aspose.com/cells/java/aspose-cells-gridjs/">Aspose.Cells.GridJs demo for Java</a>
|
|
26
|
+
</header>
|
|
27
|
+
<main class="demo-container">
|
|
28
|
+
<fieldset class="demo-selector">
|
|
29
|
+
<legend>Select a demo:</legend>
|
|
30
|
+
<label [class]="demoType === DEMO_PERMANENT ? 'radio-card active' : 'radio-card'">
|
|
31
|
+
<input type="radio" name="demoType" [checked]="demoType === DEMO_PERMANENT" (change)="demoType = DEMO_PERMANENT" />
|
|
32
|
+
<span>permanent url load demo</span>
|
|
33
|
+
</label>
|
|
34
|
+
<label [class]="demoType === DEMO_HIGHLIGHT ? 'radio-card active' : 'radio-card'">
|
|
35
|
+
<input type="radio" name="demoType" [checked]="demoType === DEMO_HIGHLIGHT" (change)="demoType = DEMO_HIGHLIGHT" />
|
|
36
|
+
<span>highlight and custom context menu demo</span>
|
|
37
|
+
</label>
|
|
38
|
+
</fieldset>
|
|
39
|
+
<section class="upload-block">
|
|
40
|
+
<h4>Upload a local file to start show workbook</h4>
|
|
41
|
+
<input type="file" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" (change)="upload($event)" />
|
|
42
|
+
</section>
|
|
43
|
+
<section class="path-block">
|
|
44
|
+
<h4>The specific file path : {{ directory }}</h4>
|
|
45
|
+
<h4>Navigate one of the below file to start show workbook</h4>
|
|
46
|
+
</section>
|
|
47
|
+
<p class="status-message" role="status">{{ status }}</p>
|
|
48
|
+
<section class="file-list" aria-label="Workbook files">
|
|
49
|
+
<p *ngIf="status === 'Ready' && files.length === 0" class="empty-message">No workbooks found in the configured directory.</p>
|
|
50
|
+
<a *ngFor="let file of files" [href]="'/?file=' + file" class="file-item" (click)="$event.preventDefault(); openFile(file)">
|
|
51
|
+
<em>{{ file }}</em>
|
|
52
|
+
</a>
|
|
53
|
+
</section>
|
|
54
|
+
</main>
|
|
55
|
+
<footer class="demo-footer">© 2026 - <a href="https://products.aspose.com/cells/java">Aspose.Cells for Java</a></footer>
|
|
56
|
+
</div>
|
|
57
|
+
</ng-template>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, HostListener, OnInit } from '@angular/core';
|
|
3
|
+
import { GridJsSpreadsheetComponent } from 'gridjs-spreadsheet/angular';
|
|
4
|
+
import { DEMO_PERMANENT, DEMO_HIGHLIGHT, DemoType, WorkbookRef, makeUid, readRoute, pushWorkbookRoute } from './routing';
|
|
5
|
+
import { fetchJson } from './api';
|
|
6
|
+
|
|
7
|
+
// Root demo component.
|
|
8
|
+
// Renders either:
|
|
9
|
+
// - the start page (demo picker + sample file list + upload box), or
|
|
10
|
+
// - the full-page spreadsheet editor once a workbook has been selected.
|
|
11
|
+
// Which one is shown is driven entirely by the URL (see ./routing.ts).
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'app-root',
|
|
14
|
+
standalone: true,
|
|
15
|
+
imports: [CommonModule, GridJsSpreadsheetComponent],
|
|
16
|
+
templateUrl: './app.component.html',
|
|
17
|
+
})
|
|
18
|
+
export class AppComponent implements OnInit {
|
|
19
|
+
readonly DEMO_PERMANENT = DEMO_PERMANENT;
|
|
20
|
+
readonly DEMO_HIGHLIGHT = DEMO_HIGHLIGHT;
|
|
21
|
+
|
|
22
|
+
// Sample workbooks listed on the start page.
|
|
23
|
+
files: string[] = [];
|
|
24
|
+
directory = '';
|
|
25
|
+
// The workbook selected via the URL; null means "show the start page".
|
|
26
|
+
current: WorkbookRef | null = readRoute();
|
|
27
|
+
// Which demo mode is active (only relevant while on the start page).
|
|
28
|
+
demoType: DemoType = this.current?.demo || DEMO_PERMANENT;
|
|
29
|
+
workbookData: any = null;
|
|
30
|
+
status = 'Loading workbook list...';
|
|
31
|
+
adapter: any = null;
|
|
32
|
+
|
|
33
|
+
async ngOnInit(): Promise<void> {
|
|
34
|
+
await this.loadFiles();
|
|
35
|
+
if (this.current) await this.loadWorkbook();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Keeps state in sync when the user navigates with the browser's back/forward buttons.
|
|
39
|
+
@HostListener('window:popstate')
|
|
40
|
+
onPopState(): void {
|
|
41
|
+
this.current = readRoute();
|
|
42
|
+
if (this.current?.demo) {
|
|
43
|
+
this.demoType = this.current.demo;
|
|
44
|
+
}
|
|
45
|
+
void this.loadWorkbook();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
logEvent(message: string): void {
|
|
49
|
+
console.log('[GridJS Event]', message);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Loads the list of sample workbooks available on the server.
|
|
53
|
+
async loadFiles(): Promise<void> {
|
|
54
|
+
try {
|
|
55
|
+
const result = await fetchJson<{ directory: string; files: string[] }>('/gridjsdemo/api/files');
|
|
56
|
+
this.files = result.files || [];
|
|
57
|
+
this.directory = result.directory || '';
|
|
58
|
+
this.status = 'Ready';
|
|
59
|
+
} catch (error: any) {
|
|
60
|
+
this.status = 'Failed to load files: ' + error.message;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Navigates to a workbook: updates the URL and local state together.
|
|
65
|
+
openWorkbook(workbook: WorkbookRef): void {
|
|
66
|
+
const normalized = { ...workbook, demo: workbook.demo || this.demoType };
|
|
67
|
+
pushWorkbookRoute(normalized);
|
|
68
|
+
this.current = normalized;
|
|
69
|
+
this.demoType = normalized.demo;
|
|
70
|
+
void this.loadWorkbook();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
openFile(file: string): void {
|
|
74
|
+
this.openWorkbook({ file, storedFile: file, demo: this.demoType, uid: makeUid(file), fromUpload: '' });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Fetches workbook data for the GridJsSpreadsheet component. Which endpoint
|
|
78
|
+
// is used depends on the demo mode:
|
|
79
|
+
// - permanent: uid-based endpoint, backend caches parsed data per uid.
|
|
80
|
+
// - highlight: plain endpoint, re-parses the file on every load.
|
|
81
|
+
async loadWorkbook(): Promise<void> {
|
|
82
|
+
if (!this.current?.file) {
|
|
83
|
+
this.workbookData = null;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.workbookData = null;
|
|
87
|
+
this.adapter = null;
|
|
88
|
+
this.status = 'Loading ' + this.current.file + '...';
|
|
89
|
+
try {
|
|
90
|
+
const demo = this.current.demo || DEMO_PERMANENT;
|
|
91
|
+
const params = new URLSearchParams({
|
|
92
|
+
filename: this.current.storedFile || this.current.file,
|
|
93
|
+
fromUpload: this.current.fromUpload || '',
|
|
94
|
+
});
|
|
95
|
+
let endpoint = '/GridJs2/DetailStreamJson';
|
|
96
|
+
if (this.current.fromUpload) {
|
|
97
|
+
params.set('uid', this.current.uid || makeUid(this.current.file));
|
|
98
|
+
endpoint = '/GridJs2/DetailStreamJsonWithUidFromUpload';
|
|
99
|
+
} else if (demo === DEMO_PERMANENT) {
|
|
100
|
+
params.set('uid', this.current.uid || makeUid(this.current.file));
|
|
101
|
+
endpoint = '/GridJs2/DetailStreamJsonWithUid';
|
|
102
|
+
}
|
|
103
|
+
const payload = await fetchJson<any>(endpoint + '?' + params);
|
|
104
|
+
this.workbookData = { ...payload, filename: this.current.file };
|
|
105
|
+
this.status = 'Loaded ' + this.current.file;
|
|
106
|
+
} catch (error: any) {
|
|
107
|
+
this.status = 'Workbook load failed: ' + error.message;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async upload(event: Event): Promise<void> {
|
|
112
|
+
const input = event.target as HTMLInputElement;
|
|
113
|
+
const file = input.files?.[0];
|
|
114
|
+
if (!file) return;
|
|
115
|
+
const form = new FormData();
|
|
116
|
+
form.append('file', file);
|
|
117
|
+
form.append('client', 'angular');
|
|
118
|
+
this.status = 'Uploading ' + file.name + '...';
|
|
119
|
+
try {
|
|
120
|
+
const result = await fetchJson<{ file: string; displayName: string; uid: string; fromUpload: string }>('/gridjsdemo/api/upload', { method: 'POST', body: form });
|
|
121
|
+
this.logEvent('uploaded ' + result.file);
|
|
122
|
+
// Newly uploaded files live under the server's uploads dir, flagged with fromUpload=1.
|
|
123
|
+
this.openWorkbook({
|
|
124
|
+
file: result.displayName || file.name,
|
|
125
|
+
storedFile: result.file,
|
|
126
|
+
demo: this.demoType,
|
|
127
|
+
uid: result.uid || makeUid(result.file),
|
|
128
|
+
fromUpload: '1',
|
|
129
|
+
});
|
|
130
|
+
} catch (error: any) {
|
|
131
|
+
this.status = 'Upload failed: ' + error.message;
|
|
132
|
+
} finally {
|
|
133
|
+
input.value = '';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Restores the previously active sheet/cell (from the workbook data) once
|
|
138
|
+
// the grid has mounted, and points the "open file" link back at the start page.
|
|
139
|
+
onReady(event: { instance: any; adapter: any }): void {
|
|
140
|
+
this.adapter = event.adapter;
|
|
141
|
+
const sheetName = event.adapter.payload?.actname;
|
|
142
|
+
const row = event.adapter.payload?.actrow;
|
|
143
|
+
const col = event.adapter.payload?.actcol;
|
|
144
|
+
event.instance?.setActiveSheetByName?.(sheetName)?.setActiveCell?.(row, col);
|
|
145
|
+
event.instance?.setOpenFileUrl?.('/');
|
|
146
|
+
this.logEvent('ready ' + (event.adapter.payload?.filename || this.current?.file));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
onError(payload: any): void {
|
|
150
|
+
console.error(payload);
|
|
151
|
+
this.logEvent('error ' + (payload?.message || payload?.type || 'unknown'));
|
|
152
|
+
}
|
|
153
|
+
}
|