Skip to content

Commit 46fc602

Browse files
committed
added some more reports
1 parent 5309ad0 commit 46fc602

35 files changed

+2837
-42
lines changed

README.md

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,94 @@
44
git clone https://github.com/moofoo/nestjs-jsreport-examples && cd nestjs-jsreport-examples && yarn && yarn start:dev
55
```
66

7-
This repo demonstrates (very basic) NestJS + JSReport integration. The app has six endpoints which generate different reports, taken from the [JSReport Playground](https://playground.jsreport.net/). The goal here is not to present a robust JSReports module, but demonstrate the basics of initializing JsReports and generating reports from templates and data, in addition to covering some of the 'gotchas' and configuration quirks involved.
7+
This repo demonstrates NestJS + JSReport integration. I've replicated all of the JSReport "[showcase](https://jsreport.net/showcases/)" reports minus the "PDF Stock Report", due to it's complexity. Like seriously, they went to town with that one. I also did a few of the simpler example reports from the [JSReport Playground](https://playground.jsreport.net/), just because.
88

9-
The following 'Recipes' are used:
9+
The goal here is not to present a complete and self-contained JSReports module that others can import and use, though that might happen eventually. Rather, I wanted to
1010

11-
- [DocX](https://jsreport.net/learn/docx)
12-
- [Chrome PDF](https://jsreport.net/learn/chrome-pdf) (html-to-pdf using headless chromium)
13-
- [Xlsx](https://jsreport.net/learn/xlsx)
14-
- [Html-to-Xlsx](https://jsreport.net/learn/html-to-xlsx)
11+
- Show that the integration is possible and its potential,
12+
- Work through the expected 'gotchas', quirks and pain points that come with the territory, so that future templating/report work that I'm actually getting paid for will be hella easy,
13+
- I also want to show off how powerful and fully-featured the core JSReport framework is, to anyone paying attenntion. JSReport is literally the only business reports company that has their entire code base, top to bottom, open source and free for anyone to use, and it's fucking **legit**
1514

16-
## Report Endpoints
15+
Software like this deserves attention and love, especially given how ridiculously costly and frankly predatory so many SaaS services in the space are.
16+
17+
#
18+
19+
## Implemented Reports and Endpoints
20+
21+
<hr>
22+
23+
#
24+
25+
### [http://localhost:3333/reports/pdf-dashboard](http://localhost:3333/reports/pdf-dashboard)
26+
27+
- ![PDF Dashboard](images/tasks-report.png)
28+
29+
- Chrome PDF
30+
- [Playground Link](https://playground.jsreport.net/w/admin/cBFKE3RY)
31+
32+
#
33+
34+
### [http://localhost:3333/reports/excel-dashboard](http://localhost:3333/reports/excel-dashboard)
35+
36+
- ![Excel Dashboard](images/excel-dashboard.png)
37+
38+
- Chrome PDF
39+
- [Playground Link](https://playground.jsreport.net/w/admin/VvaGnaE)
40+
41+
#
1742

1843
### [http://localhost:3333/reports/student](http://localhost:3333/reports/student)
1944

45+
- ![Students](images/docx-students.png)
46+
2047
- DocX
2148
- [Playground Link](https://playground.jsreport.net/w/admin/d7o0nIWc)
2249

50+
#
51+
52+
### [http://localhost:3333/reports/ticket](http://localhost:3333/reports/ticket)
53+
54+
- ![Ticket](images/e-ticket.png)
55+
56+
- Chrome PDF
57+
- [Playground Link](https://playground.jsreport.net/w/admin/ms2EkdfI)
58+
59+
#
60+
61+
### [http://localhost:3333/reports/pdf-forms](http://localhost:3333/reports/pdf-forms)
62+
63+
- ![Ticket](images/pdf-form.png)
64+
- Chrome PDF
65+
- [Playground Link](https://playground.jsreport.net/w/admin/lbhULCsP)
66+
67+
#
68+
2369
### [http://localhost:3333/reports/invoice](http://localhost:3333/reports/invoice)
2470

2571
- DocX
2672
- [Playground Link](https://playground.jsreport.net/w/admin/yo9J3hvu)
2773

74+
#
75+
2876
### [http://localhost:3333/reports/invoice-xlsx](http://localhost:3333/reports/invoice-xlsx)
2977

3078
- Xlsx
3179
- [Playground Link](https://playground.jsreport.net/w/admin/Lh8Kjc~f)
3280

81+
#
82+
3383
### [http://localhost:3333/reports/population](http://localhost:3333/reports/population)
3484

3585
- Xlsx
3686
- [Playground Link](https://playground.jsreport.net/w/admin/V71OgRWt)
3787

88+
#
89+
3890
### [http://localhost:3333/reports/html-to-xlsx](http://localhost:3333/reports/html-to-xlsx)
3991

4092
- Html-to-Xlsx
4193
- [Playground Link](https://playground.jsreport.net/w/admin/h45L49Dp)
4294

43-
### [http://localhost:3333/reports/ticket](http://localhost:3333/reports/ticket)
44-
45-
- Chrome PDF
46-
- [Playground Link](https://playground.jsreport.net/w/admin/ms2EkdfI)
47-
48-
All endpoints except for `flight-ticket` endpoint will generate a PDF (instead of .docx or .xlsx) with the query `pdf=1` (i.e, http://localhost:3333/reports/invoice?pdf=1)
49-
50-
## Why do this?
51-
52-
Well, in terms of pure document generation chops (not talking about templating backends, GUIs or workflows), JSReport is more-or-less on par with what is possible using SaaS services like [Bold Reports](https://www.boldreports.com/), [DocxTemplater](https://docxtemplater.com/), [CarboneIO](https://carbone.io), [DocuPilot](https://docupilot.app/), [Formstack](https://www.formstack.com/), etc...
53-
54-
However, unlike those services, JSReports does not gatekeep **ANY** functionality behind payment tiers. Rather, their business model is oriented around usage of their 'Studio' template builder GUI, which has SaaS and self-hosted versions, while the JSReport server code itself is completely open source and accessible.
55-
56-
So, by making use of the [jsreport core package](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-core) you can have self-hosted document generation that's on-par with any SaaS out there.
95+
#
5796

58-
The [JSReport Studio GUI](https://playground.jsreport.net/w/admin/S3xqZ0Zc) is actually quite good, if that's something you're looking for.
97+
Most of these will generate a PDF (instead .docx or .xlsx) with the query `pdf=1` (i.e, http://localhost:3333/reports/invoice?pdf=1)

images/docx-students.png

37.5 KB
Loading

images/e-ticket.png

33.8 KB
Loading

images/excel-dashboard.png

117 KB
Loading

images/pdf-form.png

224 KB
Loading

images/tasks-report.png

50.1 KB
Loading

nest-cli.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,14 @@
22
"$schema": "https://json.schemastore.org/nest-cli",
33
"collection": "@nestjs/schematics",
44
"sourceRoot": "src",
5-
"compilerOptions": {"assets": ["**/template.*", "**/*.png", "**/*.css", "**/*.config.json"]}
5+
"compilerOptions": {
6+
"assets": [
7+
"**/*.html,",
8+
"**/template.*",
9+
"**/*.png",
10+
"**/*.css",
11+
"**/*.config.json",
12+
"**/*.xlsx"
13+
]
14+
}
615
}

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
"@jsreport/jsreport-fs-store": "^3.2.4",
2828
"@jsreport/jsreport-handlebars": "^3.2.1",
2929
"@jsreport/jsreport-html-to-xlsx": "^3.3.1",
30+
"@jsreport/jsreport-pdf-utils": "^3.9.0",
31+
"@jsreport/jsreport-scripts": "^3.4.1",
3032
"@jsreport/jsreport-unoconv": "^3.0.1",
3133
"@jsreport/jsreport-xlsx": "^3.4.0",
3234
"@nestjs/common": "^9.4.2",
@@ -54,6 +56,7 @@
5456
"@types/jsreport-core": "^2.0.5",
5557
"@types/jsreport-docx": "^2.8.2",
5658
"@types/jsreport-html-to-xlsx": "^2.0.3",
59+
"@types/jsreport-scripts": "^2.6.2",
5760
"@types/jsreport-xlsx": "^1.4.2",
5861
"@types/node": "20.2.3",
5962
"@types/supertest": "^2.0.12",

src/js-report/helpers/asset.helper.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,40 @@ import fs from 'fs';
33

44
export class AssetHelper {
55
private readonly jsReport: JsReporter;
6+
collectionName = 'assets';
67

7-
constructor(jsReport: JsReporter) {
8+
constructor(jsReport: JsReporter, collectionName = 'assets') {
9+
this.collectionName = collectionName;
810
this.jsReport = jsReport;
911
}
1012

1113
async stored(name: string) {
1214
const result = await this.jsReport.documentStore
13-
.collection('assets')
15+
.collection(this.collectionName)
1416
.find({ name });
1517

1618
return result.length > 0;
1719
}
1820

21+
async shortId(name) {
22+
const isStored = await this.stored(name);
23+
24+
if (!isStored) {
25+
return 'shortId';
26+
}
27+
28+
const found: any = await this.find(name);
29+
console.log('FOUND', found);
30+
31+
return found.shortid;
32+
}
33+
1934
async insert(asset: {
2035
name: string;
2136
path?: string;
2237
content?: any;
2338
encoding?: string;
39+
scope?: string;
2440
}) {
2541
const isStored = await this.stored(asset.name);
2642

@@ -30,7 +46,9 @@ export class AssetHelper {
3046
}
3147
}
3248

33-
await this.jsReport.documentStore.collection('assets').insert(asset);
49+
await this.jsReport.documentStore
50+
.collection(this.collectionName)
51+
.insert(asset);
3452
}
3553

3654
async insertAll(
@@ -39,6 +57,7 @@ export class AssetHelper {
3957
path?: string;
4058
content?: any;
4159
encoding?: string;
60+
scope?: string;
4261
}>,
4362
) {
4463
for (const asset of assets) {
@@ -51,6 +70,7 @@ export class AssetHelper {
5170
path?: string;
5271
content?: any;
5372
encoding?: string;
73+
scope?: string;
5474
}) {
5575
const isStored = await this.stored(asset.name);
5676

@@ -61,20 +81,26 @@ export class AssetHelper {
6181
asset.content = fs.readFileSync(asset.path, asset.encoding as any);
6282
}
6383

64-
await this.jsReport.documentStore
65-
.collection('assets')
66-
.update(
67-
{ name: asset.name },
68-
{ $set: { content: asset.content, encoding: asset.encoding } },
69-
);
84+
await this.jsReport.documentStore.collection(this.collectionName).update(
85+
{ name: asset.name },
86+
{
87+
$set: {
88+
content: asset.content,
89+
encoding: asset.encoding,
90+
scope: asset.scope,
91+
},
92+
},
93+
);
7094
}
7195
}
7296

7397
async remove(name: string) {
7498
const isStored = await this.stored(name);
7599

76100
if (isStored) {
77-
await this.jsReport.documentStore.collection('assets').remove({ name });
101+
await this.jsReport.documentStore
102+
.collection(this.collectionName)
103+
.remove({ name });
78104
}
79105
}
80106

@@ -83,14 +109,15 @@ export class AssetHelper {
83109

84110
if (isStored) {
85111
const found = await this.jsReport.documentStore
86-
.collection('assets')
112+
.collection(this.collectionName)
87113
.find({ name });
88114

89115
return found[found.length - 1] as {
90116
name: string;
91117
path?: string;
92118
content?: any;
93119
encoding?: string;
120+
scope?: string;
94121
};
95122
}
96123
}

src/js-report/helpers/template.helper.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ export class TemplateHelper {
1717
return result.length > 0;
1818
}
1919

20-
async insertFn<T = unknown>(name: string, templateFn: () => Named & T) {
20+
async insertFn<T = unknown>(
21+
name: string,
22+
templateFn: () => (Named & T) | Promise<Named & T>,
23+
) {
2124
const isStored = await this.stored(name);
2225
if (!isStored) {
23-
await this.insert(templateFn());
26+
await this.insert(await templateFn());
2427
}
2528
}
2629

0 commit comments

Comments
 (0)