nextgenSOFTWARE
SOFTWARE NEXT GENERATION

Nextgen Reports user manual

Report previewRendered by NextgenReportEngine
Open PDF ↗
Page 1Demonstration data
Sample sales report, page 1
← Studio

Integrating the engine? Open the Developer guide & code examples for complete C#, HTTP, Blazor and Flutter examples, data connections and exports.

Learn to open, create, edit and share reports using the features available in this version. Start with the first report exercise; programming is optional. This manual is served locally with Studio and does not require an Internet connection. Examples use fictional data.

Contents

  1. Start and find your way around
  2. Open, save and recover work
  3. Build your first report
  4. Data and bindings
  5. Design, pages and formatting
  6. Parameters and input controls
  7. Preview and PDF
  8. Design a parameter dialog
  9. Build a two-step form
  10. Toolbox reference
  11. Code and report events
  12. Dialog events and dependent choices
  13. Keyboard reference
  14. Troubleshooting
  15. Desktop Studio
  16. Flutter and Dart integration
  17. .NET and Blazor integration
  18. Server roles and schedules
  19. Library and versions
  20. SQL, JSON and objects
  21. Limits and terminology

1. Start and find your way around

Open this guide with Manual ↗ in Studio’s bottom status bar, or Code → Manual. It opens in a new tab and leaves your report and unsaved edits in the original Studio tab. Switch back to that original tab to continue editing.

If Studio is already open, no installation commands are needed. Otherwise, from the repository directory, install .NET SDK 10 and Node.js 22+ with npm, then run:

Bash
npm ci --ignore-scripts
npm run prepare-editor
dotnet restore NextgenReports.sln
dotnet build NextgenReports.sln -c Release --no-restore
dotnet run --project src/NextgenReports.Studio --urls http://127.0.0.1:5274

Open the displayed local URL. A sample report loads automatically. Studio defaults to local mode; Library stores versions on the host, and server mode adds accounts and schedules. Save your work before reloading the page or choosing Load sample.

AreaUse
PreviewCalculated pages, page navigation, search and zoom.
DataEdit/upload JSON or inspect arrays as a table.
DesignBuild printed content with Home, Insert, Page and Layout tools.
DialogsArrange the input form using Toolbox, Properties and Document outline.
Report tree / DictionarySelect report blocks / insert data and parameter bindings.
Parameters sidebarEnter current values and the PDF File name.
Generate previewRecalculate from the current template, data and values.
Run with parametersEdit a private input draft, then generate or cancel.

2. Open, save and recover work

  1. Use Open project for a .nrproject.json containing a template, data and values. A failed import leaves current work intact.
  2. For separate files, use Design → Open template for .nrtemplate, then Data → Upload JSON.
  3. Enter parameters, generate, inspect every page and export PDF.
  4. Use Save project to continue later; reopen a downloaded copy to confirm the round trip.
ActionWhat it keeps
Save templateLayout, parameter definitions, images, dialog and code. It does not include input data or current user values.
Save projectThe current draft template, data, values and committed dynamic choices. Saving does not itself validate generation.
Export PDFThe last successful preview request, executed again for PDF.
Undo / RedoUp to 80 template states; not data JSON or the history of entered values.

There is no automatic server backup. New report, Load sample and opening another file replace working state. Save a project first. Projects contain report data; use Save template when only the reusable design should be shared. Undo history resets on successful project import.

3. Build your first report

This exercise creates a one-page equipment list without code.

Download Equipment project to inspect the finished example. Downloading does not change your report. Save your current work, then return to Studio and use Open project to open the downloaded file. It includes fictional data and uses no scripts. To learn by building it yourself, follow the steps below.

  1. Choose New report, name Equipment, A4, Portrait, then Create report.
  2. Open Data → JSON and enter:
JSON
{
  "items": [
    {
      "name": "Monitor",
      "quantity": 8
    },
    {
      "name": "Desk",
      "quantity": 2
    },
    {
      "name": "Chair",
      "quantity": 12
    }
  ]
}
  1. In Data → Table, choose items and confirm three rows.
  2. In Design → Insert → Text, enter Equipment list. Select it, set Home → Size to 20 and enable Bold.
  3. Open Page → Parameters → Add parameter. Set Name company, Type string, Required, Use default and Default value Example Company. Apply parameters.
  4. Add another Text: Company: {{parameters.company}}.
  5. Insert a Table. Set Data source to items. Keep two columns: Item / field name / weight 2; Quantity / field quantity / weight 1 / format N0. Use Add source fields if needed. Leave Positioning as flow.
  6. Open Page → Properties. Set Footer to Page {page} / {pages}.
  7. Choose Generate preview. Expect Example Company and Monitor 8, Desk 2, Chair 12, with Page 1 / 1.
  8. Open Run with parameters, edit company and Cancel: the original value remains. Repeat with Generate preview: the new company is accepted.
  9. Save project, export PDF, then reopen the saved project and compare the result.

For practice, add a Page break followed by Text Notes. Preview should show a second page. Undo removes the last template edit. Long flow tables paginate automatically; do not insert breaks between their rows.

4. Data and bindings

The input is a JSON object, not a spreadsheet. Upload JSON or edit it directly. Arrays supply table rows. Nested objects are addressed using dot-separated paths.

LocationExampleMeaning
Text / header / footer{{data.customer.name}}Read a scalar from input data.
Text / header / footer{{parameters.company}}Read a report parameter.
Table Data sourceitemsArray path from the data object.
Column FieldquantityPath relative to each row, not items.quantity.
Header / footer only{page} / {pages}Current and total printed pages.

Bindings are paths, not arbitrary expressions. Use column Expression for numeric table calculations; use beforeRender for other computations and bind its result. Missing paths and invalid types produce errors. Dictionary can create a new text block or insert a binding at the selection/caret in selected text.

Data → Table displays 100 rows per page, up to 50 columns. Find rows searches the chosen array; column headers cycle ascending, descending and original order. Reset sort restores source order. These operations affect inspection only, not JSON or report output. Use Design → Table → Sort by to sort report output, or beforeRender for advanced ordering/filtering. Dates are supplied as strings. XLSX import and explicit HTTP/SQL/JSON/object refresh are described below.

5. Design, pages and formatting

Select a block in Report tree or on the sheet, then edit its properties. Insert offers Text, Table, Image and Page break. Home controls text style, duplicate/delete and Copy style / Apply style. Layout changes order and aligns fixed frames. Edit JSON exposes the template; Open block designer returns to visual editing.

Pages and text

Page → Properties edits Width, Height, Margin, Header and Footer. Report dimensions use points: 72 pt = 1 inch. Dialog geometry uses CSS pixels instead. Header/footer must fit on one line. Text wraps and preserves explicit line breaks; use Space after for separation. Copy style transfers size, bold, color and alignment, not content or geometry.

Tables

Set the array source and columns. Width weight is relative, not an absolute width. Add source fields suggests scalar fields from data; manually enter paths for empty arrays. Move left/right and Duplicate column retain column settings. Use N0–N6 or F0–F6 for numbers, column alignment, cell padding, header color and alternating stripe color. Numeric formatting is invariant, not browser-locale dependent. Headers repeat across pages; very tall rows may continue on the next page. Nested grouping and master-detail are available; merged cells are not supported.

Filtering report rows

  1. Select a Table. Enter a row field (such as amount) in Filter field. Nested paths and undisplayed fields are allowed.
  2. Choose Filter condition: Equals, Does not equal, Greater than, At least, Less than, At most, Contains, Is null or Is not null.
  3. For conditions other than Is null / Is not null, choose Filter value source → Constant, then set Filter value type (string/number/boolean) and Filter value. Enter plain text without JSON quotes. Changing type resets the value to empty text, 0 or false.
  4. Generate preview. Clear Filter field to disable; Undo/Redo and Save project retain the settings.

Processing order is filter → sort → group → aggregate. Only surviving rows contribute to totals and groups; source JSON stays unchanged. No matches produce an empty table with zero Sum/Count and blank Average/Min/Max. Data → Table search still affects inspection only. Up to 20 conditions can use All/Any; use grouped filters for nested conditions and beforeRender for advanced transformations.

Try grouped-orders: amount / At least / number / 80 keeps Monitor and Desk, amount total 205.50 and quantity 3. Value 1000 leaves no rows. customer / Contains / string / North keeps Monitor and Chair, total 200.00. Is null on customer keeps none; Is not null keeps all six. Export PDF and reopen the project to verify.

Non-null field and value types must match; numeric strings are not converted. Numbers compare as decimal; text/Contains are ordinal and case-sensitive. Contains requires text; empty text matches every non-null string. Boolean supports Equals/Does not equal. Null matches Is null and Does not equal a supplied value, but no other ordinary comparison. Is not null accepts any non-null value. Missing fields are errors even for Is null. Invalid definitions fail even on empty sources.

Combining conditions with All / Any

Add filter adds an Additional filter block. It copies the primary condition when present, otherwise the last additional condition; with none, it starts with Is not null on the first detected field. Edit field/condition/value source in that block. Each condition can use its own constant or report parameter.

Match conditions → All (AND) requires every condition; Any (OR) requires at least one. A row matching several OR conditions is counted once. All is the default. There are at most 20 conditions including the primary one; Use grouped filters converts these conditions to a nested AND/OR tree.

Try samples/combined-filters.nrtemplate with grouped-orders.data.json: amount ≥ minAmount (default 80) plus customer Equals North. All gives Monitor and 125.50; Any gives Monitor, Chair and Desk, total 280.00. Test Undo/Redo, PDF and save/reopen.

Remove filter removes that additional condition; clearing a Filter field removes only that condition. Clear filters removes all conditions in one Undo step. No conditions include every row in either mode. Removing the extra condition in the sample gives 205.50; clearing all gives 310.30.

Every condition is checked for every source row without short-circuiting, so OR cannot hide a missing-field or type error in another condition. Definitions and parameters are checked even with no source rows. Filtering still precedes sorting, grouping and totals without changing source JSON.

Filter from a report parameter

  1. In Page → Parameters, add minAmount, Type number, Required, Default 80; Apply parameters.
  2. Select the Table: Filter field amount, condition At least. Choose Filter value source → Report parameter and Filter parameter → minAmount.
  3. Generate preview uses the current/default value. Open Run with parameters and change the minimum: Generate applies it, Cancel preserves the prior values and report.

Try samples/parameter-filter.nrtemplate with samples/grouped-orders.data.json: default 80 gives Monitor + Desk and total 205.50; 100 gives Monitor and 125.50; 0 gives all rows and 310.30. Save/reopen the project to preserve the binding and run values. PDF matches the last generated snapshot, so generate again after changing parameters. Undo/Redo supports binding edits.

The selector lists scalar string/number/boolean parameters. Contains requires string; ordered comparisons require string/number; equality also supports boolean. The value must match the data field type. Unknown/deleted parameters and string[] are rejected. Supply defaults or run values for number/boolean: an omitted optional value does not disable the filter. Empty string remains valid; empty Contains matches all non-null text. Decimal range rules still apply.

Changing to Is null/Is not null clears the parameter binding. Changing to Constant clears the binding and starts with empty text; choose type/value again. Other condition changes retain the parameter, so verify type compatibility.

Sorting report rows

  1. Select a Table in Design. Enter a row field such as amount in Sort by; nested paths are allowed, even for fields not displayed as columns.
  2. Set Sort direction to asc (ascending, default) or desc (descending), then Generate preview.
  3. Clear Sort by to remove the primary key; Clear sorting removes every key. Undo/Redo and saved projects preserve these settings.

Filtering happens first, then sorting, then grouping. Groups follow first occurrence in sorted rows; rows retain that order inside each group. Equal sort keys keep original order in either direction. Set Sort by and Group by to the same field to order groups by key. Only this table changes; source JSON is untouched. Data → Table sorting still affects inspection only.

In the grouped-orders sample, amount asc gives East/South/North and Clip, Cable, Lamp, Desk, Chair, Monitor; desc gives North/South/East and Monitor, Chair, Desk, Lamp, Cable, Clip. Grand total stays 310.30. Clearing Sort by restores the original group order.

Non-null keys must all be decimal numbers, strings or booleans of the same type. Numbers sort numerically, strings use case-sensitive ordinal order (A, Z, a) independent of locale, and false precedes true ascending. Null sorts first ascending and last descending. Mixed types, missing fields, arrays/objects and numbers outside decimal range fail. Dates sort as text: use consistent ISO strings for chronological ordering. Up to five keys are supported; use beforeRender for computed keys or advanced transformations. Sorting by aggregate results is not supported.

Multiple sort priorities

Add sort field adds a Then by block with Sort field and Direction. Sort by is the primary key; additional fields are applied top to bottom to refine ties. Earlier / Later reorder additional keys; the primary key stays first. Up to five keys total are supported. The added field defaults to the first unused detected field: check it before generating.

