Fmt Tool
用于重排段落、去除多余空格,清理文本文件的简单工具。
下载 409
基于 docx 库创建跨平台兼容的精美 Word 表格,支持专业排版与样式。
openclaw skills install @happytreees/pretty-tables命令、参数、文件名以原文为准
在 Word 文档中创建美观的表格,确保在 Word 和 Google Docs 中都能一致显示。
经过大量测试,以下是确保表格在所有平台正确渲染的必要规范:
每个表格都需要在表格层级和每个单元格层级分别设置宽度:
// 表格层级
new Table({
width: { size: 9360, type: WidthType.DXA }, // 总宽度
columnWidths: [1872, 7488], // 每列宽度
rows: [...]
})
// 单元格层级 - 每个单元格都必须设置!
new TableCell({
width: { size: 1872, type: WidthType.DXA }, // 该单元格的宽度
children: [...]
})如果任一位置缺失,某些平台上的表格将显示异常。
百分比在 Google Docs 中会失效。始终使用 DXA(twips):
// ❌ 错误 - 在 Google Docs 中失效
width: { size: 100, type: WidthType.PERCENTAGE }
// ✅ 正确
width: { size: 9360, type: WidthType.DXA }这是一个微妙但关键的问题:
const { ShadingType } = require('docx');
// ❌ 错误 - 产生黑色背景
shading: { type: ShadingType.SOLID, fill: "E0F2F1" }
// ✅ 正确 - 正确应用填充颜色
shading: { type: ShadingType.CLEAR, fill: "E0F2F1" }防止文字紧贴边框:
const cellMargins = { top: 80, bottom: 80, left: 120, right: 120 };
new TableCell({
children: [...],
margins: cellMargins
})对于 US Letter 带 1 英寸边距的情况:9360 DXA
// 2 列:20% + 80%
columnWidths: [1872, 7488] // = 9360 ✓
// 3 列:均分
columnWidths: [3120, 3120, 3120] // = 9360 ✓
// 3 列:25% + 25% + 50%
columnWidths: [2340, 2340, 4680] // = 9360 ✓const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
WidthType, AlignmentType, BorderStyle, TableLayoutType, ShadingType } = require('docx');
const fs = require('fs');
// 常量
const TOTAL_WIDTH = 9360; // US Letter 带 1" 边距
const TIME_COL = 1872; // 20%
const CONTENT_COL = 7488; // 80%
// 浅灰色边框
const cellBorders = {
top: { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" },
bottom: { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" },
left: { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" },
right: { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" }
};
// 单元格内边距
const cellMargins = { top: 80, bottom: 80, left: 120, right: 120 };
// 表格生成器
function table(columnWidths, rows) {
return new Table({
layout: TableLayoutType.FIXED,
width: { size: columnWidths.reduce((a, b) => a + b, 0), type: WidthType.DXA },
columnWidths: columnWidths,
rows: rows
});
}
// 标题行
function headerRow(text, color) {
return new TableRow({
children: [
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text, bold: true, size: 32, color: "FFFFFF" })],
alignment: AlignmentType.CENTER
})],
width: { size: TIME_COL + CONTENT_COL, type: WidthType.DXA },
columnSpan: 2,
shading: { type: ShadingType.CLEAR, fill: color },
borders: cellBorders,
margins: cellMargins
})
]
});
}
// 数据行
function dataRow(time, activity, color) {
return new TableRow({
children: [
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text: time, bold: true, size: 26, color })],
alignment: AlignmentType.CENTER
})],
width: { size: TIME_COL, type: WidthType.DXA },
borders: cellBorders,
margins: cellMargins
}),
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text: activity, size: 26 })]
})],
width: { size: CONTENT_COL, type: WidthType.DXA },
borders: cellBorders,
margins: cellMargins
})
]
});
}
// 构建文档
const doc = new Document({
sections: [{
properties: {
page: { margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } }
},
children: [
table([TIME_COL, CONTENT_COL], [
headerRow("SCHEDULE", "1565C0"),
dataRow("9:00 AM", "到达目的地", "1565C0"),
dataRow("10:00 AM", "上午活动", "1565C0"),
dataRow("12:00 PM", "午餐休息", "1565C0"),
])
]
}]
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync('output.docx', buffer);
});适用于 US Letter(8.5 英寸)带 1 英寸边距 = 9360 DXA:
| 布局 | 列宽设置 | 总和 |
|---|---|---|
| 2 列(20/80) | [1872, 7488] | 9360 |
| 2 列(25/75) | [2340, 7020] | 9360 |
| 2 列(30/70) | [2808, 6552] | 9360 |
| 2 列(均分) | [4680, 4680] | 9360 |
| 3 列(均分) | [3120, 3120, 3120] | 9360 |
| 3 列(25/25/50) | [2340, 2340, 4680] | 9360 |
| 3 列(20/30/50) | [1872, 2808, 4680] | 9360 |
| 4 列(均分) | [2340, 2340, 2340, 2340] | 9360 |
❌ 缺少单元格宽度:
new TableCell({ children: [...] }) // 未设置宽度!❌ 使用百分比:
width: { size: 100, type: WidthType.PERCENTAGE } // 在 Google Docs 中失效❌ 错误的阴影类型:
shading: { type: ShadingType.SOLID, fill: "E0F2F1" } // 产生黑色背景!❌ 列宽总和不正确:
columnWidths: [2000, 7000] // 总和为 9000,不是 9360✅ 正确用法:
new TableCell({
width: { size: 1872, type: WidthType.DXA },
shading: { type: ShadingType.CLEAR, fill: "E0F2F1" },
margins: { top: 80, bottom: 80, left: 120, right: 120 },
borders: cellBorders,
children: [...]
})表头颜色:
| 颜色 | 十六进制 | 用途 |
|---|---|---|
| 蓝色 | 1565C0 | 默认表头 |
| 红色 | C62828 | 重要信息 |
| 绿色 | 2E7D32 | 成功提示 |
| 橙色 | EF6C00 | 警告提示 |
| 紫色 | 6A1B9A | 特殊标记 |
| 青绿色 | 00695C | 信息提示 |
浅色背景:
| 颜色 | 十六进制 | 用途 |
|---|---|---|
| 浅蓝色 | BBDEFB | 高亮显示 |
| 浅绿色 | C8E6C9 | 成功状态 |
| 浅黄色 | FFF9C4 | 注释说明 |
| 浅灰色 | F5F5F5 | 交替行背景 |
以下组合确保了表格在 Microsoft Word、Google Docs 及其他 DOCX 查看器中正确渲染:
ShadingType.CLEAR 实现正确的颜色填充问:表格在 Google Docs 中过窄
WidthType.DXA,而非 PERCENTAGETableCell 是否都设置了 width 属性问:单元格背景显示为黑色
ShadingType.SOLID 改为 ShadingType.CLEAR问:文本紧贴边框
margins: { top: 80, bottom: 80, left: 120, right: 120 }问:列宽不均匀
已收录 1 个 Skill