// Node Schedule module
var schedule = require("node-schedule");
console.log("Node Schedule loaded");
// Stimulsoft Reports module
var Stimulsoft = require("stimulsoft-reports-js");
console.log("Stimulsoft Reports loaded");
// Creating new report
var report = new Stimulsoft.Report.StiReport();
console.log("New report created");
// Loading report template
report.loadFile("SimpleList.mrt");
console.log("Report template loaded");
// Run the task every day at 10:00
var rule = new schedule.RecurrenceRule();
rule.hour = 10;
rule.minute = 0;
console.log("Rule for the task created");
// Scheduling the task
schedule.scheduleJob(rule, function () {
// Renreding report
report.renderAsync(() => {
console.log("Report rendered. Pages count: ", report.renderedPages.count);
// Export to PDF
report.exportDocumentAsync((pdfData) => {
// Converting Array into buffer
var buffer = Buffer.from(pdfData);
// File System module
var fs = require("fs");
// Saving string with rendered report in PDF into a file
fs.writeFileSync("./SimpleList.pdf", buffer);
console.log("Rendered report saved into PDF-file.");
}, Stimulsoft.Report.StiExportFormat.Pdf);
});
});
We demonstrated the automation process with an example. From now on, the report will be converted to a PDF file and saved to disk daily at 10:00.
{
event: "PrepareVariables",
sender: "Viewer",
report: StiReport,
preventDefault: boolean,
async: boolean,
variables: []
}
An example of replacing a variable value:
viewer.onPrepareVariables = (args, callback) => {
args.variables[0].value = "Replace value";
}
{
sender: "Viewer",
event: "BeginProcessData",
report: StiReport,
preventDefault: boolean,
async: boolean,
command: string,
database: string,
connection: string,
headers: [],
withCredentials: string,
// Json
pathData: string,
tryParseDateTime: boolean,
relationDirection: StiRelationDirection,
// Xsd
pathSchema: string,
// Xml
pathData: string,
tryParseDateTime: boolean,
relationDirection: StiRelationDirection,
// Excel
pathData: string,
firstRowIsHeader: boolean,
// OData
connectionString: string,
dataSource: string,
collectionName: string,
// Sql
connectionString: string,
dataSource: string,
queryString: string,
timeout: number,
parameters: { name: string, value: string | number }[],
escapeQueryParameters: boolean,
// Gis
pathData: string,
separator: string,
dataType: StiGisDataType,
// Csv
pathData: string,
separator: string,
codePage: number,
// DBase
pathData: string,
codePage: number
}
Below is an example of replacing a connection string:
viewer.onBeginProcessData = (args) => {
if (args.database == "MySQL")
args.connectionString = "new connection string";
}
And here is an example of our own implementation of data retrieval:
viewer.onBeginProcessData = (args, callback) => {
if (args.database == "MySQL"){
args.preventDefault = true;
var result = {
success: true,
rows: [
["value1", 1, false],
["value2", 1, true],
["value3", 2, false]
],
columns: [
"Column1_name",
"Column2_name",
"Column3_name"
],
types:[
"string",
"int",
"boolean"
]
}
// https://github.com/stimulsoft/DataAdapters.JS/
callback(result);
}
}
{
sender: "Viewer",
event: "EndProcessData",
report: StiReport,
command: string,
dataSource: string,
connection: string,
database: string,
result: DataSet|any
}
An example of adjusting data from the adapter:
viewer.onEndProcessData = (args) => {
if (args.command == "ExecuteQuery" && args.dataSource == "Categories")
args.result.rows.push(rowData) ;
// https://github.com/stimulsoft/DataAdapters.JS/
}
{
sender: "Viewer",
event: "PrintReport",
report: StiReport,
preventDefault: boolean,
async: boolean
printAction: string,
}
An example of deleting a picture before printing:
viewer.onPrintReport = (args) => {
var page = args.report.renderedPages.getByIndex(0);
var image = page.components.getByName("Image1");
if (image)
page.components.remove(image);
}
{
sender: "Viewer",
event: "BeginExportReport",
report: StiReport
preventDefault: boolean,
async: boolean,
action: StiExportAction,
settings: IStiDashboardExportSettings | StiExportSettings,
format: StiExportFormat,
formatName: string,
fileName: string,
openAfterExport: boolean,
}
An example of adjusting export parameters:
viewer.onBeginExportReport = (args) => {
if (args.format == Stimulsoft.Report.StiExportFormat.Pdf)
args.settings.imageQuality = 0.5;
}
{
sender: "Viewer",
event: "BeginExportReport",
report: StiReport,
preventDefault: boolean,
async: boolean,
action: StiExportAction,
format: StiExportFormat,
formatName: string,
fileName: string,
openAfterExport: boolean,
data: string | number[]
}
An example of changing the name of an exported file:
viewer.onEndExportReport = (args) => {
args.fileName = "SampleFileName.txt";
}
{
sender: "Viewer",
event: "Interaction",
report: StiReport,
preventDefault: boolean,
async: boolean,
action: string,
variables,
sortingParameters,
collapsingParameters,
drillDownParameters,
filteringParameters
}
An example of replacing a variable value:
viewer.onInteraction = (args) => {
if (args.action == "Variables")
args.variables["Variable1"] = "New Value";
}
{
sender: "Viewer",
event: "EmailReport",
report: StiReport,
settings: {
email: string;
subject: string;
message: string;
},
format: StiExportFormat,
formatName: string,
fileName: string,
data: number[] | string
}
To enable the button, you need to set the following parameter:
viewerOptions.toolbar.showSendEmailButton = true;
An example of sending email:
viewer.onEmailReport = (args) => {
var emailAddress = args.settings.email;
var emailMessage = args.settings.message;
var emailSubject = args.settings.subject;
var emailAttachmentFileName = args.fileName;
var emailAttachment = args.data;
sendEmail(emailAddress, emailMessage, emailSubject, emailAttachmentFileName, emailAttachment);
}
{
sender: "Viewer",
event: "DesignReport",
report: StiReport
}
To enable the button, you need to set the following parameter:
viewerOptions.toolbar.showDesignButton = true;
An example of deleting a viewer, creating a designer and sending a report to the designer:
var viewerOptions = new Stimulsoft.Viewer.StiViewerOptions();
viewerOptions.toolbar.showDesignButton = true;
var viewer = new Stimulsoft.Viewer.StiViewer(viewerOptions, "StiViewer", false);
viewer.renderHtml("content");
viewer.onDesignReport = (args) => {
var viewerDiv = document.getElementById("content");
viewerDiv.innerHTML = "";
var designerOptions = new Stimulsoft.Designer.StiDesignerOptions();
designerOptions.appearance.fullScreenMode = true;
var designer = new Stimulsoft.Designer.StiDesigner(designerOptions, "StiDesigner", false);
designer.renderHtml("content");
designer.report = args.report;
}
{
sender: "Viewer",
event: "ShowReport",
report: StiReport,
preventDefault: boolean,
async: boolean
}
{
sender: "Viewer",
event: "OpenReport",
report: StiReport,
preventDefault: boolean,
async: boolean
}
To enable the button, you should set the following parameter:
viewerOptions.toolbar.showOpenButton = true;
An example of interrupting the call of a dialog box and passing its template:
viewer.onOpenedReport = (args) => {
args.preventDefault = true;
args.async = true;
args.report = anotherReport;
callback();
}
{
sender: "Viewer",
event: "OpenedReport",
report: StiReport,
preventDefault: boolean,
async: boolean
}
To enable the button, you need to set the following parameter:
viewerOptions.toolbar.showOpenButton = true;
An example of interrupting the opening of a report if the reportAuthor property is not equal to 'Stimulsoft':
viewer.onOpenedReport = (args) => {
if (args.report.reportAuthor != "Stimulsoft") {
args.preventDefault = true;
window.alert("report.reportAuthor == " + args.report.reportAuthor);
}
}
StiReport report = new StiReport();
report.ReportCacheMode = StiReportCacheMode.On;
report.Load(path);
In this scenario, report caching will not be enabled, and here is why: The required ReportCacheMode property, like most report properties, is saved in the report template. Therefore, any value set before loading the report will be overwritten by the value from the template. StiReport report = new StiReport();
report.Load(path);
report.ReportCacheMode = StiReportCacheMode.On;
var settings = new StiWord2007ExportSettings();
settings.EncryptionPassword = "123456";
report.ExportDocument(StiExportFormat.Word2007, "Report.docx", settings);
Code used in our products AFTER version 2024.2.1
var settings = new StiWordExportSettings();
settings.EncryptionPassword = "123456";
report.ExportDocument(StiExportFormat.Word, "Report.docx", settings);
var settings = new StiWord2007ExportSettings();
settings.RestrictEditing = StiWord2007RestrictEditing.ExceptEditableFields;
settings.ProtectionPassword = "123456";
report.ExportDocument(StiExportFormat.Word2007, "Report.docx", settings);
Code used in our products AFTER version 2024.2.1
var settings = new StiWordExportSettings();
settings.RestrictEditing = StiWordRestrictEditing.ExceptEditableFields;
settings.ProtectionPassword = "123456";
report.ExportDocument(StiExportFormat.Word, "Report.docx", settings);
If you have any inquiries or require assistance regarding the process of protecting MS Office documents within Stimulsoft products, please do not hesitate to reach out to us. We are here to provide guidance and support to ensure your documents remain secure.
StiOptions.Engine.CheckForEmptyNestedDetail=false
{
event: "PrepareVariables",
sender: "Report",
report: StiReport,
preventDefault: boolean,
async: boolean,
variables: []
}
An example of replacing a value in a report variable:
report.onPrepareVariables = (args, callback) => {
args.variables[0].value = "Replace value";
}
{
sender: "Report",
event: "BeginProcessData",
report: StiReport,
preventDefault: boolean,
async: boolean,
command: string,
database: string,
connection: string,
headers: [],
withCredentials: string,
// Json
pathData: string,
tryParseDateTime: boolean,
relationDirection: StiRelationDirection,
// Xsd
pathSchema: string,
// Xml
pathData: string,
tryParseDateTime: boolean,
relationDirection: StiRelationDirection,
// Excel
pathData: string,
firstRowIsHeader: boolean,
// OData
connectionString: string,
dataSource: string,
collectionName: string,
// Sql
connectionString: string,
dataSource: string,
queryString: string,
timeout: number,
parameters: { name: string, value: string | number }[],
escapeQueryParameters: boolean,
// Gis
pathData: string,
separator: string,
dataType: StiGisDataType,
// Csv
pathData: string,
separator: string,
codePage: number,
// DBase
pathData: string,
codePage: number
}
Below is an example of replacing a connection string:
report.onBeginProcessData = (args) => {
if (args.database == "MySQL")
args.connectionString = "new connection string";
}
And also, here is an example of our own implementation of data retrieval:
report.onBeginProcessData = (args, callback) => {
if (args.database == "MySQL"){
args.preventDefault = true;
var result = {
success: true,
rows: [
["value1", 1, false],
["value2", 1, true],
["value3", 2, false]
],
columns: [
"Column1_name",
"Column2_name",
"Column3_name"
],
types:[
"string",
"int",
"boolean"
]
}
// https://github.com/stimulsoft/DataAdapters.JS/
callback(result);
}
}
{
sender: "Report",
event: "EndProcessData",
report: StiReport,
command: string,
dataSource: string,
connection: string,
database: sgtring,
result: DataSet|any
}
An example of adjusting data from the adapter:
report.onEndProcessData = (args) => {
if (args.command == "ExecuteQuery" && args.dataSource == "Categories")
args.result.rows.push(rowData) ;
// https://github.com/stimulsoft/DataAdapters.JS/
}
report.onBeginRender = function (args) {
const text = this.pages.getByIndex(0).components.getByIndex(0);
const newValue = report.dictionary.variables.getByName("Variable2").value;
text.text = newValue;
}
report.onRendering = function (args) {
const components = this.pages.getByIndex(0).components.list;
for (let component of components) {
if (component instanceof Stimulsoft.Report.Components.StiText) {
const num = Number.parseFloat(component.text);
if (!isNaN(num)) {
component.text = String(num * 100);
} else {
console.log("The value is NaN");
}
}
}
}
report.onEndRender = (args) => {
report.exportDocumentAsync(function (data) {
Stimulsoft.System.StiObject.saveAs(data, "Report.pdf", "application/pdf");
}, Stimulsoft.Report.StiExportFormat.Pdf);
}
report.onExporting = (args) => {
console.log("The report is complected for exporting to ${args.exportFormat");
}
report.onExported = (args) => {
const pages = report.renderedPages.list;
console.log("PDF file contains " + pages.length + " pages");
}
report.onExported = (args) => {
const pages = report.renderedPages.list;
console.log("PDF file contains " + pages.length + " pages");
}
{
sender: "Report",
event: "PrintReport",
report: StiReport,
preventDefault: boolean,
async: boolean,
data: string | number[]
}
An example of interrupting execution and implementing your own printing method:
report.onPrintReport = (args) => {
args.preventDefault = true;
var printData = args.data;
myPrintingMethod(printData);
}