Files
2026-03-18 18:26:24 +08:00

110 lines
2.8 KiB
TypeScript

import {
Document,
Paragraph,
TextRun,
HeadingLevel,
Packer,
AlignmentType,
} from 'docx';
export async function generateDocx(
content: string,
toolName: string
): Promise<Buffer> {
const lines = content.split('\n');
const children: Paragraph[] = [];
// Title
children.push(
new Paragraph({
children: [
new TextRun({
text: `NGO Toolkit Lab — ${toolName.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase())}`,
bold: true,
size: 32,
color: '1a6b3c',
}),
],
heading: HeadingLevel.TITLE,
alignment: AlignmentType.CENTER,
spacing: { after: 400 },
})
);
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) {
children.push(new Paragraph({ spacing: { after: 100 } }));
continue;
}
if (trimmed.startsWith('### ')) {
children.push(
new Paragraph({
children: [new TextRun({ text: trimmed.slice(4), bold: true, size: 24 })],
heading: HeadingLevel.HEADING_3,
spacing: { before: 200, after: 100 },
})
);
} else if (trimmed.startsWith('## ')) {
children.push(
new Paragraph({
children: [new TextRun({ text: trimmed.slice(3), bold: true, size: 28, color: '1a6b3c' })],
heading: HeadingLevel.HEADING_2,
spacing: { before: 300, after: 150 },
})
);
} else if (trimmed.startsWith('# ')) {
children.push(
new Paragraph({
children: [new TextRun({ text: trimmed.slice(2), bold: true, size: 32, color: '1a6b3c' })],
heading: HeadingLevel.HEADING_1,
spacing: { before: 400, after: 200 },
})
);
} else if (trimmed.startsWith('- ') || trimmed.startsWith('* ')) {
children.push(
new Paragraph({
children: [new TextRun({ text: trimmed.slice(2), size: 22 })],
bullet: { level: 0 },
})
);
} else if (trimmed.startsWith('**') && trimmed.endsWith('**')) {
children.push(
new Paragraph({
children: [new TextRun({ text: trimmed.slice(2, -2), bold: true, size: 22 })],
})
);
} else {
children.push(
new Paragraph({
children: [new TextRun({ text: trimmed, size: 22 })],
spacing: { after: 100 },
})
);
}
}
// Footer
children.push(
new Paragraph({
children: [
new TextRun({
text: 'Generated by NGO Toolkit Lab — ngotoolkit.com',
italics: true,
size: 18,
color: '888888',
}),
],
alignment: AlignmentType.CENTER,
spacing: { before: 600 },
})
);
const doc = new Document({
sections: [{ children }],
});
return Buffer.from(await Packer.toBuffer(doc));
}