首次提交
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
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}`)
|
||||
Reference in New Issue
Block a user