Types are checked separately per key, so a text customer key can precede a numeric amount key. Each key follows the same null/ordinal/decimal rules. Complete ties preserve source order in either direction. Even a low-priority key must exist and have a consistent type across all filtered rows. Fields may be nested or absent from displayed columns.

Try samples/multi-sort.nrtemplate with grouped-orders.data.json: customer asc then amount asc gives East Clip/Cable, North Chair/Monitor, South Lamp/Desk. Amount desc gives Cable/Clip, Monitor/Chair, Desk/Lamp. Add item desc and move it Earlier: Monitor precedes Chair within North. Total remains 310.30. Check Undo/Redo, PDF and project save/reopen.

Remove sort or clearing Sort field removes that additional key. Clear sorting removes all keys in one Undo step. Clearing only the primary Sort by leaves the additional keys active. With no keys, source order is used before grouping. Input JSON is unchanged; sorting by aggregate results is not supported.

Grouping and totals

  1. Select a Table. Set Group by to a row field such as customer; leave blank to remove the primary level; Clear grouping removes all levels.
  2. Choose Aggregate → Sum, Average, Min, Max or Count on columns; None disables the aggregate. Toggle Group subtotals and Grand total independently; both default on.
  3. Generate preview. Groups follow first occurrence, with source order (or the optional sorted order) inside each group, including non-adjacent matching rows.

Totals have a full-width Subtotal/Grand total caption followed by aligned values using each column's number format. Other cells stay blank. Without aggregates there are no totals; without grouping only the grand total appears. An empty array gives zero for Sum/Count and blank for Average/Min/Max. Save project preserves these settings; Undo/Redo applies to edits.

Group keys may be strings (case-sensitive), decimal numbers, booleans or null, shown as (null). Number 1 and 1.0 match; string "1" is separate. Missing keys, objects and arrays fail. Every Sum/Average/Min/Max value must be a JSON decimal number: missing values, null, numeric strings and overflow fail. Values are summed before formatting.

Cross-tab tables

A cross-tab turns records into a matrix, for example regions by quarter with sales at each intersection.

  1. Try samples/cross-tab.nrtemplate with samples/cross-tab.data.json, or prepare items with region, quarter and amount.
  2. Choose Insert → Cross-tab. Set Data source to items, Row field to region, Column field to quarter and Value field to amount. Source paths are root-relative; field paths are record-relative. Dotted paths are supported.
  3. Select Aggregate: sum, average, min, max or count. Count counts records without reading Value field; the others require decimal JSON numbers in every record.
  4. Set Number format (F0–F6/N0–N6; empty preserves precision) and Font size. Toggle Row totals for the right Total column and Column totals for the bottom Grand total row.
  5. Generate preview and export PDF. The sample shows North/Q1 30.30, North/Q2 9.70, South/Q1 −5.00, South/Q2 0.00 and grand total 35.00. With Average the grand total is 8.75. Totals aggregate original records, never averages of cells. Undo/Redo, duplication/reordering and saved projects preserve settings.

Categories must be nonempty strings of at most 200 characters. Case and spaces are preserved and compared exactly; numbers, null, arrays, objects and missing categories fail. Convert categories to strings before rendering. Both axes use first-seen order. Missing intersections show 0 for Sum/Count and blank for Average/Min/Max. Empty arrays keep headings and enabled totals.

Up to three levels per axis and three measures; up to 100,000 records, 1,000 row categories and 20 column categories. Flow only, with headers repeated on subsequent pages. Columns do not split horizontally: each numeric column needs at least 40pt and row labels take double width. Reduce categories or widen the page on a width error. Long text wraps. The final total row uses ordinary matrix-row styling. Prepare filters, sorting and transformations in data/beforeRender; other tables' settings do not affect this block. No Fixed or visual filters yet.

Nested axes

  1. Open samples/cross-tab-hierarchy.nrtemplate with samples/cross-tab-hierarchy.data.json.
  2. Set Row field to region. Click Add row level and set Row level 2 to city. Set Column field to year, then Add column level and Column level 2 to quarter.
  3. Add up to three distinct field paths per axis, outermost first. All category values must be nonempty strings. Edit the fields to change level order. Remove row level / Remove column level removes the last level; removing level 2 restores the single-field editor. Undo/Redo preserves changes.
  4. Generate preview: North/Central and North/Harbor stay together before South/Central. Columns are 2025/Q1, 2025/Q2, 2026/Q1. Equal child names under different parents remain independent. North/Central has Sales 60.00 and Average 30.00; grand totals are Sales 110.00 and Average 27.50.
  5. Save the project or export PDF. All levels and measures are retained; every page repeats full column headings.

Paths print on separate lines with repeated parent labels, with repeated row labels and no collapse controls; column headings can be merged. Optional group subtotals are described below. Siblings follow first-seen order within each parent. Limits of 1,000 rows and 20 column categories count leaf paths; width and measure limits still apply. Totals aggregate original records. In JSON, nonempty rowFields/columnFields replace rowField/columnField; empty lists restore legacy fields.

Group subtotals

  1. Open samples/cross-tab-subtotals.nrtemplate with samples/cross-tab-hierarchy.data.json, or select a Cross-tab with nested axes.
  2. Enable Row group subtotals for a Subtotal row after each parent's children. Enable Column group subtotals for a Subtotal column group, with every measure, after each parent's columns.
  3. For this dense sample, set Font size to 8 and generate preview: North Subtotal has Sales 90.00 and Average 30.00; grand totals remain 110.00 and 27.50. Subtotals use original records, never averages of displayed values or sums that include other subtotal cells.
  4. Toggle the switches independently. You can hide Row totals and Column totals while keeping group subtotals. Undo/Redo, saved projects and PDF retain these settings. Both subtotal switches default off.

Three-level axes subtotal the inner group first, then the outer group, including parents with one child. Single-level axes and empty data add none. Labels show the parent path followed by Subtotal. Rows use ordinary matrix styling and may continue on another page; subtotal column headings repeat. Per-level subtotal selection is not supported.

Subtotal columns count toward the 50 rendered-column limit and require at least 40pt per measure. On a width error, disable Column group subtotals, reduce categories/measures or widen the page. The 1,000-row and 20-column category limits count leaf paths; subtotal rows are additional (up to 2,000 for three levels). In JSON use showRowSubtotals and showColumnSubtotals.

Merged column headers

  1. Open samples/cross-tab-merged-headers.nrtemplate with samples/cross-tab-hierarchy.data.json, or select a Cross-tab with nested column categories or multiple measures.
  2. Enable Merge column headers and generate preview. The sample shows 2025 once above its Q1, Q2 and Subtotal columns, and 2026 above its own Q1 and Subtotal. Sales/Average form a separate bottom header band.
  3. Group subtotal and grand-total switches still work independently. Values stay unchanged: North 90.00/30.00, grand totals 110.00/27.50.
  4. Save the project or export PDF. Every page repeats the complete header. Undo/Redo preserves the switch; it defaults off.

Only column headings are merged, using the full parent path. Row labels repeat full paths unless Merge row labels is enabled separately. Total spans the category bands, while Subtotal spans the remaining bands below its parent. Explicit measure titles appear below. Long text wraps within its combined cell width. The header can become taller and change page counts; if it cannot fit with one data line, increase page height, reduce font size or disable Merge column headers. Width and column-count limits remain unchanged. In JSON set mergeColumnHeaders to true.

Merged row labels

  1. Open samples/cross-tab-merged-rows.nrtemplate with samples/cross-tab-hierarchy.data.json, or select a Cross-tab with nested row categories.
  2. The sample uses A3 landscape: Page properties → Width (pt) 1190.55, Height (pt) 841.89. Enable Merge row labels and generate preview. Each row level has its own column. North appears once beside Central, Harbor and its subtotal; South/Central remains a separate group.
  3. Merge column headers works independently. Subtotal spans the remaining label columns; Grand total spans all of them. Sample totals stay 110.00/27.50.
  4. Save the project or export PDF. Parent labels repeat beside continued groups on each new page. Undo/Redo preserves the switch, which defaults off.

Labels use white cells with borders and left/top alignment; numeric stripes remain. Each level needs its own label column at double relative width, included in the 50-column limit. Widen the page, reduce measures/categories or disable Merge row labels if the matrix is too wide.

With row merging enabled, each matrix row must fit below the repeated header. Overly tall labels cause an error: increase page height, reduce font size or disable Merge row labels to restore ordinary row splitting. Text and records are never silently truncated. In JSON use mergeRowLabels.

Multiple cross-tab measures

  1. Click Add measure in Cross-tab properties. The current measure becomes Measure 1 (Title Value); Measure 2 starts with Count and F0.
  2. Set each measure's unique Title, Value field, Aggregate and Number format. For example Sales/amount/sum/F2, Orders/amount/count/F0 and Average/amount/average/F2. Count does not read Value field.
  3. Add up to three measures. Move measure up/down changes their order in every category and total. Remove measure removes the selected measure; the final one cannot be removed. With one remaining, Use single measure preserves its field, aggregate and format and removes its separate title.
  4. Choose Page → A4 landscape and generate preview. Each column category is followed by its measure titles; the right Total group uses the same order. Grand total aggregates original records independently for each measure.
  5. Try samples/cross-tab-measures.nrtemplate with samples/cross-tab.data.json: Sales total 35.00, Orders 4, Average 8.75; Q1 average 8.43. Save the project or export PDF. Adding, editing, removing and reordering support Undo/Redo.

Titles must be distinct nonempty strings up to 100 characters (case-sensitive). Each category uses one column per measure. At most 50 rendered columns including row labels and totals; the page-width limit may be reached sooner. Reduce categories/measures, disable Row totals or widen the page. Empty intersections are zero for Sum/Count, blank otherwise. Existing single-measure templates remain compatible. In JSON, a nonempty measures list replaces and ignores the block's valueField/aggregate/format; an empty list uses those legacy settings.

Code 39 barcodes

  1. In Design choose Insert → Barcode.
  2. Set Barcode value to SO-2026-001, {{data.orderCode}} or a declared {{parameters.code}}. Store identifiers with leading zeros as JSON strings.
  3. Set Module width (pt) from 1 to 4 (default 1). This is the narrow bar width; wide bars are three times wider. Total width is automatic and includes white quiet zones.
  4. Set Barcode height (pt) (default 60). It includes the optional human-readable text. Show text controls the caption; Text size (pt) is at most 36. Hiding text gives all the height to bars without changing the payload.
  5. Generate preview and export PDF. Design shows the value; Preview/PDF show vector bars. Undo/Redo, duplicate/reorder and saved templates/projects preserve settings.

Try samples/code39.nrtemplate with samples/code39.data.json: the displayed and decoded value is SO-2026-001. Start/stop asterisks are automatic and excluded from the caption; do not enter *.

Standard Code 39 without checksum or Extended/Full ASCII. Resolved payload: 1–80 characters, A–Z, 0–9, space and - . $ / + %. No automatic uppercasing or trimming. Lowercase, Unicode, underscore, line breaks, empty values and * fail generation. Configure the reader for standard Code 39 without mandatory checksum or extended ASCII.

Flow only; the entire block moves to the next page when needed. No Fixed, table-cell barcodes or optional Code 39 checksum yet. QR/Data Matrix are described below. Black bars on white; colors are fixed. Bars must be at least 20pt high. If text is too wide, reduce its font or hide it. If the barcode is too wide, shorten the value, reduce the module (minimum 1pt), or widen the page. An 80-character payload may require a wider page. Keep quiet zones clear and print at actual size.

Rasterized PDFs were independently decoded at 150/300 dpi, including hidden text, the minimum 1pt module and the full alphabet. A physical printer/scanner has not been tested; check a sample with your actual printing setup.

Code 128 B barcode

  1. Choose Insert → Barcode, then Symbology → code128b. The default code39 preserves existing templates.
  2. Set Barcode value to so_2026-001 or {{data.orderCode}}. Use 1–80 printable ASCII characters (space through ~), including lowercase, underscore and *. Case, spaces and leading zeros are preserved; store identifiers as JSON strings.
  3. Set Module width (pt) from 1 to 4, height and Show text. Bars/spaces are one to four modules wide; white quiet zones count toward the total width. If too wide, reduce the module to 1pt, shorten the value or widen the page. Bars must be at least 20pt high.
  4. Generate preview and export PDF: expect black vector bars and the original caption. Start/stop and the mandatory checksum are automatic and excluded from the caption. Hiding text preserves the encoded value.
  5. Save/reopen a project to retain symbology and settings; Undo/Redo restores changes. Switching back to code39 with lowercase produces a validation error.

Try samples/code128b.nrtemplate with samples/code128b.data.json; a Code 128 reader should return so_2026-001. Flow only, whole-block pagination. Code Set B only: no A/C switching, numeric compression, GS1/FNC1 or control characters. Unicode and newlines fail after binding. This is not GS1-128. Caption/page-fit constraints match Code 39; no automatic shrinking.

