{"_id":"@diyrex/n8n-nodes-temp-doc","name":"@diyrex/n8n-nodes-temp-doc","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@diyrex/n8n-nodes-temp-doc","version":"0.1.1","description":"n8n node for generating DOCX, XLSX, Markdown, and TXT files from templates","license":"MIT","main":"index.js","publishConfig":{"access":"public"},"scripts":{"build":"tsc && cp nodes/UniversalTemplater/UniversalTemplater.node.json dist/nodes/UniversalTemplater/","dev":"tsc --watch","lint":"eslint nodes --ext .ts","format":"prettier --write \"nodes/**/*.ts\" \"*.ts\""},"n8n":{"n8nNodesApiVersion":1,"credentials":[],"nodes":["dist/nodes/UniversalTemplater/UniversalTemplater.node.js"]},"keywords":["n8n-community-node-package","n8n","template","docx","xlsx","handlebars","document-generation"],"devDependencies":{"@types/node":"^18.16.0","@typescript-eslint/eslint-plugin":"^5.62.0","@typescript-eslint/parser":"^5.62.0","eslint":"^8.45.0","eslint-plugin-n8n-nodes-base":"^1.16.1","n8n-workflow":"^1.0.0","prettier":"^3.0.0","typescript":"^5.1.6"},"peerDependencies":{"n8n-workflow":">=0.5.0"},"dependencies":{"@types/handlebars":"^4.1.0","docxtemplater":"^3.44.0","exceljs":"^4.4.0","handlebars":"^4.7.8","pizzip":"^3.1.7"},"engines":{"node":">=18.0","npm":">=8.0"},"_id":"@diyrex/n8n-nodes-temp-doc@0.1.1","_nodeVersion":"25.8.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-Or4wgTaQmIun1A6SZbdrYswh4gOuq4xX2B8V+Ee708lke0wyTjxcCaKGoTkJ+2gni73yNR2aactTki9MYW9ydw==","shasum":"aba598a9788ddcd0ac08221ac14bc482641c64f0","tarball":"https://registry.npmjs.org/@diyrex/n8n-nodes-temp-doc/-/n8n-nodes-temp-doc-0.1.1.tgz","fileCount":27,"unpackedSize":88302,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIB+hre5kKzrf6/Ks1Rwl8v0pip7uKSIXPSXFqdwzadrcAiEAhKAd+z/0MGVvvL/43Leyvf53sLkvkGihB9pOrJ3XfMI="}]},"_npmUser":{"name":"diyrex","email":"dsdissanayaka2002@gmail.com"},"directories":{},"maintainers":[{"name":"diyrex","email":"dsdissanayaka2002@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/n8n-nodes-temp-doc_0.1.1_1773062152305_0.9806512676128607"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-09T13:15:52.134Z","0.1.1":"2026-03-09T13:15:52.463Z","modified":"2026-03-09T13:15:52.760Z"},"maintainers":[{"name":"diyrex","email":"dsdissanayaka2002@gmail.com"}],"description":"n8n node for generating DOCX, XLSX, Markdown, and TXT files from templates","keywords":["n8n-community-node-package","n8n","template","docx","xlsx","handlebars","document-generation"],"license":"MIT","readme":"# n8n-nodes-universal-templater\n\nAn n8n community node that generates **DOCX**, **XLSX**, **Markdown**, and **TXT** files\nfrom templates using a single, standardised JSON data structure.\n\n---\n\n## Supported Formats\n\n| Format   | Engine            | Template Syntax                         |\n|----------|-------------------|-----------------------------------------|\n| DOCX     | docxtemplater     | `{key}`, `{#each rows}…{/each}`         |\n| XLSX     | ExcelJS           | `{{key}}`, `{{rows[*].col}}`            |\n| Markdown | Handlebars        | `{{key}}`, `{{#each rows}}…{{/each}}`   |\n| TXT      | Handlebars        | same as Markdown                        |\n\n---\n\n## Installation\n\n### In an existing n8n instance\n\n```bash\n# Inside the n8n user data directory\nnpm install n8n-nodes-universal-templater\n```\n\nRestart n8n. The **Universal Templater** node will appear in the node palette under\nthe *Transform* group.\n\n### Local / development install\n\n```bash\ngit clone https://github.com/your-org/n8n-nodes-universal-templater.git\ncd n8n-nodes-universal-templater\nnpm install\nnpm run build\n\n# Link into your local n8n\ncd ~/.n8n/nodes   # or wherever N8N_CUSTOM_EXTENSIONS points\nnpm link /path/to/n8n-nodes-universal-templater\n```\n\n---\n\n## Node Parameters\n\n| Parameter               | Type    | Default  | Description                                                                  |\n|-------------------------|---------|----------|------------------------------------------------------------------------------|\n| Output Format           | Select  | DOCX     | The format of the file to generate.                                          |\n| Input Binary Property   | String  | `data`   | Binary property on the input item that holds the template file.              |\n| Template Data           | JSON    | `{}`     | Data object injected into the template.                                      |\n| Output File Name        | String  | `output` | Base name for the output file (extension is added automatically).            |\n| Output Binary Property  | String  | `data`   | Binary property on the output item where the rendered file will be written.  |\n\n---\n\n## JSON Data Structure\n\nThe node expects a flat-or-nested JSON object. The recommended standardised shape is:\n\n```json\n{\n  \"title\": \"My Report\",\n  \"author\": \"John Doe\",\n  \"date\": \"2024-01-01\",\n  \"rows\": [\n    { \"name\": \"Item 1\", \"price\": 10.00, \"qty\": 2 },\n    { \"name\": \"Item 2\", \"price\": 25.50, \"qty\": 1 }\n  ]\n}\n```\n\nAll engines accept this shape. Scalar fields (`title`, `author`, `date`) are substituted\nwherever their placeholder appears. The `rows` array (or any other array) drives row\nexpansion in XLSX and loop iteration in DOCX / Handlebars templates.\n\n---\n\n## Template Syntax by Format\n\n### DOCX (docxtemplater)\n\ndocxtemplater uses **single-brace** tags inside a valid `.docx` file.\n\n```\nDear {firstName} {lastName},\n\nPlease find below your order summary dated {date}:\n\n{#items}\n  - {name}: {qty} × ${price}\n{/items}\n\nTotal items: {totalItems}\n```\n\n**Tips:**\n- Tags must be styled normally inside Word — do not split them across formatting runs.\n- Use `{#arrayName}…{/arrayName}` for loops.\n- Use `{?condition}…{/condition}` for conditionals.\n- See the [docxtemplater docs](https://docxtemplater.com/docs/tag-types/) for the full syntax.\n\n---\n\n### XLSX (ExcelJS)\n\nPlace placeholder strings directly in cell values within a `.xlsx` template file.\n\n**Scalar replacement** — any cell whose text contains `{{key}}` will have the token\nreplaced with the matching value from the data object:\n\n```\nCell A1: {{title}}\nCell B1: Generated on {{date}}\n```\n\n**Array / table expansion** — place one template row whose cells use the pattern\n`{{arrayName[*].propertyName}}`:\n\n| Column A               | Column B               | Column C              |\n|------------------------|------------------------|-----------------------|\n| `{{rows[*].name}}`     | `{{rows[*].price}}`    | `{{rows[*].qty}}`     |\n\nAt render time the node will:\n1. Detect that row as a template row for the `rows` array.\n2. Duplicate the row once per item in `data.rows`.\n3. Fill each cell with the corresponding item property value.\n4. Delete the original template row.\n\nMultiple independent template rows (for different arrays) are supported within the\nsame sheet. They are processed bottom-up to keep row numbers stable.\n\n---\n\n### Markdown & TXT (Handlebars)\n\nBoth formats use the full [Handlebars](https://handlebarsjs.com/) templating language.\nThe template is stored as binary text (UTF-8) on the input item.\n\n**Basic interpolation:**\n\n```handlebars\n# {{title}}\n\n**Author:** {{author}}\n**Date:** {{date}}\n```\n\n**Loops:**\n\n```handlebars\n## Line Items\n\n{{#each rows}}\n- **{{name}}** — qty: {{qty}}, price: ${{fixed price 2}}\n{{/each}}\n```\n\n**Conditionals:**\n\n```handlebars\n{{#if rows}}\nThe report contains {{rows.length}} items.\n{{else}}\nNo items found.\n{{/if}}\n```\n\n**Built-in helpers registered by this node:**\n\n| Helper                  | Description                                          |\n|-------------------------|------------------------------------------------------|\n| `{{eq a b}}`            | True if `a === b`                                    |\n| `{{gt a b}}`            | True if `a > b`                                      |\n| `{{lt a b}}`            | True if `a < b`                                      |\n| `{{gte a b}}`           | True if `a >= b`                                     |\n| `{{lte a b}}`           | True if `a <= b`                                     |\n| `{{ne a b}}`            | True if `a !== b`                                    |\n| `{{json obj}}`          | Pretty-print an object as JSON                       |\n| `{{upper str}}`         | Convert to UPPER CASE                                |\n| `{{lower str}}`         | Convert to lower case                                |\n| `{{trim str}}`          | Remove leading/trailing whitespace                   |\n| `{{default val fallback}}` | Return `val` if truthy, else `fallback`           |\n| `{{add a b}}`           | `a + b`                                              |\n| `{{subtract a b}}`      | `a - b`                                              |\n| `{{multiply a b}}`      | `a × b`                                              |\n| `{{divide a b}}`        | `a / b` (returns 0 on divide-by-zero)               |\n| `{{fixed num digits}}`  | Format number to fixed decimal places                |\n| `{{formatDate dateStr locale}}` | Format a date string using `toLocaleDateString` |\n\n---\n\n## Examples\n\n### Example 1 — Generate a Word invoice\n\n**Workflow:**\n1. **Read Binary File** node — reads `invoice_template.docx` into binary property `data`.\n2. **Set** node — sets `jsonData` to the invoice data JSON.\n3. **Universal Templater** — format: DOCX, data property: `data`, output: `invoice_2024.docx`.\n4. **Write Binary File** or **Send Email** — uses the `data` binary output.\n\n**Template data:**\n```json\n{\n  \"invoiceNumber\": \"INV-2024-001\",\n  \"clientName\": \"Acme Corp\",\n  \"date\": \"2024-01-15\",\n  \"rows\": [\n    { \"description\": \"Consulting services\", \"hours\": 8, \"rate\": 150.00 },\n    { \"description\": \"Expense reimbursement\", \"hours\": 0, \"rate\": 75.00 }\n  ],\n  \"total\": 1275.00\n}\n```\n\n**Excerpt from invoice_template.docx:**\n```\nInvoice #: {invoiceNumber}\nClient: {clientName}\nDate: {date}\n\n{#rows}\n{description}  |  {hours}h  |  ${rate}\n{/rows}\n\nTotal: ${total}\n```\n\n---\n\n### Example 2 — Generate a Markdown report via HTTP\n\n**Workflow:**\n1. **HTTP Request** node — GET `https://api.example.com/data` → JSON response.\n2. **Function** node — transforms API response into the standard data shape.\n3. **Read Binary File** node — reads `report_template.md` → binary `template`.\n4. **Universal Templater** — format: Markdown, input binary property: `template`,\n   template data from expression `{{ $json }}`, output file name: `report`.\n5. **Write Binary File** — saves `report.md`.\n\n---\n\n### Example 3 — Excel report with table expansion\n\n**Template `sales_template.xlsx` cell layout:**\n\n| A1: `{{title}}`     | B1: (blank)         | C1: (blank)        |\n|---------------------|---------------------|--------------------|\n| A2: `Month`         | B2: `Revenue`       | C2: `Units`        |\n| A3: `{{rows[*].month}}` | B3: `{{rows[*].revenue}}` | C3: `{{rows[*].units}}` |\n\n**Template data:**\n```json\n{\n  \"title\": \"Sales Report Q1 2024\",\n  \"rows\": [\n    { \"month\": \"January\",  \"revenue\": 45200, \"units\": 312 },\n    { \"month\": \"February\", \"revenue\": 51800, \"units\": 389 },\n    { \"month\": \"March\",    \"revenue\": 63100, \"units\": 441 }\n  ]\n}\n```\n\n**Output:** Row 1 gets `Sales Report Q1 2024` in A1; the template row (row 3) expands\ninto three rows, one per month, then the template row is deleted.\n\n---\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Compile TypeScript (outputs to ./dist)\nnpm run build\n\n# Watch mode\nnpm run dev\n\n# Lint\nnpm run lint\n\n# Format\nnpm run format\n```\n\n### Project structure\n\n```\nn8n-nodes-universal-templater/\n├── nodes/\n│   └── UniversalTemplater/\n│       ├── UniversalTemplater.node.ts   # Main INodeType implementation\n│       ├── engines/\n│       │   ├── docxEngine.ts            # docxtemplater wrapper\n│       │   ├── xlsxEngine.ts            # ExcelJS placeholder engine\n│       │   └── textEngine.ts            # Handlebars wrapper\n│       └── utils/\n│           └── binaryHelpers.ts         # Buffer ↔ IBinaryData conversion\n├── index.ts                             # Package entry point\n├── package.json\n└── tsconfig.json\n```\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-d158879e8f09ac8be62a28d8ba9f1743"}