fluentreports
Advanced tools
Comparing version 1.3.0 to 1.3.1
@@ -43,2 +43,3 @@ 0.0.1 - [2013/08/15] - Initial Release | ||
1.3.0 - Upgraded to PDFKit 0.11.0 & Fixed several Gui issues | ||
1.3.1 - Add/Publish testing Infrastructure, remove some extra console.logs | ||
@@ -45,0 +46,0 @@ |
@@ -0,1 +1,11 @@ | ||
/************************************************************************************** | ||
* (c) 2019-2020, Master Technology | ||
* Licensed under the MIT license or contact me for a support, changes, enhancements. | ||
* | ||
* Any questions please feel free to put a issue up on github | ||
* | ||
* Nathan@master-technology.com | ||
*************************************************************************************/ | ||
"use strict"; | ||
// Import the Report system. | ||
@@ -492,3 +502,2 @@ const Report = require('./fluentReports' ).Report; | ||
case 'raw': | ||
console.log("Raw", setting); | ||
setting.raw = setting.values; | ||
@@ -495,0 +504,0 @@ this._handlePrint(setting, info, callback); |
@@ -28,3 +28,7 @@ { | ||
], | ||
"licenses": "MIT", | ||
"funding": { | ||
"type": "github", | ||
"url": "https://github.com/sponsors/NathanaelA/" | ||
}, | ||
"license": "MIT", | ||
"lib": "lib", | ||
@@ -42,5 +46,5 @@ "bugs": { | ||
"main": "lib/fluentReports", | ||
"version": "1.3.0", | ||
"version": "1.3.1", | ||
"engines": { | ||
"node": ">= 0.6.0" | ||
"node": "*" | ||
}, | ||
@@ -54,4 +58,8 @@ "devDependencies": { | ||
"uglifyify": "^5.0.2", | ||
"unassertify": "^2.1.1" | ||
"unassertify": "^2.1.1", | ||
"blink-diff": "latest" | ||
}, | ||
"scripts": { | ||
"test": "chmod +x ./examples/runtests.sh && ./examples/runtests.sh" | ||
} | ||
} |
236
README.md
# Fluent Reports | ||
![.github/workflows/renderer.yml](https://github.com/NathanaelA/fluentreports/workflows/fluentReports%20Renderer%20CI/badge.svg) | ||
See: [https://www.fluentreports.com](FluentReports.com) for more information. | ||
[![npm](https://img.shields.io/npm/v/fluentreports.svg)](https://www.npmjs.com/package/fluentReports) | ||
[![npm](https://img.shields.io/npm/l/fluentreports.svg)](https://www.npmjs.com/package/fluentReports) | ||
[![npm](https://img.shields.io/npm/dt/fluentreports.svg?label=npm%20d%2fls)](https://www.npmjs.com/package/fluentReports) | ||
[![GitHub last commit](https://img.shields.io/github/last-commit/nathanaela/fluentreports)](https://img.shields.io/github/last-commit/nathanaela/fluentreports) | ||
[![Dependencies](https://img.shields.io/librariesio/github/nathanaela/fluentreports)](https://www.github.com/nathanaela/fluentReports) | ||
--- | ||
#### Funding and sponsorship | ||
[![github](https://img.shields.io/badge/Github-Sponsorship-orange)](https://github.com/sponsors/nathanaela) | ||
You can now sponsor us on Github: [https://github.com/sponsors/NathanaelA](https://github.com/sponsors/nathanaela) | ||
--- | ||
#### Website and demos | ||
See: [https://www.fluentreports.com](https://FluentReports.com) for more information. | ||
Fluent Reports - Data Driven PDF Reporting Engine for **Node.js** and **Browsers** | ||
@@ -16,4 +33,8 @@ | ||
Please [read the commands.md file](commands.md) for a overview of all the commands. The files in the `docs/` folder are generated from the source code via jsdocs, so they **might** be more up to date. | ||
Please [read the commands.md file](commands.md) for an overview of all the commands. The files in the `docs/` folder are generated from the source code via jsdocs, so they **might** be more up to date. | ||
Please [read the examples readme file](examples) for a list of examples. | ||
Please [read the tutorial.md file](tutorials.md) for the tutorials. | ||
## Features: | ||
@@ -23,2 +44,3 @@ | ||
* **New: Report Generator** | ||
* Testing Harness to verify reports look the same after any updates | ||
* Completely Data Driven. You pass in the data; you tell it easily how to print the data, and it generates the PDF report. | ||
@@ -31,3 +53,3 @@ * Data agnostic, can be arrays, and/or objects; whatever you prefer. | ||
* Images, Gradients, Text, Fonts, Lines, and many other PDF features supported. | ||
* Data can come from anywhere and the report engine even support Pageable data loading and related(or sub-query) data loading. | ||
* Data can come from anywhere, and the report engine even support Pageable data loading and related(or sub-query) data loading. | ||
* Sub-Reports, Sub-Sub-Reports, etc... | ||
@@ -50,14 +72,16 @@ * Bands (Tables/Grids) & Suppressed Bands (w/ column wrapping or column clipping) | ||
## Examples | ||
Currently we ship 6 example reports showing: | ||
## Some Examples | ||
Currently, we ship multiple [examples](examples) | ||
* Simple Grid Report with Grouping ![Example 1](https://github.com/nathanaela/fluentReports/raw/master/examples/demo1.png) | ||
* Simple Account Summary Report (w/ color & grid for account balances) ![Example 2](https://github.com/nathanaela/fluentReports/raw/master/examples/demo2.png) | ||
* Simple Fax Cover Sheet (w/ image) ![Example 3](https://github.com/nathanaela/fluentReports/raw/master/examples/demo3.png) | ||
* Grid Report showing off Sub-Reports with auto-queries, cell colorization and url links. ![Example 4](https://github.com/nathanaela/fluentReports/raw/master/examples/demo4.png) | ||
* More complex invoice/proposal with grouping, headers, footers. ![Example 5](https://github.com/nathanaela/fluentReports/raw/master/examples/demo5.png) | ||
* The Grocery Report Example done in stages to see from simple to complex reporting. ![Example 6](https://github.com/nathanaela/fluentReports/raw/master/examples/GroceryList3.png) | ||
* Simple Grid Report with Grouping ![Example 1](https://github.com/nathanaela/fluentReports/raw/master/examples/Originals/demo01-1.png) | ||
* Simple Account Summary Report (w/ color & grid for account balances) ![Example 2](https://github.com/nathanaela/fluentReports/raw/master/examples/Originals/demo02-1.png) | ||
* Simple Fax Cover Sheet (w/ image) ![Example 3](https://github.com/nathanaela/fluentReports/raw/master/examples/Originals/demo03-1.png) | ||
* Grid Report showing off Sub-Reports with auto-queries, cell colorization and url links. ![Example 4](https://github.com/nathanaela/fluentReports/raw/master/examples/Originals/demo04-1.png) | ||
* More complex invoice/proposal with grouping, headers, footers. ![Example 5](https://github.com/nathanaela/fluentReports/raw/master/examples/Originals/demo05-1.png) | ||
* The Grocery Report Example done in stages to see from simple to complex reporting. ![Example 6](https://github.com/nathanaela/fluentReports/raw/master/examples/Originals/demo06-1.png) | ||
* For many other examples; [click here](examples) | ||
Please note these following reports are using the simplest report methods; to show how quickly you can create a simple report. | ||
You have the ability to EASILY FULLY override any and all of the Headers, Footers, and Detail bands. | ||
## Simple Sample Report | ||
This following report is using the a few of the simplest report methods. We can show you how quickly you can create a simple report. | ||
You have the ability to EASILY FULLY override any and all of the Headers, Footers, and Detail bands (and much more). | ||
@@ -78,16 +102,4 @@ Really Simple Report: | ||
The same report in Array format: | ||
One other sample report using a list type output: | ||
```js | ||
// Our Simple Data in Array format: | ||
const data = [['Elijah', 18], ['Abraham', 22], ['Gavin', 28]]; | ||
// Create a Report | ||
const rpt = new Report("Report.pdf") | ||
.pageHeader( ["Employee Ages"] ) // Add a simple (optional) page Header... | ||
.detail( [[0, 200],[1, 50]]) // Layout the report in a grid of 200px & 50px | ||
.render(); // Render the report | ||
``` | ||
And one other sample report using a list type output: | ||
```js | ||
const data = [ | ||
@@ -111,174 +123,6 @@ {item: 'Bread', count: 5, unit: 'loaf'}, | ||
## Tutorial | ||
Data Driven reporting is done in basically a couple steps: | ||
1. Get your initial data. | ||
So in the above example we are setting the data to grocery items; this data can come from databases, data stores, files, web services, anywhere ever you store your data. | ||
2. Then you are defining the report/page overall structure. So do you want headers or footers on all pages; are you grouping, totalling, or just printing raw data. | ||
So in the above example; we are setting a fixed page header that prints on every page that uses the reporting engine defaults and puts "My Grocery List" in the center of the top. | ||
3. Then we choose how we want to display each detail record; again you can decide to use the simpler built in system like I did in the three above reports or you can use a function that will allow you to control it entirely. | ||
So, now looking at the above simple grocery list report; and lets spruce it up a bit. | ||
First lets change from the default header to make a look a bit nicer for a Grocery List; so we need to create a function that will control how the header looks. | ||
```js | ||
const headerFunction = function(Report) { | ||
Report.print("My Grocery List", {fontSize: 22, bold: true, underline:true, align: "center"}); | ||
Report.newLine(2); | ||
}; | ||
``` | ||
This function changes the font size to 22 point, bolds and underlines the text and centers the words "My Grocery List" on the page. Then we add 2 new blank lines to space the header from the detail records. This looks so much cleaner. | ||
Next, I think I actually do want to continue to have the date and page number printed. But I think I would prefer them on the bottom of the page, so lets add a footer for these items. Here is our footer function that also will be printed on every page, just like the header function above. | ||
```js | ||
const footerFunction = function(Report) { | ||
Report.line(Report.currentX(), Report.maxY()-18, Report.maxX(), Report.maxY()-18); | ||
Report.pageNumber({text: "Page {0} of {1}", footer: true, align: "right"}); | ||
Report.print("Printed: "+(new Date().toLocaleDateString()), {y: Report.maxY()-14, align: "left"}); | ||
}; | ||
``` | ||
Now in this function we print a line across the bottom of the page; then we use the "pageNumber" helper function to print the current page number and total number of page, then we print the current date. | ||
A couple things to point out; Report.maxY and maxX are the largest location that can be printed to before entering the margins. If you attempt to create your footer beyond the maxY coordinate; it WILL let you; but it WILL send a error to the Report.error system stating that you exceeded the margin by however many pixels so that you can fix your report. | ||
So our new report is: | ||
```js | ||
const data = [ | ||
{item: 'Bread', count: 5, unit: 'loaf'}, | ||
{item: 'Egg', count: 3, unit: 'dozen'}, | ||
{item: 'Sugar', count: 32, unit: 'gram'}, | ||
{item: 'Carrot', count: 2, unit: 'kilo'}, | ||
{item: 'Apple', count: 3, unit: 'kilo'}, | ||
{item: 'Peanut Butter', count: 1, unit: 'jar'} | ||
]; | ||
const headerFunction = function(Report) { | ||
Report.print("My Grocery List", {fontSize: 22, bold: true, underline:true, align: "center"}); | ||
Report.newLine(2); | ||
}; | ||
const footerFunction = function(Report) { | ||
Report.line(Report.currentX(), Report.maxY()-18, Report.maxX(), Report.maxY()-18); | ||
Report.pageNumber({text: "Page {0} of {1}", footer: true, align: "right"}); | ||
Report.print("Printed: "+(new Date().toLocaleDateString()), {y: Report.maxY()-14, align: "left"}); | ||
}; | ||
const rpt = new Report("grocery2.pdf") | ||
.margins(20) // Change the Margins to 20 pixels | ||
.data(data) // Add our Data | ||
.pageHeader(headerFunction) // Add a header | ||
.pageFooter(footerFunction) // Add a footer | ||
.detail("{{count}} {{unit}} of {{item}}") // Put how we want to print out the data line. | ||
.render(); // Render it out | ||
``` | ||
Wow, this report looks a **lot** cleaner and sharper. However, I think we can spruce it up a still bit more... | ||
```js | ||
const detailFunction = function(Report, Data) { | ||
if (Data.count !== 1) { | ||
Data.item = pluralize(Data.item); | ||
Data.unit = pluralize(Data.unit); | ||
} | ||
Report.box(Report.currentX()-1, Report.currentY()-1, 10, 10, {}); | ||
Report.print(numberToText(Data.count) + ' ' + Data.unit + ' of ' + Data.item, {addX: 12}); | ||
}; | ||
``` | ||
This is our new Detail function. I first uses a simple pluralizer to make any singular words plural if they need be. The next thing it does is draw a box for your check marks. Then it spits out your detail line with changes. | ||
Now since I can have a really large grocery list; I can make this two or three columns, so we lets modify the code to make it three columns like so: | ||
```js | ||
const detailFunction = function(Report, Data) { | ||
if (Data.count !== 1) { | ||
Data.item = pluralize(Data.item); | ||
Data.unit = pluralize(Data.unit); | ||
} | ||
let x = 0, y = 0; | ||
if (columnCounter % 3 === 1) { | ||
x += 200; | ||
y = (Report.heightOfString() + 1); | ||
} else if (columnCounter % 3 === 2) { | ||
x += 400; | ||
y = (Report.heightOfString() + 1); | ||
} | ||
Report.box(Report.currentX()+x , Report.currentY()-y, 10, 10, {}); | ||
Report.print(numberToText(Data.count) + ' ' + Data.unit + ' of ' + Data.item, {addX: x+12, addY: -(y-1)}); | ||
columnCounter++; | ||
}; | ||
``` | ||
Basically it is the same functions as the prior version but we are changing the X and Y coordinates for column 2 & 3 to make them end up on the same line just in a different column. So the finished report looks this. | ||
example\demo6.js contains this report in its three different iterations. | ||
--- | ||
# GUI & Browser | ||
To build the browser version of the engine, you need to run `npm i` on the repository to install all the developer dependencies. You might also want to install browserfy globally using `npm i -g browserfy` | ||
``` | ||
cd lib | ||
browserify fluentReportsBuilder.js -s fluentReports --ignore iconv-lite -o ../generator/fluentReportsBrowser.js | ||
``` | ||
Then I minify it with this command: | ||
``` | ||
cd ../generator | ||
terser --compress --mangle -- fluentReportsBrowser.js > fluentReportsBrowser.min.js | ||
``` | ||
This gives me both an easy to debug version, and a standalone version. This will give you a full version of the Data Driven engine that runs in a browser and can run both types of reports. | ||
If you want to use the GUI editor in your app, you just need to include: | ||
``` | ||
<link rel="stylesheet" href="fr.css"> | ||
<script src="fluentReportsBrowser.min.js"></script> | ||
<script src="plain-draggable.min.js"></script> | ||
<script src="fluentReportsGenerator.js"></script> | ||
``` | ||
### GUI & Browser Implementations | ||
You can also combine all of this together, and then minimize it also. | ||
<b>Please note you DO NOT need to include the `fluentReportBrowser.min.js` file if you do NOT want to do previews from the browser!!!</b> <br> | ||
You can also override the GUI "preview" button to disable it or send the generated report to the server to serve it up for you. | ||
HTML | ||
``` | ||
<div id="fluentReportsEditor"></div> | ||
``` | ||
To create a new Report on the Browser (see the `reportgenerator.html` for detailed example); | ||
``` | ||
const frg = new window.FluentReportsGenerator({ | ||
id: "fluentReportsEditor", | ||
data: {your data}, | ||
report: {your report}, | ||
debug: true, | ||
js: false, | ||
css: false, | ||
scale: 1.45, | ||
// Don't set a "preview" (or set to undefinded) for it to use the built in preview | ||
preview: undefined, | ||
// Override the preview function | ||
preview: (generator, done) => { | ||
// Do Whatever you need, probably with: | ||
// generator.report and generator.data | ||
done(); | ||
}, | ||
// OR to disable preview functionality... | ||
preview: false | ||
save: (value, done) => { | ||
console.log("Saving"); | ||
console.dir(value); | ||
done(); | ||
} | ||
}); | ||
``` | ||
See the [generator](generator) documentation |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
357108
11
7251
8
123