EAN-13, EAN-8 and UPC-A

  1. Open samples/retail-barcodes.nrtemplate with samples/retail-barcodes.data.json, or choose Insert → Barcode.
  2. Select Symbology: ean13, ean8 or upca. Enter 12, 7 or 11 ASCII digits respectively to calculate a check digit, or a complete 13/8/12-digit code to validate it. Incorrect check digits fail without silent repair.
  3. Use a literal or data/parameter binding. Keep codes as JSON strings to preserve leading zeros; spaces and Unicode digits are rejected.
  4. Set Module width (1–4pt), height and Show text, then Generate preview. Expected sample captions: 5901234123457, 96385074 and 036000291452. Captions include the calculated check digit; template/data stay unchanged.
  5. Export PDF or save a project. Bars remain vector shapes; projects and Undo/Redo retain settings. Hiding captions preserves the encoded value.

Flow only, whole-block pagination. Bars must be at least 20pt high; quiet zones on both sides are at least 11 modules and 18pt. If too wide, reduce the module to 1pt or widen the page; never crop quiet zones. Equal-height bars and a centered caption are used, without extended guards or grouped digits for retail packaging. Some readers return UPC-A as equivalent EAN-13 with a leading zero (0036000291452 in the sample); the caption remains 12 digits. No UPC-E, 2/5-digit supplements, GS1-128 or GTIN registration checks. PDF decoding is verified in software; physical printer/scanner and packaging compliance remain unverified.

Line charts

  1. Open samples/line-chart.nrtemplate with samples/bar-chart.data.json, or insert a Chart and set its source/fields.
  2. Select Chart type → line. Orientation is disabled: categories always run left-to-right. The saved orientation is reused when switching back to bar.
  3. Set Line color, Negative color, number format, height and font. Generate preview connects North 125.50, South 80.00, Returns −30.00 and East 0.00 in source order. The whole line uses Line color; negative point markers use Negative color. Values appear above the plot, categories below.
  4. Save the project or export PDF. Segments and square markers remain vector shapes. Chart type supports Undo/Redo; bar restores the bar chart.

Categories are equally spaced, including date-like or numeric labels. This example uses one categorical series, without an XY/time scale, smoothing or area fill. Duplicate categories remain separate. Zero points are included; one record has only a marker and empty data shows No data. Missing/non-numeric values fail rather than creating gaps. The same 30-row, width/height and whole-chart pagination rules as vertical bars apply.

Vertical column charts

  1. Open samples/column-chart.nrtemplate with samples/bar-chart.data.json, or choose Insert → Chart and set the source/fields as described below.
  2. Select Orientation → vertical. Set Chart height (pt) (for example 260), number format, colors and font; generate preview.
  3. North 125.50 and South 80.00 extend upward from zero; Returns −30.00 extends downward. East 0.00 has a label without a bar. Values appear in a band above the plot and categories below it. Bar height uses the original value.
  4. Export PDF or save the project. Orientation supports Undo/Redo. Select Orientation → horizontal to switch back; existing templates default to horizontal.

This example uses one series, up to 30 source rows in original order; repeated categories stay separate. Empty data shows No data. The vector chart moves whole to another page when necessary. Values must fit on one line in their category slots; category labels can wrap. For width errors widen the page, reduce font/precision or use fewer categories. For height errors increase Chart height or reduce font/label length. Labels are not clipped. Add series enables grouped bars or multiple lines with a legend; Bar mode enables stacking. Pie and donut composition charts are described below.

Horizontal bar charts

  1. Prepare an array such as {"regions":[{"name":"North","net":125.5},{"name":"Returns","net":-30}]}.
  2. In Design, choose Insert → Chart and select the new block.
  3. Set Data source to regions, Category field to name and Value field to net. The source is root-relative; fields are row-relative dotted paths. Changing the source refreshes field suggestions.
  4. Set Chart title, Chart height (pt) (for example 260) and Number format F2. Title supports data/parameters bindings; empty hides it. Empty format uses the original numeric value without added formatting.
  5. Choose Bar color, Negative color, Font size and Text color. Generate preview and export PDF. Design shows structure; Preview shows the actual chart.

Positive bars extend right of zero, negative bars left, and zero values have a label without a bar. Length uses the original value; display rounding does not change geometry. Numbers appear in a right-hand column. Source order is preserved; duplicate categories remain separate. Prepare summaries, filtering and sorting in data/beforeRender. Other tables' settings do not affect the chart. Undo/Redo, duplicate/reorder and saved templates/projects preserve chart settings. PDF uses vector bars and text labels.

Try samples/bar-chart.nrtemplate with samples/bar-chart.data.json: North 125.50, South 80.00, Returns −30.00, East 0.00. Empty arrays display No data. Values must be JSON decimal numbers; missing/null/non-numeric values fail. Categories must be scalar; null displays (null).

Up to three series of horizontal/vertical bars or lines, at most 30 rows, Flow only. The chart moves whole to the next page when needed; its height must fit one page's content area. Category labels wrap; labels that cannot fit cause an error instead of clipping. Increase height, reduce font size, or shorten/reduce categories. For wide numeric labels, reduce font/precision or widen the page. Title limit: 10,000 characters. No Fixed placement, drill-down or built-in aggregates yet.

Multiple chart series

  1. Open samples/chart-series.nrtemplate with samples/chart-series.data.json. Generate preview shows grouped horizontal bars, grouped columns and multiple lines on three pages. Actual/Budget/Previous share one zero scale; South Previous is negative and East Actual is zero.
  2. For your own chart, set Data source and Category field, then Add series. The current value field, format and color become the first series; a second is added.
  3. Set each Series Title, Value field, Number format and Color. Titles must be distinct, nonempty and at most 100 characters. Up to three series, all from each record of the same array.
  4. Use Move series up/down and Remove series. One explicit series must remain. Use single series transfers its field/format/color to legacy settings and removes the legend.
  5. Choose Chart type bar/line and, for bars, Orientation. Bars form groups; lines connect only points of their own series. Colors identify series for both signs; Negative color applies only in legacy mode and becomes active again after Use single series. Choose distinct colors.
  6. Generate preview, export PDF or save/reopen the project. Legend order, values and colors persist. Undo/Redo restores changes; source data remains unchanged. Number formats affect labels only.

The legend is above the plot and consumes Chart height. Vertical/line values appear above the plot, one row per series in legend order; horizontal values align with bars. If crowded, increase height/page width, reduce font/precision or use fewer categories. Labels are not clipped. Empty data retains the legend and shows No data; one line record has one marker per series. Missing/null/non-numeric values fail. Maximum 30 source records, original order, duplicate categories remain separate. No dual axes, mixed types, automatic aggregation or gaps. Missing/empty series retains the original single-value behavior.

Stacked and percentage bars

  1. Open samples/stacked-charts.nrtemplate with samples/stacked-charts.data.json. Generate preview shows four pages: stacked/percent in both orientations.
  2. For your own chart, use Add series and Chart type → bar. Choose Bar mode: grouped (default), stacked or percent; Orientation controls the direction.
  3. In stacked mode, positive series accumulate right/up from zero; negative series separately left/down. Colors follow the legend; series order controls segment order from zero. The common scale uses category sums. Outside labels show original formatted values in legend order.
  4. In percent mode each nonempty sign side normalizes independently to 100%. North 120/60/60 becomes 50%/25%/25%; South 60/-30/-10 becomes 100%/-75%/-25%. This is not a share of the signed net total. Mixed-sign categories can span -100% to +100%. East stays zero.
  5. Number format controls percentage labels (F1 recommended), with % appended. Labels replace original amounts in this mode. Rounded labels may total 99.9%/100.1%; geometry uses unrounded shares.
  6. Preview/PDF, saved projects and Undo/Redo preserve the mode. Switching to line disables Bar mode and uses original values; returning to bar restores the saved mode. Use single series resets grouped and removes the legend. Source data is unchanged.

Up to three series, Flow only; the whole chart moves together. Legend and labels consume chart height. Increase dimensions or reduce font/precision if crowded. Zero values have labels without segments; empty data shows No data. No mixed chart-type stacking or totals inside segments. Existing templates stay grouped.

Nested filter groups

  1. Open samples/nested-filters.nrtemplate with samples/grouped-orders.data.json. With minAmount = 80, Preview shows Monitor and Desk; grand total is 205.50.
  2. Select the table in Design. Use grouped filters converts existing conditions and All/Any without changing their meaning. With no filters, it creates Is not null on the first detected field.
  3. Group match → All (AND) requires every direct condition and subgroup; Any (OR) requires at least one. Add condition starts with Is not null; configure field, operator, typed constant or Report parameter.
  4. Add subgroup creates an Any group with one condition. Example: root All with amount ≥ minAmount and an Any subgroup containing customer = North and customer = South.
  5. Remove condition/subgroup keeps each group nonempty. Clear filters removes the tree and restores the simple editor. Undo/Redo includes conversion and removal.
  6. Generate preview, export PDF/HTML or save the project. Filtering precedes sorting, grouping and totals; source data stays unchanged.

Up to 3 levels including root, 10 groups and 20 total conditions. Scroll the properties panel for larger trees. Flow, Fixed and master-detail are supported; master-detail filters child rows per parent. Every branch is checked, so data type errors cannot be hidden by a matching OR branch. No standalone NOT or moving conditions between groups. Legacy filter/filters remain supported but cannot coexist with filterGroup.

Standalone HTML export

  1. Generate preview, then select Export HTML in the Preview toolbar.
  2. Open the downloaded .html file in a browser. It contains every page, embedded DejaVu fonts and PNG/JPEG images; Studio and internet are not needed. Text remains selectable/searchable and charts/barcodes remain vector graphics.
  3. After editing, generate preview again before exporting. Like PDF, HTML exports the last successful render request; the server reruns enabled scripts, so nondeterministic handlers can change results.

This is a fixed page report, not an editable project or a spreadsheet table. Narrow screens scale whole pages without reflow. Fonts add about 2 MB. No scripts or external resources are included. Print CSS supplies page sizes, but browser/printer settings may override them; use PDF for precise printing. macOS and Windows remain unverified.

Use scripts/report-tool.py --template samples/sales.nrtemplate --data samples/sales.data.json --format html --output artifacts/sales.html with Studio running, or give the .NET CLI an output filename ending in .html for offline generation. API: POST /api/export/html, same request as PDF, returns text/html and X-Report-Pages.

Import CSV / TSV

  1. Open Data → Import data, choose a UTF-8 file and a Table name such as items. TSV selects Tab; other files default to Comma. Choose Semicolon/Pipe if needed. First row contains headers can be disabled for column1, column2, etc.
  2. Keep all text preserves strings. Infer columns examines every row: lowercase true/false become booleans; plain decimal-point numbers with at most 15 digits become numbers. Leading zeros, dates, exponents, longer numbers and mixed columns stay text. Select individual auto/string/number/boolean overrides and Preview again. Invalid forced values fail; empty numeric/boolean cells become null, empty text stays empty.
  3. Preview the counts, first 20 rows and normalized field names (Product name → Product_name; non-ASCII-only names → columnN; collisions receive suffixes). Values are not trimmed; formulas/HTML are literal data. Long preview cells are truncated to 500 characters without truncating imported values.
  4. Apply import adds one root array and preserves other data. Replacing an existing array requires Replace existing table; object/scalar properties cannot be replaced. Cancel/errors leave the project unchanged. Changed options require another Preview.
  5. Set the report table's Data source and fields to the imported array/keys, then generate Preview/PDF. Import does not rebuild report columns. Undo import restores the latest import while its data is unchanged; it is separate from template Undo/Redo. Save your project to retain rows.

Try samples/import/items.csv or items.tsv with table name items and Infer columns, then samples/import/inventory.nrtemplate. Codes retain leading zeros, quantity/price become numbers and active becomes boolean. Quoted delimiters, doubled quotes and multiline values are supported. Headers must be unique/nonempty (100 characters maximum); unequal field counts, malformed quotes, whitespace after a closing quote and NUL fail. Limits: 2 MB UTF-8, 10,000 rows, 50 columns, 200,000 cells including headers, 64,000 characters per field, 6 MB imported JSON and 8 MB project. Table names use ASCII letters/digits/underscores and start with a letter/underscore. This is a one-time import, without live refresh, SQL, HTTP or encoding conversion. XLSX worksheets are supported as described below.

Text and calendar expressions

  1. Open samples/text-dates.nrtemplate with text-dates.data.json. Preview shows ALICE NORTH *, GUEST, due dates 06 Mar 2024 / 08 Mar 2024, Count 2 and total 1,314.50.
  2. In Design, edit a Text block: Due {{= formatDate(addDays(data.ordered, 7), 'dd MMM yyyy') }}. Inline expressions also work in page headers/footers, chart titles, barcode values and Master header. Existing dotted bindings remain supported.
  3. For a table column, enter concat(upper(trim(coalesce(row.name, 'Guest'))), if(row.priority, ' *', '')) in Text expression. It overrides Field. Enabling it clears numeric Expression, Number format and numeric aggregates; Count remains available. Undo/Redo restores settings. Clear Text expression to use Field again.
  4. Use formatDate(addDays(row.ordered, parameters.leadDays), 'dd MMM yyyy') for due dates. Run with parameters → Lead days = 2 gives 01 Mar 2024 and 03 Mar 2024. daysBetween(data.reportDate, row.ordered) returns signed end-minus-start calendar days.
  5. Generate preview, Save project, reopen and export PDF/HTML. Source JSON remains unchanged. Invalid dates or arguments produce errors; correct the expression and generate again.

