// 开发合同.docx 生成脚本 // 标准 Word 排版:A4、宋体、清晰的层级 const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, AlignmentType, HeadingLevel, BorderStyle, WidthType, ShadingType, PageNumber, Footer, Header, LevelFormat } = require('docx'); const fs = require('fs'); // 边框样式 const noBorder = { style: BorderStyle.NONE, size: 0, color: "FFFFFF" }; const tableBorders = { top: { style: BorderStyle.SINGLE, size: 6, color: "000000" }, bottom: { style: BorderStyle.SINGLE, size: 6, color: "000000" }, left: { style: BorderStyle.SINGLE, size: 6, color: "000000" }, right: { style: BorderStyle.SINGLE, size: 6, color: "000000" }, insideHorizontal: { style: BorderStyle.SINGLE, size: 4, color: "000000" }, insideVertical: { style: BorderStyle.SINGLE, size: 4, color: "000000" }, }; // 标题段落(一级) function h1(text) { return new Paragraph({ heading: HeadingLevel.HEADING_1, spacing: { before: 360, after: 200 }, children: [new TextRun({ text, bold: true, size: 32, font: "SimSun" })], }); } // 标题段落(二级) function h2(text) { return new Paragraph({ heading: HeadingLevel.HEADING_2, spacing: { before: 240, after: 120 }, children: [new TextRun({ text, bold: true, size: 28, font: "SimSun" })], }); } // 正文段落 function p(text, opts = {}) { return new Paragraph({ spacing: { line: 360, before: 80, after: 80, lineRule: "auto" }, alignment: opts.align || AlignmentType.JUSTIFIED, indent: opts.indent ? { firstLine: opts.indent } : undefined, children: [new TextRun({ text, size: 24, font: "SimSun" })], }); } // 粗体段落 function pBold(text, opts = {}) { return new Paragraph({ spacing: { line: 360, before: 80, after: 80, lineRule: "auto" }, alignment: opts.align || AlignmentType.LEFT, children: [new TextRun({ text, bold: true, size: 24, font: "SimSun" })], }); } // 空行 function empty() { return new Paragraph({ children: [new TextRun({ text: "" })] }); } // 居中粗体大标题 function bigTitle(text) { return new Paragraph({ alignment: AlignmentType.CENTER, spacing: { before: 200, after: 400 }, children: [new TextRun({ text, bold: true, size: 44, font: "SimHei" })], }); } // 表格单元格 function cell(text, opts = {}) { return new TableCell({ borders: tableBorders, width: { size: opts.width || 2000, type: WidthType.DXA }, shading: opts.header ? { fill: "E7E6E6", type: ShadingType.CLEAR, color: "auto" } : undefined, margins: { top: 100, bottom: 100, left: 120, right: 120 }, children: [new Paragraph({ alignment: opts.align || AlignmentType.LEFT, spacing: { line: 300, before: 0, after: 0 }, children: [new TextRun({ text: String(text), bold: !!opts.header, size: 24, font: "SimSun", })], })], }); } // 创建表格 function makeTable(rows, colWidths) { return new Table({ width: { size: colWidths.reduce((a, b) => a + b, 0), type: WidthType.DXA }, columnWidths: colWidths, rows: rows.map((row, i) => new TableRow({ children: row.map((text, j) => cell(text, { width: colWidths[j], header: i === 0 })), })), }); } // ==================== 内容 ==================== const children = []; // 大标题 children.push(bigTitle("36仓体直流电瓶车充电柜")); children.push(bigTitle("开发合同")); // 合同信息 children.push(p("合同编号:_______________", { align: AlignmentType.LEFT })); children.push(p("签订地点:_______________", { align: AlignmentType.LEFT })); children.push(p("签订日期:______年______月______日", { align: AlignmentType.LEFT })); children.push(empty()); // 第一条 children.push(h1("第一条 合同双方")); children.push(pBold("甲方(委托方):")); children.push(p("公司名称:____________________________________")); children.push(p("法定代表人:________________")); children.push(p("地址:____________________________________")); children.push(p("联系人:________________ 联系电话:________________")); children.push(empty()); children.push(pBold("乙方(开发方):")); children.push(p("公司名称:____________________________________")); children.push(p("法定代表人:________________")); children.push(p("地址:____________________________________")); children.push(p("联系人:________________ 联系电话:________________")); // 第二条 children.push(h1("第二条 项目概述")); children.push(p("1. 项目名称:36仓体直流电瓶车充电柜开发项目。")); children.push(p("2. 项目目标:开发充电柜配套的柜控主板、仓控主板、嵌入式固件、后台管理系统及微信小程序。")); children.push(p("3. 开发周期:合同生效后12周。")); children.push(p("4. 交付成果:详见第五条及附件。")); // 第三条 children.push(h1("第三条 开发内容")); children.push(makeTable( [ ["序号", "开发内容", "详见附件"], ["1", "柜控主板硬件设计开发", "附件一"], ["2", "仓控主板硬件设计开发", "附件一"], ["3", "嵌入式固件开发(柜控板+仓控板)", "附件一"], ["4", "后台管理系统开发", "附件二"], ["5", "微信小程序开发", "附件二"], ["6", "通讯协议栈开发实现", "附件三"], ], [1000, 5360, 3000] )); children.push(empty()); children.push(p("乙方负责主板设计、元器件采购、焊接调试及联调支持。柜体、电源及外部器件由甲方提供。本合同不交付任何源代码。")); // 第四条 children.push(h1("第四条 开发阶段")); children.push(makeTable( [ ["阶段", "时间", "交付物"], ["M1 方案定稿", "第1-2周", "原理图、PCB、BOM、协议文档"], ["M2 开发完成", "第3-6周", "硬件样板、固件、后台、小程序"], ["M3 联调完成", "第7-9周", "集成测试报告"], ["M4 验收交付", "第10-12周", "完整成品、技术文档"], ], [2500, 2000, 4860] )); children.push(empty()); children.push(p("付款方式:______________________________________________________________________")); // 第五条 children.push(h1("第五条 交付与验收")); children.push(p("交付物清单及验收标准详见附件三。整机验收时乙方到甲方现场完成联调,验收所需柜体及电源由甲方提供。")); // 第六条 children.push(h1("第六条 知识产权")); children.push(p("1. 乙方在本合同履行过程中产生的全部技术成果(包括但不限于源代码、设计图纸、技术文档等)的知识产权归甲乙双方共同所有。")); children.push(p("2. 任何一方均有权在自身业务范围内自由使用上述技术成果,无需征得另一方同意或另行支付费用。")); // 第七条 children.push(h1("第七条 保密条款")); children.push(p("1. 双方对合同履行过程中知悉的对方商业秘密、技术秘密负有保密义务。")); children.push(p("2. 保密期限自合同生效之日起3年。")); children.push(p("3. 未经对方书面同意,不得向第三方披露任何与本合同相关的信息。")); // 第八条 children.push(h1("第八条 质保与维护")); children.push(p("1. 硬件质保期自验收通过之日起12个月,质保期内免费维修或更换。")); children.push(p("2. 软件质保期自验收通过之日起6个月,质保期内免费修复Bug。")); children.push(p("3. 质保期外的维护服务费用由双方另行协商。")); // 第九条 children.push(h1("第九条 违约责任")); children.push(p("1. 甲方逾期付款的,每逾期一日按应付未付金额的千分之三支付违约金。")); children.push(p("2. 乙方逾期交付的,每逾期一日按合同总金额的千分之三支付违约金。")); children.push(p("3. 任何一方违反知识产权或保密条款的,应赔偿对方全部损失。")); // 第十条 children.push(h1("第十条 合同总金额")); children.push(p("合同总金额:人民币____________元(大写:__________________________)。")); // 第十一条 children.push(h1("第十一条 争议解决")); children.push(p("本合同履行过程中发生争议的,双方应协商解决;协商不成的,提交合同签订地人民法院诉讼解决。")); // 第十二条 children.push(h1("第十二条 其他")); children.push(p("1. 本合同一式两份,甲乙双方各执一份,具有同等法律效力。")); children.push(p("2. 本合同附件为合同的组成部分,与本合同具有同等法律效力。")); children.push(p("3. 未尽事宜,双方可另行签订补充协议。")); // 签章区 children.push(empty()); children.push(empty()); children.push(pBold("甲方(盖章):__________________________")); children.push(p("授权代表签字:________________________")); children.push(p("日期:______年______月______日")); children.push(empty()); children.push(pBold("乙方(盖章):__________________________")); children.push(p("授权代表签字:________________________")); children.push(p("日期:______年______月______日")); // ==================== 生成文档 ==================== const doc = new Document({ creator: "CodeBuddy", title: "36仓体直流电瓶车充电柜开发合同", styles: { default: { document: { run: { font: "SimSun", size: 24 } }, }, paragraphStyles: [ { id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true, run: { size: 32, bold: true, font: "SimHei" }, paragraph: { spacing: { before: 360, after: 200 }, outlineLevel: 0 }, }, { id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true, run: { size: 28, bold: true, font: "SimHei" }, paragraph: { spacing: { before: 240, after: 120 }, outlineLevel: 1 }, }, ], }, sections: [{ properties: { page: { size: { width: 11906, height: 16838 }, // A4 margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }, }, }, footers: { default: new Footer({ children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [ new TextRun({ text: "第 ", size: 20, font: "SimSun" }), new TextRun({ children: [PageNumber.CURRENT], size: 20, font: "SimSun" }), new TextRun({ text: " 页 / 共 ", size: 20, font: "SimSun" }), new TextRun({ children: [PageNumber.TOTAL_PAGES], size: 20, font: "SimSun" }), new TextRun({ text: " 页", size: 20, font: "SimSun" }), ], })], }), }, children, }], }); Packer.toBuffer(doc).then(buffer => { fs.writeFileSync("开发合同.docx", buffer); console.log("OK: 开发合同.docx 已生成 (" + buffer.length + " bytes)"); });