本规范依据最新公文格式修订标准,适用于中国党政机关公文的排版与格式化。
涵盖国家标准15种公文的要求,其余公文可参照执行。
使用本 skill 时,应同时加载 docx skill 以获取 docx-js 创建文档的基础能力。
| 方向 | 数值 (mm) | DXA 换算 (约) |
|---|---|---|
| ------ | ----------- | --------------- |
| 上 | 37mm | 2098 |
| 下 | 35mm | 1984 |
| 左 | 28mm | 1588 |
| 右 | 26mm | 1474 |
// docx-js 页面设置
const pageConfig = {
page: {
size: { width: 11906, height: 16838 }, // A4
margin: {
top: 2098, // 37mm
bottom: 1984, // 35mm
left: 1588, // 28mm
right: 1474 // 26mm
}
}
};
| 属性 | 规格 |
|---|---|
| ---------- | ----------------------------------- |
| 字体 | 方正小标宋简体 (FZXiaoBiaoSong-B05S) |
| 字号 | 二号 (22pt / 44 half-pts) |
| 加粗 | 是 |
| 对齐 | 居中 |
// docx-js 大标题段落
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { line: 560, lineRule: "exact", after: 560 }, // 28磅行距 + 空一行
children: [new TextRun({
text: "公文大标题",
font: { ascii: "FZXiaoBiaoSong-B05S", eastAsia: "FZXiaoBiaoSong-B05S" },
size: 44, // 二号 = 22pt = 44 half-pts
bold: true
})]
})
| 层级 | 字体 | 加粗 | 字号 | half-pts |
|---|---|---|---|---|
| ---------- | ------------------- | ------ | ------ | ---------- |
| 一级标题 | 黑体 (SimHei) | 是 | 三号 | 32 |
| 二级标题 | 楷体 (KaiTi) | 是 | 三号 | 32 |
| 三级标题 | 仿宋_GB2312 | 是 | 三号 | 32 |
| 四级标题 | 仿宋_GB2312 | 否 | 三号 | 32 |
| 层级 | 编号格式 | 示例 |
|---|---|---|
| ---------- | -------------------------- | ------------------- |
| 一级标题 | 汉字数字 + "、" | 一、二、三、 |
| 二级标题 | 括号 + 汉字数字 + 括号 | (一)(二)(三) |
| 三级标题 | 阿拉伯数字 + "." | 1. 2. 3. |
| 四级标题 | 括号 + 阿拉伯数字 + 括号 | (1)(2)(3) |
重要规则:
const HEADING_FONTS = {
level1: { ascii: "SimHei", eastAsia: "SimHei" },
level2: { ascii: "KaiTi", eastAsia: "KaiTi" },
level3: { ascii: "FangSong_GB2312", eastAsia: "FangSong_GB2312" },
level4: { ascii: "FangSong_GB2312", eastAsia: "FangSong_GB2312" }
};
| 属性 | 规格 |
|---|---|
| ------------- | -------------------------------------------- |
| 字体 | 仿宋_GB2312 (FangSong_GB2312) |
| 字号 | 三号 (16pt / 32 half-pts) |
| 加粗 | 否 |
| 行间距 | 固定值 28磅 (可根据内容在 25-30磅 间微调) |
| 首行缩进 | 2字符 (约 640 DXA) |
// docx-js 正文段落
new Paragraph({
indent: { firstLine: 640 }, // 首行缩进2字符
spacing: { line: 560, lineRule: "exact" }, // 28磅行距
children: [new TextRun({
text: "正文内容...",
font: { ascii: "FangSong_GB2312", eastAsia: "FangSong_GB2312" },
size: 32, // 三号
bold: false
})]
})
正确示例:
附件:1. 这是一个非常非常长的附件名称,
需要换行显示
附件:2. 这是第二个附件
由于 "方正小标宋简体" 和 "仿宋_GB2312" 可能不在所有系统上安装,
在实际操作时应尝试查找系统已安装字体,若缺失则降级使用:
| 规范字体 | 备用字体 |
|---|---|
| ------------------- | ------------------------ |
| 方正小标宋简体 | SimSun (宋体) |
| 仿宋_GB2312 | FangSong (仿宋) |
| 黑体 (SimHei) | Microsoft YaHei |
| 楷体 (KaiTi) | 无直接替代,保留 KaiTi |
# 检查并选择字体的辅助逻辑
import subprocess
def get_available_font(primary, fallback):
"""检查首选字体是否可用,否则返回备用字体"""
try:
result = subprocess.run(
['powershell', '-Command',
f'[System.Drawing.FontFamily]::Families | Where-Object {{$_.Name -eq "{primary}"}} | Select-Object -First 1'],
capture_output=True, text=True
)
if primary in result.stdout:
return primary
except:
pass
return fallback
格式化完成后,逐项检查:
当需要生成完整公文时,以下为 docx-js 的完整代码参考模板:
const { Document, Packer, Paragraph, TextRun, AlignmentType, PageBreak } = require('docx');
const fs = require('fs');
// ===== 常量定义 =====
const FONT_TITLE = "FZXiaoBiaoSong-B05S"; // 方正小标宋简体
const FONT_BODY = "FangSong_GB2312"; // 仿宋_GB2312
const FONT_HEI = "SimHei"; // 黑体
const FONT_KAI = "KaiTi"; // 楷体
const SIZE_ER_HAO = 44; // 二号 = 22pt
const SIZE_SAN_HAO = 32; // 三号 = 16pt
const LINE_SPACING = 560; // 28磅 (DXA)
const FIRST_LINE_INDENT = 640; // 首行缩进2字符
// ===== 辅助函数 =====
function bodyParagraph(text, options = {}) {
return new Paragraph({
indent: { firstLine: FIRST_LINE_INDENT },
spacing: { line: LINE_SPACING, lineRule: "exact" },
...options,
children: [
new TextRun({
text: text,
font: { ascii: FONT_BODY, eastAsia: FONT_BODY },
size: SIZE_SAN_HAO,
bold: false
})
]
});
}
function headingParagraph(text, level) {
const fonts = {
1: { font: FONT_HEI, bold: true },
2: { font: FONT_KAI, bold: true },
3: { font: FONT_BODY, bold: true },
4: { font: FONT_BODY, bold: false }
};
const cfg = fonts[level];
return new Paragraph({
indent: { firstLine: FIRST_LINE_INDENT },
spacing: { line: LINE_SPACING, lineRule: "exact" },
children: [
new TextRun({
text: text,
font: { ascii: cfg.font, eastAsia: cfg.font },
size: SIZE_SAN_HAO,
bold: cfg.bold
})
]
});
}
function emptyLine() {
return new Paragraph({
spacing: { line: LINE_SPACING, lineRule: "exact" },
children: [new TextRun({ text: "", size: SIZE_SAN_HAO })]
});
}
// ===== 构建文档 =====
const doc = new Document({
sections: [{
properties: {
page: {
size: { width: 11906, height: 16838 },
margin: { top: 2098, bottom: 1984, left: 1588, right: 1474 }
}
},
children: [
// 大标题
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { line: LINE_SPACING, lineRule: "exact" },
children: [new TextRun({
text: "公文大标题",
font: { ascii: FONT_TITLE, eastAsia: FONT_TITLE },
size: SIZE_ER_HAO,
bold: true
})]
}),
// 空一行
emptyLine(),
// 一级标题
headingParagraph("一、一级标题示例", 1),
bodyParagraph("这是正文内容,字体为仿宋_GB2312,三号字,首行缩进2字符,行间距固定值28磅。"),
// 二级标题
headingParagraph("(一)二级标题示例", 2),
bodyParagraph("正文内容继续..."),
// 正文与落款之间空三行
emptyLine(), emptyLine(), emptyLine(),
// 落款
bodyParagraph("落款单位名称", { indent: { firstLine: 0 }, alignment: AlignmentType.RIGHT }),
bodyParagraph("2026年5月7日", { indent: { firstLine: 0 }, alignment: AlignmentType.RIGHT }),
]
}]
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync("公文示例.docx", buffer);
console.log("公文生成完成!");
});
共 1 个版本