Functions: concat (1–16 scalar arguments), upper/lower/trim, replace (case-sensitive, nonempty search), substring(text,start,length) and length (zero-based UTF-16), coalesce (null only), eq (exact scalar equality), if (boolean condition, lazy branches), formatNumber (N0–N6/F0–F6), formatDate, addDays and daysBetween. coalesce does not hide missing fields. Use single-quoted strings, decimal numbers without exponent, true/false/null; string escapes are \', \\, \n, \r, \t. No arithmetic operators in the text language; numeric Expression keeps its existing syntax.

References: row is a table row, data the enclosing report/repeat context, root the report data, parent the enclosing repeat context, parameters a declared scalar parameter. master is only available in Master header. Arrays/objects and string[] parameters are unsupported. Global headers/footers use root data. Sorting/filtering/grouping/style rules use original fields, not computed text. Substituted braces are literal, never re-evaluated.

Dates must be real ISO yyyy-MM-dd calendar dates, without time/timezone. Output formats: yyyy-MM-dd, dd/MM/yyyy, MM/dd/yyyy, dd.MM.yyyy, dd MMM yyyy, MMMM d, yyyy, yyyy-MM; month names are English. Leap years are respected. There is no now(), month/year arithmetic or locale setting: supply the current date as data/parameter. Limits: years 0001–9999, integer arguments ±1,000,000, 512 expression characters, 128 nodes, 16 levels/arguments and 16,000 UTF-16 units per string input/intermediate/result. Definitions validate even for empty sources; values validate during evaluation.

Pie and donut composition charts

  1. Open samples/circular-charts.nrtemplate with matching data. Preview shows region shares 50/30/20% and channel shares 60/25/15%, each totaling 1,000.00. Zero category Other stays in the legend without a slice.
  2. Select or insert Chart. Choose Chart type → pie / donut, Data source, Category field and Value field. Number format controls legend values and total. Chart title supports bindings/expressions.
  3. Slice colors accepts 1–12 comma-separated #RRGGBB colors, assigned by source-row order and reused cyclically. Show percentages toggles the percentage beside each value. Bar/Negative/series colors do not override this palette.
  4. For donut, Donut hole ratio 0.2–0.8 sets inner/outer radius (default 0.55). Orientation/Bar mode and Add series are disabled. A single existing explicit series is supported; remove extra series before selecting pie/donut. Use separate charts to compare measures.
  5. Generate preview. Increase Chart height, reduce Font size or shorten category labels if the right-hand legend cannot fit. The entire chart moves to the next page when necessary. Verify Undo/Redo, Save project, reopen and export PDF/HTML: geometry and holes remain the same.

At most 12 rows, nonnegative decimal values; negative/null/nonnumeric data fails. Empty input shows No data, all zeros No positive values. Duplicate categories stay separate; prepare aggregated data first if needed. Legend values and total always remain visible. Percentages use one decimal and may not sum to exactly 100% after rounding; geometry uses unrounded proportions. Sectors start at 12 o'clock, clockwise. Flow only, including repeat contexts, with an 80pt minimum circle and legend width. No Fixed, 3D, exploded sectors, inside-slice captions or multi-page legends. Boundaries are vectors with chords of at most two degrees.

QR Code and Data Matrix labels

  1. Open samples/matrix-barcodes.nrtemplate with matrix-barcodes.data.json. Preview produces two shipping-label pages, SO-101 and SO-102, each with a tracking QR and internal-reference Data Matrix.
  2. Use Insert → Barcode or Edit section → select an existing barcode. Choose Symbology → qr / dataMatrix. Barcode value accepts literal text, data/parameter bindings and expressions such as {{= concat(parameters.portal, data.id) }}. Inside repeat, data is the current record.
  3. Module width (pt) 1–4 controls physical size. Matrix dimensions/height are automatic. Barcode height is hidden for 2D and retained only for switching back to a 1D code. A QR has a four-module white quiet zone; Data Matrix has one. Keep these zones clear.
  4. QR error correction offers L/M/Q/H, default M. Higher correction may increase size. Data Matrix uses square ECC200 with no configurable correction. Show text wraps the payload below the square; Text size affects only its caption. Hide text for long payloads or characters unavailable in the report font.
  5. Run with parameters → change Portal URL, generate and check both pages. Undo/Redo and Save project preserve settings. Export PDF or HTML; all outputs use the same vector modules. URLs are encoded, never opened. Data remains unchanged.
  6. Print without clipping or distorting proportions and check a real scan at the final size. Automated checks decode PDF rasters at 150/300 dpi; your printer/scanner still needs an on-site check.

UTF-8 up to 512 bytes after binding; bytes are not character counts. Whitespace-only values, invalid Unicode and controls other than tab/CR/LF fail; surrounding spaces are preserved. The whole square and caption must fit one page and move together on overflow. Reduce module/font size, hide the caption or enlarge the page when needed. Caption wrapping never alters encoded bytes. Only Flow, including repeated sections; no Fixed, table-cell symbols, GS1/FNC1, logos, colors/inversion, structured append, rectangular Data Matrix or DMRE. No automatic Wi-Fi/payment payload construction.

Repeated report sections

  1. Open samples/repeated-sections.nrtemplate with repeated-sections.data.json. Generate preview produces two order packs: SO-101/North totals 281.30, SO-102/South totals 80.00. Each has its own image, text, table, chart, barcode and notes.
  2. Select Insert → Repeat section. Set Repeat source to an array of objects, such as orders. Replace the initial Section text with your own content.
  3. Select Edit section. The sheet/tree now show this section's children. Insert/edit/reorder/duplicate/delete ordinary blocks using the existing tools. Undo/Redo works within sections; positioning is Flow only.
  4. Inside, {{data.id}} reads the current record, {{root.company}} reads global report data and {{parent.id}} reads the enclosing record. At the top repeat level, parent is the root. Dictionary shows Current record, Root and Parent fields using the first record as a sample. Enter paths manually for empty arrays.
  5. Child table/chart sources are relative to the current record, e.g. lines. Table row formulas/filters refer to each child row and totals restart per record. Insert another Repeat section for notes; up to three repeat levels are supported.
  6. Use the navigation above the ribbon to return to an ancestor or Report. New page between records starts subsequent records on new pages. Space after applies after every record. A Page break before the section also separates its first record.
  7. Generate preview and Save template/Save project always operate on the complete report. Check every page and export PDF/HTML. Source data remains unchanged.

Limits: 1,000 template blocks including descendants, 10,000 repeated records across all sections, 100,000 rendered block instances, 10,000 pages. Sources must be arrays of objects; empty arrays emit nothing. Each section must contain a block. Global page headers/footers always use root data and global numbering. Tables may paginate and repeat their column headers; ordinary section headings do not repeat automatically. No keep-together, per-section page settings/numbering, Fixed children or external template references. All sections share parameters/images and scripts run once for the report.

Master-detail tables

  1. Prepare nested data, for example {"orders":[{"id":"SO-101","customer":"North","lines":[{"item":"Monitor","quantity":2,"price":125.5}]}]}.
  2. Select Table → Properties and Flow positioning. Set Master source to orders (relative to the current data context) and Data source to lines (inside each parent).
  3. Set Master header to Order {{master.id}} · {{master.customer}}. Current-context {{data.path}}, report-root {{root.path}} and {{parameters.name}} are also supported. Empty hides the heading; default is Details.
  4. Configure columns using child fields. A calculated amount can use round(row.quantity * row.price, 2), F2 and Sum. Generate preview and export PDF.

Each parent gets a separate table in source order. Filters, sorting, grouping, expressions and aggregates apply independently to its children. Grand total means this parent's total, not the total of all parents. Space after separates parent tables and follows the block. Parent/column/active group headings repeat on page breaks and stay with the first row fragment. Empty child arrays (including fully filtered results) retain headings and standard empty totals; an empty parent array creates no tables.

Suggestions and Add source fields sample child data from the first 100 parents/rows. Enter fields manually when arrays are empty. Settings support Undo/Redo and template/project saving. Clear Master source and set a root-relative Data source to restore a normal table; the saved Master header is then ignored.

Try samples/master-detail.nrtemplate with samples/master-detail.data.json: SO-101/North has Monitor 251.00, Cable 30.30, total 281.30; SO-102/South has Desk and total 80.00; empty SO-103/East has total 0.00.

One parent-to-child level, Flow only. No Fixed master tables, arbitrary nested blocks, joins, cross-parent totals or master references in column expressions/ordinary Text. Prepare such shared data in beforeRender. Parents must be objects and every child source an array: use [] rather than null. Missing child arrays/header fields fail generation. Maximum 10,000 parents, 100,000 combined child rows before filtering and 10,000 header characters. A heading that leaves no room for table content fails generation; shorten it or reduce the font.

Calculated columns

  1. Select Table → Properties, add or select a column and enter its Title.
  2. Set Expression to round(row.quantity * row.price * (1 - parameters.discount), 2). Declare discount as a Number parameter with default 0.1. Row fields must contain JSON numbers.
  3. Choose Number format F2, Alignment right and Aggregate Sum. Generate preview, then export PDF.
  4. Use Run parameters to change discount and generate again. Expressions support Undo/Redo and saved templates/projects.

Expression overrides Field. Clear Expression to use Field again; set a valid field if it is empty. Formulas leave source JSON unchanged. Filters, sorting and grouping still use source fields. Expressions cannot refer to another calculated column; prepare shared values in beforeRender when needed.

SyntaxMeaning
row.quantity, row.product.priceNumeric field of the current row
parameters.discountDeclared Number parameter, current/default value
+ - * / %, parentheses, unary signsDecimal arithmetic; multiplication/division/remainder precede addition/subtraction
abs(x), min(a,b), max(a,b)Absolute value, minimum, maximum
round(x,digits)0–6 decimal places; midpoint away from zero (1.005 → 1.01 at 2 places)

Names are case-sensitive. Row path parts start with an ASCII letter or underscore, followed by letters/digits/underscores. Use decimal literals with a dot; exponent notation such as 1e3 is not supported. Maximum 512 characters, 128 nodes and 32 nesting levels. Comparisons, numeric logic, if/coalesce/isNull and null are supported (see below). No strings, dates, JSON booleans, arrays, aggregate references or JavaScript. Numeric expressions do not require TypeScript or scripting to be enabled.

Missing/non-numeric values, unhandled null, division by zero and overflow fail generation. Syntax is validated even for an empty source; value errors are checked on rows surviving the table filter. Sum/Average/Min/Max use calculated values, Count counts rows. Formatting happens after calculation; use round inside the expression to round each row before summing. Pagination never multiplies totals.

Try samples/calculated-columns.nrtemplate with samples/calculated-columns.data.json: discount 0.1 gives Monitor 225.90, Cable 27.27, North 253.17, Desk/South 72.00 and grand total 325.17. Discount 0.2 gives 289.04. Check Preview and PDF.

Calculations and conditional cell styling

  1. Open samples/conditional-table.nrtemplate with samples/conditional-table.data.json. The report calculates volume discounts, handles null cost as zero, guards division by zero and colors the relevant data cells. Defaults: threshold 2, discount 0.1; net total 333.17, margin 38.17.
  2. Select a table column in Design. Expression accepts comparisons == != > >= < <=, numeric logic && || !, if(test,yes,no), coalesce(value,fallback), isNull(value) and null. A test uses 0 for false and any nonzero number for true; comparisons/logic return 0 or 1. JSON booleans and strings are not converted.
  3. Example: if(row.quantity == 0, 0, row.amount / row.quantity). Only the chosen branch executes. AND/OR short-circuit; coalesce evaluates its fallback only for null. Missing fields and invalid types still fail when accessed; coalesce is not an error handler. All branches are syntax-checked even on empty data.
  4. Click Add style rule on a column. Set When with the same language, for example row.margin < 0. Choose text color/background overrides; keep at least one enabled. Default When = 1 matches every row. Rules can refer to source numeric fields/number parameters, not another calculated column.
  5. The first matching rule wins as a whole; later rules do not add colors. Move rule up changes priority; Remove rule deletes it. Unspecified colors retain the table text/stripe settings. Only data cells change: headings/subtotals/grand totals keep their styles. Every fragment of a split row keeps the same colors.
  6. Generate preview, change threshold via Run parameters, save/reopen the project and export PDF/HTML. Threshold 3 gives net total 358.27. Undo/Redo includes formulas, rule edits and priority; source JSON stays unchanged.

