| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- const {
- Document, Packer, Paragraph, TextRun, HeadingLevel,
- AlignmentType, Table, TableRow, TableCell, WidthType,
- BorderStyle, ImageRun, PageBreak, ShadingType, convertInchesToTwip
- } = require('docx');
- const fs = require('fs');
-
- // Read the embedded image from the docx media folder
- const imageBuffer = fs.readFileSync('content/word/media/image1.png');
-
- // Helper: create a horizontal line paragraph
- function hline() {
- return new Paragraph({
- border: {
- bottom: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 }
- },
- spacing: { after: 100 },
- children: []
- });
- }
-
- // Helper: info box paragraph (bordered)
- function infoPara(text, color = '4F81BD') {
- return new Paragraph({
- children: [
- new TextRun({ text: ' ' + text, font: '微软雅黑', size: 22, color: '333333' })
- ],
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- border: {
- top: { color, style: BorderStyle.SINGLE, size: 4 },
- bottom: { color, style: BorderStyle.SINGLE, size: 4 },
- left: { color, style: BorderStyle.SINGLE, size: 12 },
- right: { color, style: BorderStyle.SINGLE, size: 4 }
- },
- spacing: { before: 80, after: 80, left: 100 },
- indent: { left: 100 }
- });
- }
-
- // Helper: section title
- function sectionTitle(text) {
- return new Paragraph({
- children: [
- new TextRun({
- text: ' ' + text,
- bold: true,
- font: '微软雅黑',
- size: 26,
- color: 'FFFFFF'
- })
- ],
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- spacing: { before: 120, after: 80 },
- indent: { left: 0 }
- });
- }
-
- // Helper: normal body text
- function bodyPara(text, bold = false, color = '333333', size = 22) {
- return new Paragraph({
- children: [new TextRun({ text, bold, font: '微软雅黑', size, color })],
- spacing: { before: 60, after: 60 },
- indent: { firstLine: 480 }
- });
- }
-
- // Helper: bullet item
- function bullet(text, level = 0) {
- const indent = level * 360;
- return new Paragraph({
- children: [
- new TextRun({ text: '• ', font: '微软雅黑', size: 22, color: '2E74B5' }),
- new TextRun({ text, font: '微软雅黑', size: 22, color: '333333' })
- ],
- spacing: { before: 40, after: 40 },
- indent: { left: 480 + indent }
- });
- }
-
- // Helper: key-value row in a table
- function kvRow(label, value, labelColor = '2E74B5') {
- return new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({
- children: [new TextRun({ text: label, bold: true, font: '微软雅黑', size: 20, color: labelColor })]
- })],
- width: { size: 25, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'E8F0FB' },
- margins: { top: 80, bottom: 80, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({
- children: [new TextRun({ text: value, font: '微软雅黑', size: 20, color: '333333' })]
- })],
- width: { size: 75, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 120, right: 80 }
- })
- ]
- });
- }
-
- const doc = new Document({
- styles: {
- default: {
- document: {
- run: { font: '微软雅黑', size: 22 }
- }
- }
- },
- sections: [{
- properties: {
- page: {
- margin: { top: 1440, right: 1800, bottom: 1440, left: 1800 }
- }
- },
- children: [
- // ===== 大标题 =====
- new Paragraph({
- children: [
- new TextRun({
- text: '报错闭环处理报告',
- bold: true,
- font: '微软雅黑',
- size: 52,
- color: '1F497D'
- })
- ],
- alignment: AlignmentType.CENTER,
- spacing: { after: 200 }
- }),
-
- // ===== 元信息表格 =====
- new Table({
- width: { size: 100, type: WidthType.PERCENTAGE },
- borders: {
- top: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- bottom: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- left: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- right: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- insideH: { style: BorderStyle.SINGLE, size: 2, color: 'BDD7EE' },
- insideV: { style: BorderStyle.SINGLE, size: 2, color: 'BDD7EE' }
- },
- rows: [
- kvRow('报告编号', 'REP-20260418-001'),
- kvRow('处理日期', '2026年4月18日'),
- kvRow('报告类型', '数据异常报错闭环处理'),
- kvRow('处理状态', '已完成'),
- kvRow('报告人', '(请填写)')
- ]
- }),
-
- new Paragraph({ children: [], spacing: { after: 200 } }),
-
- // ===== 一、报错分析 =====
- sectionTitle('一、报错分析'),
- bodyPara('2026年4月18日,系统出现数据异常波动,经排查定位,确认问题原因如下:'),
- bullet('设备端上传的异常参数参与了后台整体运算流程'),
- bullet('该参数导致当日统计结果产生剧烈偏差'),
- new Paragraph({ children: [], spacing: { after: 100 } }),
-
- // 图片说明
- new Paragraph({
- children: [
- new TextRun({ text: '【错误截图】', bold: true, font: '微软雅黑', size: 22, color: '2E74B5' })
- ],
- spacing: { before: 80, after: 80 }
- }),
-
- // 嵌入截图
- new Paragraph({
- children: [
- new ImageRun({
- data: imageBuffer,
- transformation: { width: 560, height: 180 }
- })
- ],
- alignment: AlignmentType.CENTER,
- spacing: { after: 200 }
- }),
-
- // 原因描述
- new Paragraph({
- children: [
- new TextRun({ text: '问题描述:', bold: true, font: '微软雅黑', size: 22, color: 'C00000' }),
- new TextRun({
- text: '由于设备数据上传到后台后,后台将该参数参与了整体运算过程,导致该天数据产生巨大差异。',
- font: '微软雅黑',
- size: 22,
- color: '333333'
- })
- ],
- spacing: { before: 80, after: 80 },
- indent: { firstLine: 480 }
- }),
-
- hline(),
-
- // ===== 二、后台维度处理 =====
- sectionTitle('二、后台维度处理措施'),
- bodyPara('针对本次数据异常,已从以下维度制定并落实处理方案:'),
-
- new Paragraph({
- children: [new TextRun({ text: '2.1 数据校验增强', bold: true, font: '微软雅黑', size: 24, color: '1F497D' })],
- spacing: { before: 120, after: 60 }
- }),
- bullet('对特定字段数据增加范围校验与合法性校验'),
- bullet('对边界值与极值进行实时告警拦截'),
- bullet('引入异常数据默认值兜底机制,防止脏数据扩散'),
-
- new Paragraph({
- children: [new TextRun({ text: '2.2 后台运算管控', bold: true, font: '微软雅黑', size: 24, color: '1F497D' })],
- spacing: { before: 120, after: 60 }
- }),
- bullet('消除异常操作对数据统计的影响'),
- bullet('对参与整体运算的字段增加白名单过滤'),
- bullet('建立敏感参数修改的操作审计日志'),
-
- new Paragraph({
- children: [new TextRun({ text: '2.3 预警与闭环机制', bold: true, font: '微软雅黑', size: 24, color: '1F497D' })],
- spacing: { before: 120, after: 60 }
- }),
- bullet('设置数据波动阈值告警,超过阈值自动通知'),
- bullet('完善异常数据处理流程,形成闭环跟踪机制'),
- bullet('定期回溯验证,确保类似事件不再复发'),
-
- new Paragraph({ children: [], spacing: { after: 200 } }),
-
- hline(),
-
- // ===== 三、处理结论 =====
- sectionTitle('三、处理结论'),
- infoPara('处理结论:对特定字段数据进行管控处理,消除对数据异常进行的异常操作处理,增强校验机制,达到数据处理准确结果,避免类似事件再次发生。'),
-
- new Paragraph({ children: [], spacing: { after: 200 } }),
-
- hline(),
-
- // ===== 四、处理进度 =====
- sectionTitle('四、处理进度'),
- new Table({
- width: { size: 100, type: WidthType.PERCENTAGE },
- borders: {
- top: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- bottom: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- left: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- right: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- insideH: { style: BorderStyle.SINGLE, size: 2, color: 'BDD7EE' },
- insideV: { style: BorderStyle.SINGLE, size: 2, color: 'BDD7EE' }
- },
- rows: [
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '序号', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '处理阶段', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 30, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '处理措施', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '完成时间', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 15, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '状态', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- })
- ]
- }),
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '1', font: '微软雅黑', size: 20 })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '问题定位', font: '微软雅黑', size: 20 })] })],
- width: { size: 30, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '确认设备异常参数上传原因', font: '微软雅黑', size: 20 })] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '2026-04-18', font: '微软雅黑', size: 20 })] })],
- width: { size: 15, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '已完成', font: '微软雅黑', size: 20, color: '00B050' })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- })
- ]
- }),
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '2', font: '微软雅黑', size: 20 })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '数据修复', font: '微软雅黑', size: 20 })] })],
- width: { size: 30, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '清洗当日异常数据,恢复正确统计结果', font: '微软雅黑', size: 20 })] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '2026-04-18', font: '微软雅黑', size: 20 })] })],
- width: { size: 15, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '已完成', font: '微软雅黑', size: 20, color: '00B050' })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- })
- ]
- }),
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '3', font: '微软雅黑', size: 20 })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '校验增强', font: '微软雅黑', size: 20 })] })],
- width: { size: 30, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '增加参数合法性校验与极值告警机制', font: '微软雅黑', size: 20 })] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '2026-04-18', font: '微软雅黑', size: 20 })] })],
- width: { size: 15, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '已完成', font: '微软雅黑', size: 20, color: '00B050' })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- })
- ]
- }),
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '4', font: '微软雅黑', size: 20 })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '持续监控', font: '微软雅黑', size: 20 })] })],
- width: { size: 30, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '建立数据波动告警与周期性回溯机制', font: '微软雅黑', size: 20 })] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '2026-04-18', font: '微软雅黑', size: 20 })] })],
- width: { size: 15, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '已完成', font: '微软雅黑', size: 20, color: '00B050' })] })],
- width: { size: 10, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: 'F0F7FF' },
- margins: { top: 80, bottom: 80, left: 80, right: 80 }
- })
- ]
- })
- ]
- }),
-
- new Paragraph({ children: [], spacing: { after: 300 } }),
-
- hline(),
-
- // ===== 五、签字确认 =====
- sectionTitle('五、签字确认'),
- new Paragraph({
- children: [new TextRun({ text: '本报告由相关责任人确认签字后归档,确保问题处理闭环可追溯。', font: '微软雅黑', size: 22, color: '666666' })],
- spacing: { before: 80, after: 160 }
- }),
-
- new Table({
- width: { size: 100, type: WidthType.PERCENTAGE },
- borders: {
- top: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- bottom: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- left: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- right: { style: BorderStyle.SINGLE, size: 4, color: '2E74B5' },
- insideH: { style: BorderStyle.SINGLE, size: 2, color: 'BDD7EE' },
- insideV: { style: BorderStyle.SINGLE, size: 2, color: 'BDD7EE' }
- },
- rows: [
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '角色', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 20, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '姓名', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 25, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '签字', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: '日期', bold: true, font: '微软雅黑', size: 20, color: 'FFFFFF' })] })],
- width: { size: 20, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: '2E74B5' },
- margins: { top: 80, bottom: 80, left: 120, right: 80 }
- })
- ]
- }),
- ...['提出人', '开发负责人', '测试负责人', '审批人'].map((role, i) =>
- new TableRow({
- children: [
- new TableCell({
- children: [new Paragraph({ children: [new TextRun({ text: role, font: '微软雅黑', size: 20 })] })],
- width: { size: 20, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: i % 2 === 0 ? 'FFFFFF' : 'F0F7FF' },
- margins: { top: 120, bottom: 120, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [] })],
- width: { size: 25, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: i % 2 === 0 ? 'FFFFFF' : 'F0F7FF' },
- margins: { top: 120, bottom: 120, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [] })],
- width: { size: 35, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: i % 2 === 0 ? 'FFFFFF' : 'F0F7FF' },
- margins: { top: 120, bottom: 120, left: 120, right: 80 }
- }),
- new TableCell({
- children: [new Paragraph({ children: [] })],
- width: { size: 20, type: WidthType.PERCENTAGE },
- shading: { type: ShadingType.CLEAR, color: 'auto', fill: i % 2 === 0 ? 'FFFFFF' : 'F0F7FF' },
- margins: { top: 120, bottom: 120, left: 120, right: 80 }
- })
- ]
- })
- )
- ]
- })
- ]
- }]
- });
-
- Packer.toBuffer(doc).then(buffer => {
- fs.writeFileSync('20260418报错闭环处理_美化版.docx', buffer);
- console.log('Done!');
- });
|