214 lines
6.0 KiB
JavaScript
214 lines
6.0 KiB
JavaScript
import { mkdir, writeFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import {
|
|
AlignmentType,
|
|
BorderStyle,
|
|
Document,
|
|
Footer,
|
|
HeadingLevel,
|
|
Packer,
|
|
Paragraph,
|
|
Table,
|
|
TableCell,
|
|
TableRow,
|
|
TextRun,
|
|
WidthType,
|
|
} from 'docx'
|
|
|
|
const outputDir = path.resolve(process.cwd(), 'public/assets/templates')
|
|
|
|
function createInfoTable() {
|
|
const rows = [
|
|
['合同名称', '{contractName}'],
|
|
['合同编码', '{contractCode}'],
|
|
['合同类型', '{contractType}'],
|
|
['合同金额', '人民币 {contractAmountDisplay}'],
|
|
['有效期', '{effectivePeriod}'],
|
|
['付款方式', '{paymentMethod}'],
|
|
['合同相对方', '{counterpartySummary}'],
|
|
['附件情况', '{attachmentSummary}'],
|
|
]
|
|
|
|
return new Table({
|
|
width: {
|
|
size: 100,
|
|
type: WidthType.PERCENTAGE,
|
|
},
|
|
rows: rows.map(
|
|
([label, value]) =>
|
|
new TableRow({
|
|
children: [
|
|
new TableCell({
|
|
width: {
|
|
size: 22,
|
|
type: WidthType.PERCENTAGE,
|
|
},
|
|
children: [
|
|
new Paragraph({
|
|
children: [
|
|
new TextRun({
|
|
text: label,
|
|
bold: true,
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
}),
|
|
new TableCell({
|
|
width: {
|
|
size: 78,
|
|
type: WidthType.PERCENTAGE,
|
|
},
|
|
children: [
|
|
new Paragraph({
|
|
text: value,
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
}),
|
|
),
|
|
borders: {
|
|
top: { style: BorderStyle.SINGLE, size: 1, color: 'D9DDE7' },
|
|
bottom: { style: BorderStyle.SINGLE, size: 1, color: 'D9DDE7' },
|
|
left: { style: BorderStyle.SINGLE, size: 1, color: 'D9DDE7' },
|
|
right: { style: BorderStyle.SINGLE, size: 1, color: 'D9DDE7' },
|
|
insideHorizontal: { style: BorderStyle.SINGLE, size: 1, color: 'E5E7EB' },
|
|
insideVertical: { style: BorderStyle.SINGLE, size: 1, color: 'E5E7EB' },
|
|
},
|
|
})
|
|
}
|
|
|
|
function sectionTitle(text) {
|
|
return new Paragraph({
|
|
text,
|
|
heading: HeadingLevel.HEADING_2,
|
|
spacing: {
|
|
before: 280,
|
|
after: 160,
|
|
},
|
|
})
|
|
}
|
|
|
|
function clause(text) {
|
|
return new Paragraph({
|
|
text,
|
|
spacing: {
|
|
after: 160,
|
|
line: 360,
|
|
},
|
|
})
|
|
}
|
|
|
|
async function writeTemplate(filename, config) {
|
|
const doc = new Document({
|
|
sections: [
|
|
{
|
|
properties: {},
|
|
footers: {
|
|
default: new Footer({
|
|
children: [
|
|
new Paragraph({
|
|
alignment: AlignmentType.CENTER,
|
|
children: [
|
|
new TextRun({
|
|
text: `${config.title} - 模板演示文档`,
|
|
color: '6B7280',
|
|
size: 18,
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
}),
|
|
},
|
|
children: [
|
|
new Paragraph({
|
|
text: config.title,
|
|
heading: HeadingLevel.TITLE,
|
|
alignment: AlignmentType.CENTER,
|
|
spacing: {
|
|
after: 240,
|
|
},
|
|
}),
|
|
new Paragraph({
|
|
alignment: AlignmentType.CENTER,
|
|
children: [
|
|
new TextRun({
|
|
text: '用于演示合同发起模块模板填充与导出',
|
|
italics: true,
|
|
color: '64748B',
|
|
}),
|
|
],
|
|
spacing: {
|
|
after: 280,
|
|
},
|
|
}),
|
|
sectionTitle('一、合同基础信息'),
|
|
createInfoTable(),
|
|
sectionTitle('二、合同正文示例'),
|
|
...config.clauses.map(clause),
|
|
sectionTitle('三、补充说明'),
|
|
clause('合同标的说明:{contractSubject}'),
|
|
clause('业务备注:{businessRemark}'),
|
|
clause('模板来源:{templateLabel}'),
|
|
new Paragraph({
|
|
spacing: {
|
|
before: 360,
|
|
after: 180,
|
|
},
|
|
children: [
|
|
new TextRun({
|
|
text: '甲方(业务方):__________________',
|
|
}),
|
|
],
|
|
}),
|
|
new Paragraph({
|
|
spacing: {
|
|
after: 180,
|
|
},
|
|
children: [
|
|
new TextRun({
|
|
text: '乙方(相对方):__________________',
|
|
}),
|
|
],
|
|
}),
|
|
new Paragraph({
|
|
children: [
|
|
new TextRun({
|
|
text: '签署日期:{signDate}',
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
},
|
|
],
|
|
})
|
|
|
|
const buffer = await Packer.toBuffer(doc)
|
|
await writeFile(path.join(outputDir, filename), buffer)
|
|
}
|
|
|
|
await mkdir(outputDir, { recursive: true })
|
|
|
|
await writeTemplate('purchase-contract-template.docx', {
|
|
title: '采购合同模板',
|
|
clauses: [
|
|
'甲乙双方经友好协商,就 {contractName} 项下采购合作事宜达成一致,并共同遵守本合同。',
|
|
'第一条 合作内容:乙方根据甲方需求提供 {contractSubject},具体交付内容以双方确认的技术资料和补充协议为准。',
|
|
'第二条 合同金额:本合同总金额为人民币 {contractAmountDisplay},付款方式采用 {paymentMethod}。',
|
|
'第三条 合同期限:本合同自 {effectiveStart} 起生效,至 {effectiveEnd} 止。',
|
|
],
|
|
})
|
|
|
|
await writeTemplate('sales-contract-template.docx', {
|
|
title: '销售合同模板',
|
|
clauses: [
|
|
'为明确双方权利义务,甲乙双方就 {contractName} 相关销售事项签订本合同。',
|
|
'第一条 销售范围:甲方向乙方提供 {contractSubject},合同编码为 {contractCode}。',
|
|
'第二条 金额与结算:本合同金额合计人民币 {contractAmountDisplay},采用 {paymentMethod} 完成结算。',
|
|
'第三条 生效与终止:本合同有效期为 {effectivePeriod},双方应按约履约。',
|
|
],
|
|
})
|
|
|
|
console.log(`Generated templates in ${outputDir}`)
|