Precedence, highest first: unary + - !, * / %, + -, one comparison, &&, ||. Parenthesize combined comparisons; chained a < b < c is invalid. Equality permits null (null == null is 1); ordering/arithmetic and logical tests require numbers. Formula results and When must be non-null numbers. Limits: 512 characters, 128 nodes, 32 levels per expression; 10 rules per column, 100 per table. Rule colors do not change font size, wrapping or calculations. Flow, Fixed and master-detail tables are supported. Rules do not apply to cross-tabs or charts.

Nested groups

  1. Set Group by to customer. Click Add group field and set Group field to order. Check the suggested field before generating.
  2. Additional levels run outer to inner. Outer / Inner reorder additional fields; Group by stays first. Clear Group by and use only additional fields to reorder every level.
  3. Choose column aggregates, then Generate preview. Group subtotals applies to every level; Grand total is independent.

Try samples/nested-groups.nrtemplate with samples/nested-groups.data.json: North A 125.00, B 40.00, North 165.00; South A 80.00, B 10.00, South 90.00; grand total 10 / 255.00. Equal order keys under different customers remain separate. Parent Average uses original rows, never child averages.

At most three distinct fields total are allowed. Duplicate fields, missing keys and non-scalar keys fail generation. Remove group or clearing Group field removes that level. Clear grouping removes all levels while retaining aggregate settings. Undo/Redo and saved projects preserve these changes. All active ancestor headings repeat on page breaks; closed child groups do not repeat before a parent subtotal. Check Preview/PDF; Fixed tables must fit their frame. This groups one flat array; use Master source for separate child arrays.

Try the repository samples/grouped-orders.nrtemplate with grouped-orders.data.json: North 5 / 200.00, South 5 / 100.00, East 3 / 10.30; grand total 13 / 310.30. Column and active group headings repeat across pages; a group heading stays with the first row or its first fragment. Total captions stay with values. Verify Preview/PDF, since Design shows structure rather than final pagination. Up to three grouping levels and numeric column expressions are available.

Average computes the decimal sum divided by the original row count, including for the grand total; it does not average group averages. Intermediate sum overflow is an error. Min/Max return the lowest/highest number without summing. Count counts all rows, including null and strings, not distinct or non-null values. The column field must still exist for row rendering. Leave Number format blank for textual columns with Count, since formats also apply to detail cells.

Choose one aggregate per column; duplicate a column and change its Title/Aggregate to show several. In the grouped-orders example, Amount Average gives North 100.00, South 50.00, East 5.15 and grand 51.72. Min gives 74.50 / 20.00 / 0.20, grand 0.20; Max gives 125.50 / 80.00 / 10.10, grand 125.50. Item Count gives 2 / 2 / 2, grand 6. Try Undo/Redo and save/reopen the project. Legacy sum templates show Sum in the selector; changing it replaces the old setting.

Flow versus fixed

Flow blocks follow each other and paginate; use flow for variable-length lists. Fixed gives X/Y/Width/Height relative to the current page's content area. Fixed blocks do not advance the flow and can overlap other blocks. A fixed text/table must fit its height or generation fails. Drag/resize uses a 2 pt grid; arrow movement is 1 pt or 10 pt with Shift. Layout alignment uses the content area inside page margins. Inspect final layout in Preview and PDF, not just the design sheet.

Images and breaks

Insert Image and use Upload image in Properties for PNG/JPEG up to 4 MB. Resources are embedded, keep their proportions, and travel with the template. Choose Resource to reuse an existing image. External image URLs are not fetched. Page break starts another page; leading, consecutive or trailing breaks do not create empty pages.

6. Parameters and input controls

Page → Parameters defines Name, Type, Required, Use default and Default value. Names start with a letter and then use letters, digits or underscore. Existing names stay fixed; to rename, create a replacement and update all bindings/code before removing the old definition. Apply parameters is one template Undo step; Cancel discards the draft.

Label changes the caption; Help text explains the field. A definition is not the value entered for one run. Zero and false are valid values. Use defaults for fields that must already have a usable value when opened.

Type / controlConfiguration
string / Automatic, Multiline TextBoxText; multiline is string-only.
number / AutomaticOptional minimum and maximum.
number / TrackBarRequires finite minimum < maximum. Numeric readout follows manual and scripted changes.
boolean / AutomaticCheckBox.
string / ComboBox, ListBox, RadioButton groupOptions, one exact value per line; up to 200 unique nonblank values, each at most 500 characters.
string[] / CheckedListBoxMultiple choices. Default value is a JSON array, for example ["North"].
string / Date, Time, DateTimePickerYYYY-MM-DD, HH:mm[:ss], YYYY-MM-DDTHH:mm[:ss]; no timezone conversion.
string / ColorPicker#RRGGBB.
string / MaskedTextBoxMask: 0 = digit, L = ASCII letter, A = either. LL-000 changes AB123 to AB-123 on blur or Generate. API input must already include literals.
string / PasswordBoxObscures input only; values are ordinary report parameters and may be saved in projects.

Choice matching is case-sensitive, including spaces. Required empty choices still fail generation. Changing a control does not change its underlying value type. Recheck defaults after changing type/options. Dependent choices are supported through dialog events.

7. Preview and PDF

Generate preview calculates SVG pages. Use Pages thumbnails, page number, Previous/Next, Fit width, Fit page, zoom and Find text / Find next. The design sheet shows structure; Preview shows actual row content and pagination.

Edits mark Preview as Previous version. Export PDF and Open PDF use the last successful preview request, not an ungenerated draft. Failed generation leaves the previous successful document available. Export runs scripts again, so use deterministic logic; provide dates or random seeds as input instead of changing them inside handlers.

Choose File name in the Parameters sidebar, export and inspect the PDF before printing or sharing. SVG and PDF share layout/fonts, but small rasterization differences are possible.

8. Design a parameter dialog

  1. Define parameters, then open Dialogs → Create form. Automatic initial layout supports up to 12 parameters.
  2. Select Form to edit title and dimensions. Click or drag Toolbox controls onto the canvas or a container.
  3. Use Properties to edit Caption, binding, Parent, geometry, Anchors and Actions. Document outline selects nested components.
  4. Use Preview form to test appearance without scripts or generation. Use Run with parameters to test actual events and validation.
  5. Save the template/project. Remove form removes layout only, preserving parameters.

A field reuses a compatible unplaced parameter or creates an optional parameterN. Only one component may bind to a given parameter. A custom form shows only placed fields; unplaced parameters keep current/default values and still undergo server validation. Without a custom form, all parameters receive generated inputs.

Drag on an 8 px grid; resize using handles or numeric properties. Parent may be Panel, GroupBox or TabPage. Align commands use the parent boundary. Earlier/Later changes sibling order, keyboard order and small-screen stacking. Containers move with their descendants. Left+Right anchors stretch width, Right alone keeps the trailing gap; Top/Bottom act similarly. Resizes that violate child bounds/minimum sizes are rejected. Narrow runtime layouts stack controls without rewriting saved geometry.

Copy and delete

Right-click or Shift+F10 opens the context menu. Copy/Cut/Paste includes descendants. Copy creates independent parameters; Cut reuses free unchanged bindings when possible. Pasting requires sufficient space and a suitable parent; a failed paste changes nothing and preserves the clipboard. Event code/source paths are not rewritten, so review IDs after duplication. The private clipboard is cleared when another report is opened and does not access the operating-system clipboard. Delete removes a container and its children but preserves parameter definitions; Undo restores layout.

Runtime draft

Cancel discards values, dynamic options and component state. Generate validates and commits values only on success. Reset restores defaults and runs Load again. Hidden/disabled parameters still undergo report validation. While an event runs, fields/Generate are locked, but Cancel remains available. A closed dialog ignores a late response. After Changed, lost focus returns to the edited field or surviving choice unless the user already focused another control.

9. Build a two-step form

  1. Define company (string) and quantity (number). Create a form with enough space, for example 800 × 600 px.
  2. Insert TabControl, which creates two pages. Set their captions to Company and Quantity.
  3. Assign the existing company field's Parent to the first TabPage and quantity to the second. Position both inside their page bounds.
  4. Insert a Button on the first page, set Action to next and Text to Next. On the second page insert a Button with Action back, Text Back.
  5. Preview form to check layout. Then Run with parameters: empty a required field and press Next; it must stay visible and receive focus. Fill it and continue. Back does not require the current page to be complete.
  6. Enable Sequential steps on TabControl if future headers must be blocked. Next advances one page; going back blocks forward headers again.
  7. Generate and save the project.

Next/Back must have a TabPage ancestor and navigate the nearest TabControl. At boundaries they are disabled. TabPage adds another page to the selected TabControl; Caption names it and Earlier/Later changes order. Nested TabControls are allowed.

Successful navigation focuses the selected header, allowing arrow-key continuation. Next validates current-page browser constraints. Generate independently validates all report parameters, revealing an invalid page. Preview form skips validation and scripts. Sequential navigation is not a security boundary or a replacement for final validation.

10. Toolbox reference

Search the grouped Toolbox. Choose Edit parameter / options to configure a field's definition. Containers can contain children; display controls do not create parameter values.

ToolsUse / settings
LabelStatic caption.
TextBox, Multiline TextBox, MaskedTextBox, PasswordBoxString controls; see parameter formats above.
NumericUpDown, TrackBarNumber input and range slider.
CheckBox, ComboBox, ListBox, RadioButton group, CheckedListBox, ColorPickerBoolean, single/multiple choice and color.
DateTimePicker · Date, TimePicker, DateTimePickerDate/time string controls.
Panel, GroupBox, TabControl, TabPageGrouping and page navigation.
Button · Custom / Generate / Reset / CancelAction custom/submit/reset/cancel; ordinary Button properties also offer next/back.
LinkLabelExplicitly activated http, https or mailto link.
PictureBoxSelect an embedded image resource added through report Insert Image.
ProgressBarValue 0–100 or numeric Source from data; not an asynchronous job-progress API.
SeparatorVisual separation.
DataGridViewRead-only Source array, up to 100 rows and 20 columns.
TreeViewRead-only dotted Source or whole data object; up to 200 entries and six levels.

11. Code and report events

Code is optional. Open Design → Page → Code or Dialogs → Code. Insert event creates a typed starter. Check code validates TypeScript on the server; Apply code saves the draft in the template; Cancel discards edits. Apply can save invalid code, so always Check code and then exercise actual input. Monaco offers completion, hover, search and diagnostics. Reopen or Check code after changing definitions/data to refresh types.

Execution must be enabled by the host for trusted templates. On Linux/macOS, a local launch can use:

Bash
NEXTGEN_ENABLE_SCRIPTS=1 NEXTGEN_NODE=/absolute/path/to/node \
  dotnet run --project src/NextgenReports.Studio --urls http://127.0.0.1:5274

On Windows PowerShell set $env:NEXTGEN_ENABLE_SCRIPTS="1" and $env:NEXTGEN_NODE="C:\path\to\node.exe" before the dotnet run command. This is configuration guidance, not a claim of current Windows verification.

EventWhen / result
validateParameters(ctx: ReportContext)After type/default checks; return ValidationError[].
beforeRender(ctx: ReportContext)After validation; return a new JsonObject used for layout.
afterRender(ctx: AfterRenderContext)After layout; return void or throw to reject the result.

Example: first define required numeric minimumQuantity with default 3 and the items data from the exercise. Add Text Selected items: {{data.selectedCount}}. Then use:

TypeScript
export function validateParameters(ctx: ReportContext): ValidationError[] {
  return ctx.parameters.minimumQuantity < 0
    ? [{parameter: "minimumQuantity", message: "Enter zero or greater."}] : [];
}
export function beforeRender(ctx: ReportContext): JsonObject {
  const items = ctx.data.items.filter(item => item.quantity >= ctx.parameters.minimumQuantity);
  return {...ctx.data, items, selectedCount: items.length};
}
export function afterRender(ctx: AfterRenderContext): void {
  if (ctx.result.pageCount > 10) throw new Error("Narrow the selection.");
}

At 3, expect Monitor and Chair, with Selected items: 2. At -1, expect a field error. The existing inventory sample contains a runnable version. beforeRender does not overwrite the original Data JSON. afterRender can inspect title/pageCount, not edit completed pages.

Handlers are named synchronous exports; helper functions must not be exported. Context is read-only; return patches/new data. No imports, async, DOM, Node, filesystem, network or CLR APIs are exposed to scripts. Use deterministic data transformations. Interpreter limits are not a sandbox for untrusted public workloads.

12. Dialog events and dependent choices

Properties → Events opens the relevant handler for the selected object. Existing handlers are shared across the report and are selected without being rewritten. Add a branch for the selected ID/name; do not create a second same-name function.

