n8n-nodes-contract-gen-2 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/src/ContractGenerator.d.ts +5 -0
- package/dist/src/ContractGenerator.js +77 -0
- package/dist/src/ContractGenerator.node.d.ts +5 -0
- package/dist/src/ContractGenerator.node.js +95 -0
- package/dist/src/DocumentEngine.d.ts +4 -0
- package/dist/src/DocumentEngine.js +62 -0
- package/dist/src/types.d.ts +11 -0
- package/dist/src/types.js +2 -0
- package/index.ts +3 -0
- package/package.json +35 -0
- package/src/ContractGenerator.node.ts +96 -0
- package/src/DocumentEngine.ts +63 -0
- package/src/types.ts +8 -0
- package/tsconfig.json +12 -0
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContractGenerator = void 0;
|
|
4
|
+
const ContractGenerator_node_1 = require("./src/ContractGenerator.node");
|
|
5
|
+
Object.defineProperty(exports, "ContractGenerator", { enumerable: true, get: function () { return ContractGenerator_node_1.ContractGenerator; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { INodeType, INodeTypeDescription, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
export declare class ContractGenerator implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ContractGenerator = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const pdfkit_1 = __importDefault(require("pdfkit"));
|
|
9
|
+
class ContractGenerator {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.description = {
|
|
12
|
+
displayName: 'Contract Generator Lite',
|
|
13
|
+
name: 'contractGeneratorLite',
|
|
14
|
+
group: ['transform'],
|
|
15
|
+
version: 1,
|
|
16
|
+
description: 'Generates a professional contract PDF (lightweight)',
|
|
17
|
+
defaults: { name: 'Contract Generator Lite' },
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
properties: [
|
|
21
|
+
{ displayName: 'Contract Data', name: 'contractData', type: 'json', default: {}, description: 'Contract variables' },
|
|
22
|
+
{ displayName: 'Seal Image', name: 'sealImage', type: 'string', default: '', description: 'Path to seal PNG/JPG' },
|
|
23
|
+
{ displayName: 'Signature Image', name: 'signatureImage', type: 'string', default: '', description: 'Path to signature PNG/JPG' },
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async execute() {
|
|
28
|
+
const items = this.getInputData();
|
|
29
|
+
const returnData = [];
|
|
30
|
+
for (let i = 0; i < items.length; i++) {
|
|
31
|
+
const data = this.getNodeParameter('contractData', i);
|
|
32
|
+
const sealImage = this.getNodeParameter('sealImage', i);
|
|
33
|
+
const signatureImage = this.getNodeParameter('signatureImage', i);
|
|
34
|
+
['company_name', 'client_name', 'contract_number', 'date'].forEach(field => {
|
|
35
|
+
if (!data[field])
|
|
36
|
+
throw new Error(`Missing field: ${field}`);
|
|
37
|
+
});
|
|
38
|
+
const doc = new pdfkit_1.default({ size: 'A4', margin: 50 });
|
|
39
|
+
const buffers = [];
|
|
40
|
+
doc.on('data', buffers.push.bind(buffers));
|
|
41
|
+
doc.on('end', () => { });
|
|
42
|
+
// --- HEADER ---
|
|
43
|
+
doc.rect(0, 0, 595.28, 70).fill('#007BFF'); // голубой хедер
|
|
44
|
+
doc.fillColor('white').fontSize(26).text('KNK GROUP', 50, 25, { align: 'left' });
|
|
45
|
+
doc.moveDown(4);
|
|
46
|
+
doc.fillColor('black').fontSize(12);
|
|
47
|
+
// --- CONTRACT INFO ---
|
|
48
|
+
doc.text(`Договор № ${data.contract_number}`, { continued: true }).text(` от ${data.date}`);
|
|
49
|
+
doc.moveDown();
|
|
50
|
+
// --- PARTIES ---
|
|
51
|
+
doc.font('Helvetica-Bold').text('Исполнитель: ', { continued: true }).font('Helvetica').text(`${data.company_name}, ИНН ${data.inn || ''}`);
|
|
52
|
+
doc.font('Helvetica-Bold').text('Заказчик: ', { continued: true }).font('Helvetica').text(`${data.client_name}`);
|
|
53
|
+
doc.moveDown();
|
|
54
|
+
// --- SUBJECT ---
|
|
55
|
+
doc.font('Helvetica-Bold').text('Предмет договора:');
|
|
56
|
+
doc.font('Helvetica').text(data.subject || 'Оказание услуг по автоматизации бизнес-процессов', { indent: 20 });
|
|
57
|
+
doc.moveDown();
|
|
58
|
+
if (data.VAT) {
|
|
59
|
+
doc.font('Helvetica-Bold').text('НДС: ', { continued: true }).font('Helvetica').text(`включён в сумму ${data.amount || ''} руб.`);
|
|
60
|
+
doc.moveDown();
|
|
61
|
+
}
|
|
62
|
+
// --- SIGNATURES ---
|
|
63
|
+
const startY = doc.y + 30;
|
|
64
|
+
if (fs_1.default.existsSync(signatureImage)) {
|
|
65
|
+
doc.image(signatureImage, 50, startY, { width: 150 });
|
|
66
|
+
}
|
|
67
|
+
if (fs_1.default.existsSync(sealImage)) {
|
|
68
|
+
doc.image(sealImage, 400, startY, { width: 150 });
|
|
69
|
+
}
|
|
70
|
+
doc.end();
|
|
71
|
+
const pdfBuffer = Buffer.concat(buffers);
|
|
72
|
+
returnData.push({ json: { pdf: pdfBuffer.toString('base64') } });
|
|
73
|
+
}
|
|
74
|
+
return [returnData];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.ContractGenerator = ContractGenerator;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class ContractGenerator implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContractGenerator = void 0;
|
|
4
|
+
const DocumentEngine_1 = require("./DocumentEngine");
|
|
5
|
+
class ContractGenerator {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Document Generator Pro',
|
|
9
|
+
name: 'documentGeneratorPro',
|
|
10
|
+
icon: 'fa:file-invoice',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
description: 'Генератор документов (PDF/DOCX) с поддержкой ИИ-контента',
|
|
14
|
+
defaults: { name: 'Document Generator' },
|
|
15
|
+
inputs: ['main'],
|
|
16
|
+
outputs: ['main'],
|
|
17
|
+
properties: [
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Format',
|
|
20
|
+
name: 'format',
|
|
21
|
+
type: 'options',
|
|
22
|
+
options: [
|
|
23
|
+
{ name: 'PDF', value: 'pdf' },
|
|
24
|
+
{ name: 'DOCX (Word)', value: 'docx' },
|
|
25
|
+
],
|
|
26
|
+
default: 'pdf',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
displayName: 'Company Name',
|
|
30
|
+
name: 'companyName',
|
|
31
|
+
type: 'string',
|
|
32
|
+
default: 'My Company',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
displayName: 'Header Color (Hex)',
|
|
36
|
+
name: 'headerColor',
|
|
37
|
+
type: 'color',
|
|
38
|
+
default: '#007BFF',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
displayName: 'Document Title',
|
|
42
|
+
name: 'title',
|
|
43
|
+
type: 'string',
|
|
44
|
+
default: 'Contract / Invoice',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Content (AI Friendly)',
|
|
48
|
+
name: 'content',
|
|
49
|
+
type: 'string',
|
|
50
|
+
typeOptions: { rows: 10 },
|
|
51
|
+
default: '',
|
|
52
|
+
description: 'Сюда можно передать текст, сгенерированный ChatGPT',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
displayName: 'Additional Details (JSON)',
|
|
56
|
+
name: 'details',
|
|
57
|
+
type: 'json',
|
|
58
|
+
default: '[]',
|
|
59
|
+
description: 'Список в формате [{"label": "ИНН", "value": "123"}]',
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async execute() {
|
|
65
|
+
const items = this.getInputData();
|
|
66
|
+
const returnData = [];
|
|
67
|
+
for (let i = 0; i < items.length; i++) {
|
|
68
|
+
const format = this.getNodeParameter('format', i);
|
|
69
|
+
const data = {
|
|
70
|
+
companyName: this.getNodeParameter('companyName', i),
|
|
71
|
+
title: this.getNodeParameter('title', i),
|
|
72
|
+
headerColor: this.getNodeParameter('headerColor', i),
|
|
73
|
+
content: this.getNodeParameter('content', i),
|
|
74
|
+
details: this.getNodeParameter('details', i),
|
|
75
|
+
};
|
|
76
|
+
let buffer;
|
|
77
|
+
let fileName;
|
|
78
|
+
if (format === 'pdf') {
|
|
79
|
+
buffer = await DocumentEngine_1.DocumentEngine.createPDF(data);
|
|
80
|
+
fileName = 'document.pdf';
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
buffer = await DocumentEngine_1.DocumentEngine.createDOCX(data);
|
|
84
|
+
fileName = 'document.docx';
|
|
85
|
+
}
|
|
86
|
+
const binaryData = await this.helpers.prepareBinaryData(buffer, fileName);
|
|
87
|
+
returnData.push({
|
|
88
|
+
json: { status: 'success', format, date: new Date() },
|
|
89
|
+
binary: { data: binaryData }
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return [returnData];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.ContractGenerator = ContractGenerator;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DocumentEngine = void 0;
|
|
7
|
+
const pdfkit_1 = __importDefault(require("pdfkit"));
|
|
8
|
+
const docx_1 = require("docx");
|
|
9
|
+
class DocumentEngine {
|
|
10
|
+
// ГЕНЕРАЦИЯ PDF
|
|
11
|
+
static async createPDF(data) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
const doc = new pdfkit_1.default({ margin: 50 });
|
|
14
|
+
const chunks = [];
|
|
15
|
+
doc.on('data', chunk => chunks.push(chunk));
|
|
16
|
+
doc.on('end', () => resolve(Buffer.concat(chunks)));
|
|
17
|
+
// Красивый Хедер
|
|
18
|
+
doc.rect(0, 0, 600, 80).fill(data.headerColor || '#007BFF');
|
|
19
|
+
doc.fillColor('#FFFFFF').fontSize(22).text(data.companyName.toUpperCase(), 50, 30);
|
|
20
|
+
doc.fontSize(10).text(data.title, 50, 55);
|
|
21
|
+
// Тело документа
|
|
22
|
+
doc.moveDown(5);
|
|
23
|
+
doc.fillColor('#333333').fontSize(18).text(data.title, { align: 'center' });
|
|
24
|
+
doc.moveDown();
|
|
25
|
+
// Основной контент
|
|
26
|
+
doc.fontSize(12).fillColor('#000000').text(data.content, { align: 'justify' });
|
|
27
|
+
// Таблица деталей (Накладная/Реквизиты)
|
|
28
|
+
if (data.details) {
|
|
29
|
+
doc.moveDown();
|
|
30
|
+
data.details.forEach((item) => {
|
|
31
|
+
doc.fontSize(10).font('Helvetica-Bold').text(`${item.label}: `, { continued: true })
|
|
32
|
+
.font('Helvetica').text(item.value);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
doc.end();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// ГЕНЕРАЦИЯ DOCX (Word)
|
|
39
|
+
static async createDOCX(data) {
|
|
40
|
+
const doc = new docx_1.Document({
|
|
41
|
+
sections: [{
|
|
42
|
+
children: [
|
|
43
|
+
new docx_1.Paragraph({
|
|
44
|
+
text: data.companyName,
|
|
45
|
+
heading: docx_1.HeadingLevel.HEADING_1,
|
|
46
|
+
alignment: docx_1.AlignmentType.CENTER,
|
|
47
|
+
}),
|
|
48
|
+
new docx_1.Paragraph({
|
|
49
|
+
children: [new docx_1.TextRun({ text: data.title, bold: true, size: 28 })],
|
|
50
|
+
alignment: docx_1.AlignmentType.CENTER,
|
|
51
|
+
}),
|
|
52
|
+
new docx_1.Paragraph({ text: "", spacing: { before: 400 } }),
|
|
53
|
+
new docx_1.Paragraph({
|
|
54
|
+
children: [new docx_1.TextRun(data.content)],
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
57
|
+
}],
|
|
58
|
+
});
|
|
59
|
+
return await docx_1.Packer.toBuffer(doc);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.DocumentEngine = DocumentEngine;
|
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-contract-gen-2",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight contract PDF generator for n8n",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepare": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"n8n-node",
|
|
13
|
+
"contract",
|
|
14
|
+
"pdf",
|
|
15
|
+
"lightweight"
|
|
16
|
+
],
|
|
17
|
+
"author": "KNK-GROUP",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"docx": "^9.5.1",
|
|
21
|
+
"mustache": "^4.2.0",
|
|
22
|
+
"pdfkit": "^0.13.0"
|
|
23
|
+
},
|
|
24
|
+
"n8n": {
|
|
25
|
+
"nodes": [
|
|
26
|
+
"dist/src/ContractGenerator.node.js"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.19.30",
|
|
31
|
+
"@types/pdfkit": "^0.17.4",
|
|
32
|
+
"n8n-workflow": "^1.120.6",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
import { DocumentEngine } from './DocumentEngine';
|
|
3
|
+
|
|
4
|
+
export class ContractGenerator implements INodeType {
|
|
5
|
+
description: INodeTypeDescription = {
|
|
6
|
+
displayName: 'Document Generator Pro',
|
|
7
|
+
name: 'documentGeneratorPro',
|
|
8
|
+
icon: 'fa:file-invoice',
|
|
9
|
+
group: ['transform'],
|
|
10
|
+
version: 1,
|
|
11
|
+
description: 'Генератор документов (PDF/DOCX) с поддержкой ИИ-контента',
|
|
12
|
+
defaults: { name: 'Document Generator' },
|
|
13
|
+
inputs: ['main'],
|
|
14
|
+
outputs: ['main'],
|
|
15
|
+
properties: [
|
|
16
|
+
{
|
|
17
|
+
displayName: 'Format',
|
|
18
|
+
name: 'format',
|
|
19
|
+
type: 'options',
|
|
20
|
+
options: [
|
|
21
|
+
{ name: 'PDF', value: 'pdf' },
|
|
22
|
+
{ name: 'DOCX (Word)', value: 'docx' },
|
|
23
|
+
],
|
|
24
|
+
default: 'pdf',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Company Name',
|
|
28
|
+
name: 'companyName',
|
|
29
|
+
type: 'string',
|
|
30
|
+
default: 'My Company',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
displayName: 'Header Color (Hex)',
|
|
34
|
+
name: 'headerColor',
|
|
35
|
+
type: 'color',
|
|
36
|
+
default: '#007BFF',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
displayName: 'Document Title',
|
|
40
|
+
name: 'title',
|
|
41
|
+
type: 'string',
|
|
42
|
+
default: 'Contract / Invoice',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
displayName: 'Content (AI Friendly)',
|
|
46
|
+
name: 'content',
|
|
47
|
+
type: 'string',
|
|
48
|
+
typeOptions: { rows: 10 },
|
|
49
|
+
default: '',
|
|
50
|
+
description: 'Сюда можно передать текст, сгенерированный ChatGPT',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
displayName: 'Additional Details (JSON)',
|
|
54
|
+
name: 'details',
|
|
55
|
+
type: 'json',
|
|
56
|
+
default: '[]',
|
|
57
|
+
description: 'Список в формате [{"label": "ИНН", "value": "123"}]',
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
63
|
+
const items = this.getInputData();
|
|
64
|
+
const returnData: INodeExecutionData[] = [];
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < items.length; i++) {
|
|
67
|
+
const format = this.getNodeParameter('format', i) as string;
|
|
68
|
+
const data = {
|
|
69
|
+
companyName: this.getNodeParameter('companyName', i),
|
|
70
|
+
title: this.getNodeParameter('title', i),
|
|
71
|
+
headerColor: this.getNodeParameter('headerColor', i),
|
|
72
|
+
content: this.getNodeParameter('content', i),
|
|
73
|
+
details: this.getNodeParameter('details', i),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
let buffer: Buffer;
|
|
77
|
+
let fileName: string;
|
|
78
|
+
|
|
79
|
+
if (format === 'pdf') {
|
|
80
|
+
buffer = await DocumentEngine.createPDF(data);
|
|
81
|
+
fileName = 'document.pdf';
|
|
82
|
+
} else {
|
|
83
|
+
buffer = await DocumentEngine.createDOCX(data);
|
|
84
|
+
fileName = 'document.docx';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const binaryData = await this.helpers.prepareBinaryData(buffer, fileName);
|
|
88
|
+
|
|
89
|
+
returnData.push({
|
|
90
|
+
json: { status: 'success', format, date: new Date() },
|
|
91
|
+
binary: { data: binaryData }
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return [returnData];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import PDFDocument from 'pdfkit';
|
|
2
|
+
import { Document, Packer, Paragraph, TextRun, HeadingLevel, Table, TableRow, TableCell, WidthType, AlignmentType } from 'docx';
|
|
3
|
+
|
|
4
|
+
export class DocumentEngine {
|
|
5
|
+
// ГЕНЕРАЦИЯ PDF
|
|
6
|
+
static async createPDF(data: any): Promise<Buffer> {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
const doc = new PDFDocument({ margin: 50 });
|
|
9
|
+
const chunks: Buffer[] = [];
|
|
10
|
+
doc.on('data', chunk => chunks.push(chunk));
|
|
11
|
+
doc.on('end', () => resolve(Buffer.concat(chunks)));
|
|
12
|
+
|
|
13
|
+
// Красивый Хедер
|
|
14
|
+
doc.rect(0, 0, 600, 80).fill(data.headerColor || '#007BFF');
|
|
15
|
+
doc.fillColor('#FFFFFF').fontSize(22).text(data.companyName.toUpperCase(), 50, 30);
|
|
16
|
+
doc.fontSize(10).text(data.title, 50, 55);
|
|
17
|
+
|
|
18
|
+
// Тело документа
|
|
19
|
+
doc.moveDown(5);
|
|
20
|
+
doc.fillColor('#333333').fontSize(18).text(data.title, { align: 'center' });
|
|
21
|
+
doc.moveDown();
|
|
22
|
+
|
|
23
|
+
// Основной контент
|
|
24
|
+
doc.fontSize(12).fillColor('#000000').text(data.content, { align: 'justify' });
|
|
25
|
+
|
|
26
|
+
// Таблица деталей (Накладная/Реквизиты)
|
|
27
|
+
if (data.details) {
|
|
28
|
+
doc.moveDown();
|
|
29
|
+
data.details.forEach((item: any) => {
|
|
30
|
+
doc.fontSize(10).font('Helvetica-Bold').text(`${item.label}: `, { continued: true })
|
|
31
|
+
.font('Helvetica').text(item.value);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
doc.end();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ГЕНЕРАЦИЯ DOCX (Word)
|
|
40
|
+
static async createDOCX(data: any): Promise<Buffer> {
|
|
41
|
+
const doc = new Document({
|
|
42
|
+
sections: [{
|
|
43
|
+
children: [
|
|
44
|
+
new Paragraph({
|
|
45
|
+
text: data.companyName,
|
|
46
|
+
heading: HeadingLevel.HEADING_1,
|
|
47
|
+
alignment: AlignmentType.CENTER,
|
|
48
|
+
}),
|
|
49
|
+
new Paragraph({
|
|
50
|
+
children: [new TextRun({ text: data.title, bold: true, size: 28 })],
|
|
51
|
+
alignment: AlignmentType.CENTER,
|
|
52
|
+
}),
|
|
53
|
+
new Paragraph({ text: "", spacing: { before: 400 } }),
|
|
54
|
+
new Paragraph({
|
|
55
|
+
children: [new TextRun(data.content)],
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
}],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return await Packer.toBuffer(doc);
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/types.ts
ADDED
package/tsconfig.json
ADDED