Object / eventContext / return
Form → Load / dialogLoadDialogContext → DialogUpdate; open/Reset.
Field → Changed / parameterChangedParameterChangedContext → DialogUpdate; ctx.parameter names the parameter.
Custom button → Click / dialogButtonClickDialogButtonContext → DialogUpdate; ctx.componentId names the button.
TabPage → Page changing / dialogPageChangingDialogPageChangingContext → DialogNavigationResult; previousComponentId is the source, componentId the destination.
TabPage → Page changed / dialogPageChangedDialogPageContext → DialogUpdate; componentId names the newly selected page.

DialogUpdate supports parameters (new values), options (choices keyed by parameter), components (visible/enabled keyed by component ID), and message. Missing properties preserve state. Invalid responses are rejected atomically. Each event gets a fresh execution environment. Changed uses the browser change event, not every keystroke; programmatic patches do not recursively trigger it.

Dependent choices example

Define string ComboBox parameters country with options Ukraine/Poland and default Ukraine, and city with options Kyiv/Lviv and default Kyiv. Place both on the form. Insert:

TypeScript
function cityChoices(country: string): string[] {
  return country === "Poland" ? ["Warsaw", "Krakow"] : ["Kyiv", "Lviv"];
}
export function dialogLoad(ctx: DialogContext): DialogUpdate {
  return {options: {city: cityChoices(ctx.parameters.country)}};
}
export function parameterChanged(ctx: ParameterChangedContext): DialogUpdate {
  if (ctx.parameter !== "country") return {};
  const choices = cityChoices(ctx.parameters.country);
  return {options: {city: choices}, parameters: {city: choices[0]}};
}

Check/Apply, Run with parameters, choose Poland: city becomes Warsaw. Cancel discards the draft; successful Generate retains effective choices for preview/PDF and saved projects. Save template keeps the design's original choices. Without an explicit selected value, valid old choices survive and removed choices clear. Empty options do not waive Required. Changing report data/template invalidates committed dynamic choices.

Buttons and state

Custom Click updates the draft without submitting. Test ctx.componentId to distinguish buttons. Return {components: {detailsPanel: {visible: false}}} only if that unique component exists. State propagates through containers; individual TabPage state patches are not supported. Hidden/disabled values remain subject to final report validation.

Cancel a transition

Define string parameter approval, and use destination page ID confirmation:

TypeScript
export function dialogPageChanging(ctx: DialogPageChangingContext): DialogNavigationResult {
  if (ctx.componentId === "confirmation" && ctx.parameters.approval !== "yes")
    return {cancel: true, message: "Approval is required."};
  return {};
}

Order: Next browser validation → Page changing → transition → Page changed. A veto preserves the page and values. Navigation results accept only cancel/message, not updates; use Page changed for updates after arrival. Initial selection, validation-error reveals and Preview form skip page events. An event exception blocks Generate until a successful event or reopen; an ordinary veto is not an exception. Closing a pending form prevents a late transition. Generate always performs final validation independently.

13. Keyboard reference

WhereKeysAction
Design block/treeCtrl/Command+D; Delete/BackspaceDuplicate; delete.
Design / DialogsCtrl/Command+Z; Ctrl/Command+Shift+Z or Ctrl+YUndo; redo.
Fixed block handleArrows / Shift+arrowsMove 1 pt / 10 pt.
Dialog componentArrows / Shift+arrowsMove 1 px / 8 px.
Dialog componentCtrl/Command+C, X, V, DCopy, cut, paste, duplicate.
Dialog designerShift+F10 / EscapeOpen / close context menu.
Input formTab / Shift+TabNext / previous available control.
TabPage headerLeft/Right, Home/EndNavigate allowed pages.

Text fields keep normal editing shortcuts; template shortcuts do not intercept text editing. Command describes macOS conventions, not current platform test coverage.

14. Troubleshooting

ProblemWhat to do
Old Preview/PDFGenerate successfully after changes. Export uses the last successful request.
Invalid JSONCheck quotes, commas and braces. Data and template are separate JSON objects.
Missing/unknown fieldCheck path/case. A table column path is relative to its row.
Empty tableCheck Source is an array and beforeRender did not remove rows. Inspector search does not filter the report.
Content/frame overflowIncrease space, reduce content/font or use flow. Check margins and fixed coordinates.
Missing dialog fieldPlace a bound control; check Parent, active tab and visible state. Unplaced parameters are not auto-added.
Hidden required value blocks GenerateSupply a valid value/default or change the requirement. Hiding is not validation bypass.
Invalid choice/maskCheck exact options and formatted mask literals; checked lists require arrays.
Next or header unavailableCheck current fields, page boundaries, Sequential steps and Page changing. Next/Back belong inside TabPage.
No events in Preview formUse Run with parameters; design preview intentionally skips scripts.
Scripts disabled / Node missingEnable trusted scripts in the host and set NEXTGEN_NODE to the executable.
Code errorCheck code, fix diagnostics, Apply, then test actual data. Apply alone does not prove execution.
Event error blocks GenerateFix the error and run a successful event, or reopen. Cancel loses the private draft.
Report changed while dialog openClose and reopen using the current report; do not apply a stale draft.
Paste or resize rejectedCheck parent, bounds and component limits. Failed insertion preserves the clipboard.
Undo does not restore dataRestore from saved project/JSON; Undo stores template states only.
Edits disappeared after reloadOpen a saved project. Unsaved browser state is not persistent storage.

For unresolved issues, keep a copy of the project, the exact error and reproduction steps using fictional data. Work on a copy rather than deleting your original.

15. Limits and terminology

Practical limits: 8 MB project/JSON uploads, 4 MB image upload, 100 dialog components, 12 parameters for automatic Create form, 50 table columns. Large datasets/layouts have additional engine limits. Latin and Cyrillic use embedded DejaVu Sans; full RTL/CJK/emoji shaping and font fallback are not implemented.

No MRT import, SSO/per-report ACLs, debugger or printed-block/page events. CSV/XLSX import, HTTP/SQL/JSON/object sources and Word/Excel export are available as described below. TabPage events concern input forms, not printed pages. All/Any filtering and sorting by up to five fields are available in Table Properties; advanced sorting/filtering is available through beforeRender. A .NET HTTP client and Blazor Interactive Server viewer are available. A Flutter/Dart SDK is also available. Desktop shells and WebAssembly/Auto remain future work.

Current interface checks run on the local iMac/Linux in visible Chrome. macOS and Windows require separate verification; cross-platform design is not proof of a test run.

Template
The report rules: layout, definitions, resources, dialog and code.
Project
Template plus input data and parameter values.
Binding
A path connecting printed content or a field to data/parameters.
Block / component
A printed report element / an input-dialog element.
Draft
Uncommitted values or edits inside an open dialog.
Handler
A TypeScript function called for a supported event.

Further references, when online: Russian learning path, report authoring, scripting contracts, Toolbox details, template format. These files are also in the local repository's docs folder.

Back to start · Open the installed Studio to edit your report.

Check template and fix issues

Click Check template below the workspace. The inspector uses the engine's static rules and lists the first error in each invalid block. Click a zero-based path such as blocks[1].blocks[0] to open that block's properties, including nested repeat sections. Correct its settings and check again. Editing, Undo/Redo or replacing the template hides stale results.

Malformed blocks that cannot be opened in the designer fall back to the JSON editor. For JSON or report-wide errors, click Open template JSON and fix the reported problem first. Report-wide failures stop block checks; additional errors in the same block may appear after its first error is fixed.

No static issues does not guarantee that a report will render. Checks do not run scripts, require data/parameter values or replace Preview. Use the logic editor to check TypeScript and Generate to validate actual data, runtime expressions, parameters and pagination.

Import Excel worksheets

  1. Open Data → Import data, select an .xlsx file (up to 4 MB), choose Worksheet and a Table name. Hidden sheets are marked. Try samples/import/inventory.xlsx, Items, table items and Infer columns.
  2. Preview and review names/types, ISO dates and warnings. Keep all text is the default; column overrides work as for CSV. Changing sheet/options requires another Preview. Delimiter does not apply.
  3. Apply import preserves other data; replacing an array requires Replace existing table. Undo import restores the last unchanged import. Save the project to keep rows. Use samples/import/inventory.nrtemplate and Generate, then export PDF.

Formulas are rejected unless Use cached formula values is explicitly enabled. Recalculate and save the workbook first. Cached results may be stale; no formulas/macros/external links are run. Missing caches and Excel errors fail. The sample Summary sheet has an explicitly prepared result of 187.7.

First nonempty row supplies headers. Empty rows are skipped; hidden/filtered rows and columns are included. Sparse cells become empty values. Merged cells must be unmerged. Import reads values, not fonts, currency/percent symbols, display rounding or numeric zero-padding; store identifiers as text.

Recognized Excel dates use ISO strings (1900/1904 systems; built-in formats 14–22, 45, 47 or custom y/d/h/s tokens). Unknown formats remain numeric. Negative/out-of-range dates, fictitious 1900-02-29 and elapsed time [h]/[m]/[s] fail. Date-only output is yyyy-MM-dd; time-only HH:mm:ss with optional milliseconds; combined output joins them with T. Convert unsupported dates/durations to explicit text or numbers first.

Only transitional .xlsx: no .xls/.xlsm/.xlsb, encrypted files, strict OOXML, named ranges or live refresh. Limits: 100 sheets, columns A–AX, 10,000 data rows, 200,000 cells, 64,000 characters per field, 6 MB imported JSON and 8 MB project. ZIP limits: 1,024 parts, 16 MB per part and 32 MB expanded total. Numeric values beyond decimal range/precision fail; inference still limits JSON numbers to 15 digits.

Export page images

  1. Generate preview, then open Preview → Export images.
  2. Choose PNG at 72, 150 or 300 DPI, or vector SVG. DPI changes pixel size, not pagination; it is disabled for SVG.
  3. Choose All pages, Current page or an inclusive Page range (starting at 1). Current uses the viewer page selected when the dialog opens.
  4. Keep Always package as ZIP checked for an archive. Uncheck it to download a single selected page directly. Multiple pages always use ZIP. Click Download.

ZIP entries preserve original page numbers: page-0002.png, page-0003.png, etc. Export uses the last generated request, including parameters, even if editors contain unfinished changes. Like PDF/HTML it renders that request again; nondeterministic scripts can produce new values. Save the project separately to retain editable source.

Pages have white backgrounds. PNG includes DPI metadata; dimensions are ceil(points × DPI / 72): A4 portrait is 1241 × 1754px at 150 DPI. SVG embeds images and outlines text, so no installed fonts or network are needed. Text in these images is not selectable/searchable; use PDF/HTML for text access. For barcodes, prefer 150–300 DPI and adequate module width; a one-pixel module may require magnification.

Limits: 100 selected pages, 25 million pixels per PNG page / 100 million per export, 25 MB per SVG and 100 MB ZIP. Lower DPI or select fewer pages when needed. Linux on iMac is verified; macOS, Windows and physical printing remain unverified.

Excel and Word export

  1. Generate preview, then choose Export Office.
  2. Select Excel (.xlsx) or Word (.docx).
  3. Editable text exports displayed text into cells/tables. Values remain strings, including leading zeros and text starting with “=”; formulas and source types are not recreated. Convert cells to numbers in Excel when calculations are needed. Wrapped lines and repeated headers/footers remain. Word keeps basic text formatting; Excel uses default cell styles. Graphics, charts, barcodes, fills and lines are omitted. Word may reflow onto additional pages.
  4. Page images (exact layout) embeds each complete page as PNG in a worksheet/document page. Every visual is retained, but text is not editable or searchable. Choose 72, 150 or 300 DPI; DPI is disabled for editable text.
  5. Choose All pages, Current page or an inclusive Page range, then Download. Current page is captured when the dialog opens. Cancel leaves the report unchanged.

Export uses the last generated request, even with unfinished editor changes. Scripts run again. Save the project separately. Excel names worksheets “Page N” and fits each sheet on one printed page. A3/A4/A5/Letter/Legal use standard paper; custom sizes print fitted to A4. Use PDF for exact print scale. Editable mode is a layout-text export, not a source-data table; an image-only page has no editable text.

Limits: 100 pages, maximum side 1584 pt, 100 MB file; page images 25 million pixels/page and 100 million total; editable text 100,000 fragments, 5 million characters, 32,767 characters/fragment or Excel cell, 256 text columns/page. Reduce the range or DPI after an error; the dialog stays open. Fonts in editable Word are not embedded and may be substituted.

CLI: report-tool.py --format xlsx|docx --office-mode editable|pages, with --first-page, --last-page and --dpi. Output must end in .xlsx/.docx. Standalone .NET CLI: .xlsx/.docx for text; .pages.xlsx/.pages.docx for all page images at 150 DPI. API: POST /api/export/office with template/data/parameters and options format, mode, firstPage, lastPage, dpi. Native Microsoft Office, macOS and Windows remain unverified.

Row drill-down

Download Interactive orders project. Save your work first, open the downloaded project, then click an order row and a detail line. The sample uses fictional data and no scripts.

  1. Select a Table in Design and choose Add row drill-down / Edit row drill-down.
  2. Set an action label and paste/import a complete v1 detail template (.nrtemplate/.json, up to 2 MB). You can create the detail visually in a separate project, export its template, then import it here.
  3. Use {{data.row.id}} for the selected record and row.lines as a child table source. data.source is the parent's complete data after beforeRender, not an enclosing master/repeat record. At the next level data.source.row.id addresses the previous selected row.
  4. Apply validates structure before changing the parent. Runtime binding/parameter errors appear when opening an actual row. Cancel discards edits; Remove drill-down removes only the action. Apply/remove support Undo/Redo.
  5. Generate preview and click a highlighted row, or focus with Tab and press Enter/Space. Back restores the parent's cached page, zoom, search and scroll without rerunning it.
  6. Exports use the currently displayed report and remain static. Save project preserves the root and embedded detail templates; source editors still contain the root project. Successful Generate or project load resets navigation. A failed detail keeps the parent intact.

Matching parent parameters are inherited; other detail parameters use defaults/required validation. Detail parameter dialogs do not run automatically. Row values are not mapped into parameters. The parent script is not rerun on navigation; child scripts use the host's existing opt-in. Exports rerun the displayed request, so time/random-dependent scripts may change values.

Supported: ordinary Flow/Fixed tables, filters/sorting/groups, master-detail child rows and tables inside repeat. Split fragments open the same record. Headers, totals, charts and cross-tabs have no actions. Calculated display fields do not become row fields. Three detail levels, 10,000 interactive records and 8 MB serialized row data per generated report; existing request/template/page limits also apply. Preview JSON carries complete source records/data. Use static exports when only rendered content is intended. No forward/URL navigation or history across reloads. Child templates keep their own page settings and resources.

CLI: report-tool.py --drill-row 13 --drill-row 1 --format pdf selects 1-based interactive rows in render order, up to three levels. --format project saves the final detail as a separate project; Studio Save project keeps the root. API clients use the optional Preview drillDown targets/rows/regions/source/parameters to build another ordinary preview request. macOS and Windows remain unverified.

Prepare data: derived tables

In Data, choose Prepare data → Add table. Set a new Output table name and Source array (raw data or an earlier output). Add All/Any filters, stable sorts, then output columns: copy fields or calculate decimal expressions such as row.quantity * row.price. Without columns, complete records are retained.

For summaries, enter up to three comma-separated Group fields and columns for keys and Sum/Average/Min/Max/Count. Count counts rows without a field; other aggregates require numbers. Use another derived table to filter calculated values or sort totals. Rules run in declaration order; Move up/down changes it. Existing data cannot be overwritten.

Preview data displays up to 20 rows per result. Apply rules saves only successfully previewed rules; Cancel discards changes. Undo/Redo restores rules. Point a report Table/Chart Data source at the output name and Generate preview. The ordinary Data view/dictionary stays raw; generated fields may require manual entry. Save project keeps raw data plus rules.

Preparation runs after parameter normalization and before scripts on every generation/export. Data preview never runs scripts/layout. Empty global summaries return count/sum 0 and other aggregates null; empty grouped results have no rows. Numeric keys 1 and 1.0 share a group; text "1" is distinct. Null handling for numeric expressions is explicit with coalesce.

Limits: 20 tables, 10,000 input rows/table, 100,000 total input rows, 50 columns, 3 group keys, 8 MB prepared data. Filtering does not bypass input limits. No joins or nested filter groups. Use Connections for SQL/HTTP/JSON/object refresh before preparation. Output names are new identifiers; source paths use dotted identifiers. Errors preserve saved rules and source data.

Prepared sales project: Open project and generate. At minimum 10, West=120.00, East=70.00, total=190.00. At minimum 60 only West remains. Inspect sales → qualified → regional → ranked in Prepare data. API: POST /api/data/prepare with template/data/parameters returns computed data; CLI --format prepared-data writes this response without scripts/layout.

HTTP sources and snapshot refresh

Data → Connections selects a host-configured source, target root array and JSON response path (empty for a root array). Bind allowed query names to report parameter names. Save connections saves IDs/bindings only, without a network request; Undo/Redo restores definitions. Host URLs and authentication headers are never saved in projects.

Refresh sources fetches all connections into a preview. Cancel keeps current data (and aborts an in-flight request); Apply snapshot replaces target arrays while preserving neighboring fields. Generate preview then recalculates derived tables/scripts and report pages. Undo refresh restores the previous data if unchanged since Apply. Errors never apply partial snapshots.

Save project retains connections and the last applied snapshot. Opening stays offline. Generation uses the saved snapshot unless an HTTP connection enables refresh before generation; Studio exports reuse the displayed snapshot. The ordinary .NET CLI is offline; Python report-tool.py --refresh explicitly refreshes before generation, while --format refreshed-data writes the response envelope only.

Refresh before generation

  1. In Connections, enable Refresh HTTP data before each generation and save. Generate preview fetches all opted-in HTTP sources/pages before report preparation and layout.
  2. On success, the Data snapshot and preview update together. On failure, both retain their previous content. Other sources stay unchanged. A successful automatic refresh clears the old Undo refresh entry.
  3. Export PDF/HTML/images/Excel/Word from Studio: it uses the displayed snapshot without fetching again. Save project retains the new data; Open project/Library and drill-down remain offline. Turn the option off for offline generation.

API preview adds sourceSnapshot on automatic refresh. Submit it as data with useSnapshot:true for matching exports. Other API requests fetch independently; direct engine/CLI remain offline. Schedules honor connection-level refresh even with global Refresh off; global Refresh fetches every connection once. Details: automatic refresh.

Host setup: set NEXTGEN_HTTP_SOURCES to a private JSON catalog before starting Studio. Each entry has id, label, HTTP(S) url, allowed queryParameters, and optional headerEnvironment mapping header names to environment variable names. Restart after configuration changes. With no catalog, snapshots still render. GET only, JSON 200 responses, no redirects/cookies/default credentials; headers stay on the host.

Limits: 8 connections, 20 scalar query bindings each, 1,024 characters/value, 4 MB/response, 10,000 object rows, 8 MB combined data/project, 15 seconds/request including body reads. Compressed responses are rejected. Page/offset/cursor pagination is host-configured: 1–1,000 requested rows/page, at most 100 pages, 10,000 combined rows, 8 MB cumulative responses and 60 seconds per connection. No OAuth login or background polling. SQL, JSON and objects use the shared workflow below.

For all-page HTTP refresh, choose a source marked Pagination in Connections. Preview shows total rows and pages fetched. All pages must succeed before Apply; a later failure, repeated cursor or page-limit exhaustion leaves the current data unchanged. Page/offset APIs must return a short or empty final page; cursor APIs must return a null/empty final token. Tokens are query values, never followed URLs. See pagination setup and examples.

HTTP sales snapshot project: first run python3 scripts/http-source-fixture.py, then start Studio with NEXTGEN_HTTP_SOURCES="$PWD/samples/http-sources.example.json". Open the project: saved total=190.00. Refresh for region=All, Apply and Generate: West=200.00, East=90.00, total=290.00. Select Demo HTTP orders (page/offset/cursor pagination) in Connections to fetch the same three rows in two pages. Region PageError fails the second page; PageSlow lets you test Cancel. The fixture is loopback-only and synthetic. Complete host setup and API details: repository docs/http-connections.md.

SQL, JSON and objects

Data accepts uploaded JSON, raw JSON or API data directly: {"items":[{"amount":12.34}]}. A .NET host can call engine.Render(template, poco) or engine.Render(template, jsonString). POCO properties become camelCase; dictionary keys remain unchanged. Root arrays require ReportData.FromObject(rows, "items") or ReportData.FromJson(json, "items"). Cycles/scalars are rejected; depth 32, direct data 8 MB.

  1. Configure host catalog NEXTGEN_DATA_SOURCES and restart Studio. SQL providers: postgresql, mssql, mysql, mariadb, sqlite. The catalog contains id, label, provider, connectionEnvironment, query and typed parameters. Set the named environment variable to the connection string. Credentials stay on the host. Queries stay there by default; allowQueryEditing enables project SELECT overrides. Use SELECT-only database accounts; the SELECT guard does not replace permissions.
  2. For a JSON file use {"id":"json_demo","label":"Sales JSON","provider":"json","file":"source-objects.json"}. Relative paths resolve against the catalog directory. File content is reread on explicit refresh. Register object callbacks in host code; NEXTGEN_OBJECT_DEMO=1 enables a synthetic demo.
  3. Open Data → Connections, choose source and target array. SQL path must be empty. For the sample JSON set path rows and remove parameter bindings. For SQL/objects demo bind region → region. Save connections validates configuration without fetching.
  4. Refresh sources → inspect candidate → Apply snapshot → Generate preview. Cancel/failure preserves the previous data. Undo refresh restores it until the next data edit. Save project includes the applied snapshot and source IDs; opening/exporting does not fetch.

SQL, JSON and objects snapshot project starts offline at 10.00. Repository samples/data-sources.example.json supplies five SQL configurations and JSON. Configure only the sources you need. SQL examples expect orders(id, region, amount), West=200 and East=90. Select the configured *_demo source: region All yields 290.00, East yields 90.00. JSON demo yields both rows (290.00). Complete setup and .NET callback examples: Data source configuration and code.

Database browser and SQL editor

Editable SQL project opens offline at 10.00. Enable query editing on sqlite_demo: Refresh/Apply yields All=580.00 or East=180.00. Automatic HTTP project opens offline at 190.00; with the HTTP fixture/catalog configured, Generate fetches 290.00.

The host sets allowQueryEditing:true on a SQL source and restarts Studio. This exposes its default query and enables trusted Authors/Admins to submit SELECTs under its database account; use restricted SELECT-only credentials.

  1. In Connections, bind the source parameters and choose Browse / edit SQL. The editor highlights SQL.
  2. Click Browse database, filter names, expand tables/views and inspect column types/nullability. Click a table/column to insert its quoted identifier at the selection.
  3. Edit a single SELECT using exactly the host-defined @parameters. Preview query shows the first 20 rows and total row count without changing data.
  4. Use query → Save connections → Refresh sources → Apply snapshot → Generate preview. The query override and snapshot persist in saved projects. Cancel discards draft edits. Clearing the override returns to the host query.

Up to 500 tables/views and 10,000 column records; no relationship/join builder, credential editor or database writes. Schema/preview APIs require Author/Admin and CSRF. SQLite live schema/query verified; new schema browsing on the other four providers remains unverified. Setup and code: SQL editor guide.

SQL supports one SELECT with named @parameters, no comments, CTE/WITH, procedures or multiple statements; use database views. Types: string, int64, decimal, boolean, date, datetime, datetimeoffset, guid. Dates use ISO strings; offset timestamps need Z or an offset. Nullable source parameters may be omitted to pass NULL. SQL column aliases must be distinct identifiers; unsupported database types need casts. SQLite opens read-only; PostgreSQL/MySQL/MariaDB use read-only transactions; SQL Server requires a read-only principal.

Limits: 50 sources total including HTTP, 8 connections, 20 bindings/source, 10,000 rows/source, 100 SQL columns, 4 MB/source, 8 MB combined data/project, 15 seconds/fetch. SQL strings up to 4,000 characters per bound value; text/binary result fields up to 262,144 characters/bytes. Object callbacks/getters are trusted host code and must cooperate with cancellation. Connections are independently fetched; only applying the combined local snapshot is atomic. Live PostgreSQL/MySQL/MariaDB/SQLite verified on Linux iMac; SQL Server driver/binding tested, live server unverified. macOS/Windows unverified.

Report library and versions

Library stores complete projects and applied data snapshots on this host. Save project still downloads a portable file. This local library is shared by sessions using the same Studio; optional server mode provides Viewer/Author/Admin roles and schedules.

  1. Generate preview to check your report, then open Library. Enter a name and optional note. Save new copy creates version 1. After editing, Save new version adds a version to the linked report. Names need not be unique; changing the library name does not change the template title.
  2. Enter part of a name and press Find. Select a report and History version. Open version asks before replacing the editor and validates/renders the snapshot first. Save current work before opening. Download project downloads that version without changing the editor.
  3. Restore as latest copies the selected version into a new latest version. Existing versions remain unchanged, and the editor stays as it was. Open the new version explicitly to continue from it.
  4. If another session saved first, a conflict preserves your editor. Download it or Save new copy, then find/open the latest version. Opening an old version does not authorize overwriting newer history. There is no force-save.

Save checks structure, template rules and parameter values, without rendering, scripts or source refresh. Open uses the saved snapshot; Generate may refresh explicitly opted-in HTTP sources and discover data/layout errors; trusted scripts run if enabled on the host. New report, Open project/template and Load sample clear the library link. Ordinary data and parameter edits keep it. Portable files contain no library ID.

Default storage: App_Data/library.db under Studio's content root. Override with NEXTGEN_LIBRARY_FILE pointing to a dedicated private SQLite file. Stop Studio before copying/restoring the file for backup. Keep backups outside deployment folders. Project data is stored unencrypted; host permissions apply. Never use a source database file as the library.

Limits: 8 MB/project, 1,000 reports, 200 versions/report, 1 GB project payloads plus database overhead. Find shows up to 100 newest matches; narrow the search. Names 1–120 characters, notes up to 500. No delete/prune, folders, diff view or automatic save. See Server roles and schedules below. Full API/backup guidance: docs/report-library.md. Linux iMac verified; macOS/Windows unverified.

Server roles and schedules

Without NEXTGEN_SERVER_USERS, Studio is a loopback-only local administrator workbench. A configured private users file enables sign-in: Viewer reads shared reports/results; Author edits, refreshes and saves reports; Admin also manages schedules. All accounts share the same library; there are no per-report ACLs. Viewer uses a read-only library and can download saved/generated files, including source snapshots. Remote access requires configured accounts and HTTPS at Kestrel.

After a Release build, use python3 scripts/server-user.py --name administrator --role admin --output "$HOME/.config/nextgen/users.json". The helper prompts without echo and stores a password hash. Add author/viewer accounts similarly; use --replace deliberately for changes. Set NEXTGEN_SERVER_USERS to this file and restart. Changed/removed accounts lose their previous sessions after restart. The footer shows your role and Sign out. Cookies last at most eight hours; POSTs require CSRF tokens. No SSO/MFA or email password recovery is provided.

  1. Save and verify a report in Library. Open Schedules in the footer. Admin selects a report and fixed version, PDF/HTML/XLSX/DOCX, Fixed interval or Calendar (cron), and a start date/time. Calendar mode adds a five-field cron expression and host time zone. Preview next 5 runs shows selected-zone time, UTC offset and UTC before saving. Office uses editable mode.
  2. Choose Refresh configured sources before rendering only when required; default is the saved snapshot except HTTP connections explicitly set to refresh before generation. Refreshed data does not change the library version.
  3. Save with Enabled for repeating execution, or leave paused. Run now queues one execution even while paused. Refresh list shows running/succeeded/failed and Download links. Author/Viewer can read results but cannot change or run schedules.
  4. Edit and clear Enabled to pause future runs. Saving clears a queued manual request but does not cancel an active job. New library versions do not change the pinned version automatically. Conflicts require reloading/reviewing the current schedule.

Cron fields: minute, hour, day-of-month, month, day-of-week. Use numbers, abbreviated month/day names, *, ranges, lists and steps; no seconds/year fields or special modifiers. Restricted day-of-month and day-of-week combine with AND. A fixed time in a spring DST gap moves to the first valid time; an autumn fixed time runs once, while interval-style expressions retain both repeated-hour offsets. Inspect Preview around time changes. See calendar examples and API. Existing interval data needs no schema migration.

Intervals use elapsed minutes (1–525600); their next run remains claim time + interval, including Run now. Calendar rules such as 0 9 * * MON-FRI follow the selected time zone. Start at or after is entered in your browser’s local time; the stored next run is the first matching UTC instant. Run now preserves a future calendar occurrence. Saved IANA or Windows time-zone identifiers are accepted when this host can resolve them, even if its time-zone menu uses a different naming system. Verify Preview next 5 runs after moving schedules between hosts. Invalid expressions/zones cannot overwrite saved rules. Missed periods coalesce to one execution. One worker runs sequentially while Studio is running, with a cooperative 120-second deadline. An interrupted run is recorded as failed without automatic retry. Viewer PDF generation uses no scripts; scripted reports should use scheduled output. Trusted Authors/Admins can use enabled host scripting.

Limits: 100 schedules, 32 MB/file, 200 recent runs globally and 256 MB artifact payloads. Oldest completed runs/files are removed first. Generation errors publish no artifact; folder-delivery failures retain the generated download. No email/webhook delivery, parameter overrides, delete control or multi-host worker cluster. Pause unwanted schedules. The journal is operational history, not an immutable audit log.

Folder delivery

The host configures NEXTGEN_DELIVERY_FOLDERS with a private JSON catalog of IDs, labels and absolute folder paths. Pre-create folders writable by the service account, outside the public web root, and restart Studio. See configuration and API examples.

  1. As Admin, choose a named destination under Delivery, save a paused schedule, then Run now.
  2. Refresh list: expect generation succeeded and delivery delivered. Check report-<run-id>.pdf (or html/xlsx/docx) in the server folder; Download contains identical bytes.
  3. Enable repeating runs when ready. Choose Download only to stop copying. Active jobs keep their claimed destination. If a destination was removed, choose an available one or Download only before saving.

Existing files are never overwritten. A delivery failure leaves the generated file downloadable; fix permissions/configuration/space and run again manually. Generation failure shows not_attempted. An interrupted run shows unknown delivery: check its run-ID filename before rerunning because a complete folder copy may already exist. No automatic retry or exactly-once crash guarantee. A crash may leave temporary files; remove them only with the scheduler stopped. Folder copies have host-managed retention and are not pruned with the run journal. Local Linux folders verified; network mounts, macOS and Windows unverified.

Storage: dedicated App_Data/schedules.db, override NEXTGEN_SCHEDULES_FILE. An adjacent lock prevents a second scheduler process on the same file. Cookie keys are in App_Data/keys. Stop Studio before backing up/restoring library, schedules and keys together. Protect accounts/keys/data with host permissions; they are not encrypted at rest. Forwarded-header/proxy TLS setup is not included. API clients use session cookies plus X-CSRF-TOKEN; report-tool supports --user and --password-env. Full setup: docs/server-operations.md. Linux iMac verified; remote HTTPS hosting, macOS and Windows remain unverified.

26. .NET and Blazor integration

On Linux, install the desktop shortcut with python3 scripts/install-demo-launcher.py. Double-click Nextgen Reports Demo to start/reuse Studio and the demo and open both demo and this guide in Chrome. Right-click actions open demo or documentation separately. Logs are in artifacts/launcher/; processes stay running when the browser closes. If the repository moves, reinstall the shortcut.

The repository includes NextgenReports.Client and NextgenReports.Blazor. The client accepts JSON or ordinary .NET objects and uses an isolated login/CSRF session. The component provides page navigation, zoom, cancellation and downloads in an Interactive Server application.

  1. Start Studio, then run dotnet run --project examples/BlazorDemo --urls http://127.0.0.1:5277 from the repository root. Open that address. With server accounts enabled, sign in as Author/Admin; Viewer cannot generate submitted reports.
  2. Change Company and Rows, then Apply data. Expect fresh pages and a reset page position. Next/Previous uses already generated SVG pages; Zoom changes their display size.
  3. Choose PDF, HTML, Excel or Word and Download. Office offers Editable and Exact pages. Downloads regenerate from the last successful input; time-dependent scripts can differ from preview.
  4. Enable Demonstrate report error and apply: the error replaces the preview and Download is disabled. Clear it and apply to recover.

For your application, reference the Client/Blazor projects, register one ReportClient per interactive circuit, include _content/NextgenReports.Blazor/viewer.css, then pass Client and a ReportInput to ReportViewer. Assign a new input after edits. The host provides login and parameter forms; data sources use saved snapshots unless explicitly refreshed or an HTTP connection enables refresh before generation. Full code and setup: .NET / Blazor code examples.

Preview limits: 100 SVG pages, 25 MB/page, 100 MB expanded; no selectable text, designer, Studio dialog scripts, search or drill-down in this component. The demo only accepts loopback connections and must not be published as an open proxy. Flutter has a separate SDK and web demo described below. The separate Linux desktop shell is described below. Blazor WebAssembly/Auto, macOS/Windows and remote HTTPS deployment are not verified. Libraries are repository references, not published NuGet packages.

27. Flutter and Dart integration

The repository-local packages/nextgen_reports package supplies a Dart HTTP client and Flutter ReportViewer. Input accepts JSON maps or objects implementing toJson(); property case is preserved. Rendering stays on the report server.

  1. Run bash scripts/build-flutter-demo.sh, start/restart Studio, then open Flutter demo. On Linux, update the launcher with python3 scripts/install-demo-launcher.py and choose Open Flutter demo from its right-click menu. This builds missing assets and starts/reuses Studio.
  2. Local mode shows a three-page equipment report. Server mode asks for Author/Admin login. Change Company/Rows and Apply data; expect fresh pages starting at page 1. Next/Previous and Zoom use the already generated PNG pages.
  3. Choose PDF, HTML, Excel or Word and Download. Office supports Editable and Exact pages. Downloads regenerate from the last successful input snapshot; time-dependent scripts may differ.
  4. Enable Demonstrate report error and apply: expect an error and no stale preview/download. Clear it to recover. Cancel aborts a pending request. Dark/Light theme changes the demo appearance.

Web must share Studio's origin and browser cookies; signing out affects other Studio tabs. Native Dart clients have independent cookie jars. API roles/CSRF/HTTPS checks remain active even though demo assets are public for login. A custom Flutter host supplies parameter/login forms and a save/share callback; the widget never chooses an arbitrary device file path.

Preview limits: 100 PNG pages at 96 DPI, 25 MB/page, 100 MB expanded, 25 million pixels/page and 100 million total. Raster zoom is not vector scaling, and page text is not selectable. Use PDF or editable Office when needed. No designer, scripted Studio dialogs, search or drill-down inside this viewer. Flutter Web and Linux Dart HTTP verified; Android/iOS devices, native desktop GUI, macOS/Windows and remote HTTPS hosting remain unverified. No offline mobile engine or pub.dev release. Full setup: Flutter / Dart code examples.

Page sections and imported subreports

Combine portrait and landscape pages, or reuse a template from another file, in one portable report.

  1. In Design, choose Insert → Page section. Set Section width, height, margin, header and footer in Properties. The default is landscape A4.
  2. Choose Edit section to add or edit its blocks. Page properties now affect that section. Use Report in the breadcrumb to return. The parent page keeps its settings. Undo/Redo includes these edits.
  3. Choose Insert → Subreport, then Import template and select a .nrtemplate file. A named snapshot is saved inside the report. Choose an existing Imported template to reuse it. Set Data object path to an object such as order; leave blank for the current object.
  4. Generate and inspect each Preview page. A section or subreport begins and ends at a page boundary; following content resumes the enclosing format. Footer page numbers count the complete output. Export PDF, HTML, images or Office as usual.
  5. Save project to preserve the templates, data and parameters together. Open project works without the original child file. To update a child, import its edited file again; only the selected block switches to the new copy. Other references remain unchanged.

Imported templates inherit same-named parameters and use their own defaults for the rest. Their data/root is the selected object, and their own images and data preparation are retained. Scripts, dialogs and connections are rejected in children; put them in the parent. A failed import leaves the draft intact. Subreports are separate pages, not inline table cells. There is no automatic file watching or runtime URL/file access.

Up to three combined section/subreport/drill-down levels and 20 imported templates per template. Page sections cannot be inside repeats; put a repeat inside a page section. Imports can be repeated per record. Empty sections are invalid. Existing Office editable-text and custom Excel paper-size limits still apply.

Example: composed template, sample data, standalone child. Expected output: four pages, with a landscape overview and a portrait order totaling 155.50. See format details.

28. Desktop Studio

Open Nextgen Reports Desktop from the desktop, or use the demo launcher's Open desktop Studio action. The separate window starts its own local engine and sample report; it does not use the browser demo's Library.

  1. Choose File → Open project… to open a portable project. Generate preview after editing.
  2. Choose File → Save project as… for a native save dialog. Export PDF/Office/images/HTML through the existing controls.
  3. Save a Library version to retain it between launches. Desktop also saves a recovery draft every three seconds while idle. On restart, choose Restore draft, Discard draft or Quit. Restoring does not generate a preview; fix unfinished JSON and choose Generate preview.
  4. Use Help → Developer guide & code examples for local English code examples.
  5. Use File → Save recovery draft now or Delete recovery draft… to manage the local draft. Normal closing captures final edits; a failed capture asks whether to keep working. Closing stops the owned engine. Other browser demo processes remain available.

Recovery keeps raw template/data text and applied parameter controls, up to 16 MB. Open dialogs and active generation/export pause capture; modal edits, undo history and preview pages are not saved. The draft follows the current workspace and contains local report data. Save files or Library versions before switching projects. Damaged recovery files are preserved with automatic saving paused.

Desktop installation, sandbox setup, data paths, scripts and troubleshooting. Installer targets: Linux AppImage, Windows NSIS and macOS DMG/ZIP. Use Help → Check for updates to download and confirm a restart; the app saves a recovery draft first. Unsigned macOS builds cannot auto-install updates. Linux GUI is checked locally; Windows/macOS GUI and signed distribution remain unverified. See the desktop guide for platform installation steps and limitations.

Code examples use local syntax highlighting. Use Copy code to copy the original source without colors or formatting. Razor markup is highlighted; embedded C# expressions may retain the default text color.