第一章 唾手可得——三部曲
第一步:安装docx、file-saver
npm i docx --save
npm i file-saver --save
第二步:引入docx
// 快捷保存函数
import { saveAs } from "file-saver";
// 文档生成器,以及文件流导出
import { Document, Packer} from 'docx';
第三步:导出你的第一个Word
// 此时的导入应该长这样↓
import { Document, Packer, Paragraph} from 'docx';
// 初始化文档
const doc = new Document({
sections: [
{
properties: {},
children: [
new Paragraph("hello world"),
],
},
],
});
//导出
Packer.toBlob(doc).then(buffer => {
// 文档名支持模板语法 `${}` ,但注意!!一定要加文件扩展名
saveAs(buffer, '报告.docx');
});
恭喜你!!!已经掌握------------60%_____了
第二章 描边大师——文档属性
1.
new Document
( { 里面是什么呢 } )
1.1 新手入门需关注的配置项
declare type IPropertiesOptions = {
// 文档的各个部分(section)配置
readonly sections: readonly ISectionOptions[];
// 文档标题
readonly title?: string;
// 文档创建者
readonly creator?: string;
// 文档样式配置(目录第四章会详细说明)
readonly styles?: IStylesOptions;
};
1.2(附) 完整的配置项
declare type IPropertiesOptions = {
// 文档的各个部分(section)配置
readonly sections: readonly ISectionOptions[];
// 文档标题
readonly title?: string;
// 文档创建者
readonly creator?: string;
// 文档样式配置(目录第四章会详细说明)
readonly styles?: IStylesOptions;
// 文档主题
readonly subject?: string;
// 文档关键字
readonly keywords?: string;
// 文档描述
readonly description?: string;
// 最后修改者
readonly lastModifiedBy?: string;
// 文档修订版本号
readonly revision?: number;
// 外部样式表路径
readonly externalStyles?: string;
// 文档编号配置
readonly numbering?: {
readonly config: readonly {
readonly levels: [
{
readonly level: number; // 几级编号
readonly format?: (typeof LevelFormat)[keyof typeof LevelFormat]; // 编号格式
readonly text?: string; // 显示格式
readonly alignment?: (typeof AlignmentType)[keyof typeof AlignmentType]; // 对齐方式
readonly start?: number;
readonly suffix?: (typeof LevelSuffix)[keyof typeof LevelSuffix];
readonly isLegalNumberingStyle?: boolean;
readonly style?: {
readonly run?: IRunStylePropertiesOptions;
readonly paragraph?: ILevelParagraphStylePropertiesOptions;
}
}
],
readonly reference: string;
}
};
// 文档注释配置
readonly comments?: {
readonly children:[
{
readonly id: number; // 注释唯一标记
readonly children: readonly FileChild[]; // 注释的内容
readonly initials?: string;
readonly author?: string; // 注释作者
readonly date?: Date; // 注释日期
}
]
};
// 文档脚注配置
readonly footnotes?: {
"自定义脚注1":{
children: [new Paragraph("这是一个测试脚注")],
},
// ...
};
// 文档背景配置
readonly background?: {
readonly color?: string; // 背景颜色
readonly themeColor?: string; // Word的主题颜色
readonly themeShade?: string; // 主题颜色的阴影效果
readonly themeTint?: string; // 主题颜色的色调效果
};
// 文档功能配置
readonly features?: {
// 是否启用修订跟踪
readonly trackRevisions?: boolean;
// 是否更新字段
readonly updateFields?: boolean;
};
// 兼容模式版本号
readonly compatabilityModeVersion?: number;
// 兼容性配置
// 其选项稍微较多,如需了解可自行去源码第78行
// https://github.com/dolanmiu/docx/blob/master/src/file/settings/compatibility.ts
readonly compatibility?: ICompatibilityOptions;
// 自定义属性配置
readonly customProperties?: [
{
readonly name: string;
readonly value: string;
},
// ...
];
// 是否启用奇偶页不同的页眉和页脚
readonly evenAndOddHeaderAndFooters?: boolean;
// 默认制表符停止位置
readonly defaultTabStop?: number;
// 文档字体配置
readonly fonts?: [
{
readonly name: string;
readonly data: Buffer;
// 源码 第45行:https://github.com/dolanmiu/docx/blob/master/src/file/fonts/font.ts
readonly characterSet?: (typeof CharacterSet)[keyof typeof CharacterSet];
},
// ...
];
// 断字配置(连字符配置)
readonly hyphenation?: {
readonlyautoHyphenation?: boolean; // 自动断字
readonly hyphenationZone?: number; // 单词长超多少会断
readonly consecutiveHyphenLimit?: number; // 最大断字行数
readonly doNotHyphenateCaps?: boolean; // 大写单词断字
};
};
第三章 分门别类——Sections
1.
sections
里有什么?
const doc = new Document({
sections: [
{
properties: {},
children: [
// 这里面是什么
],
},
],
})
1.1 完整的配置项
declare type ISectionOptions = {
// **最重要的,决定Word具体内容**
readonly children: readonly FileChild[];
// 页面属性
readonly properties?: {
readonly page?: {
readonly size?: IPageSizeAttributes; // 页面大小
readonly margin?: IPageMarginAttributes; // 页边距
readonly pageNumbers?: IPageNumberTypeAttributes; // 页码
readonly borders?: IPageBordersOptions; // 页面边框
readonly textDirection?: (typeof PageTextDirectionType)[keyof typeof PageTextDirectionType];
};// 文本方向
readonly grid?: IDocGridAttributesProperties; // 文档网格
readonly headerWrapperGroup?: IHeaderFooterGroup<HeaderWrapper>; // 页眉组
readonly footerWrapperGroup?: IHeaderFooterGroup<FooterWrapper>; // 页脚组
readonly lineNumbers?: ILineNumberAttributes; // 行号
readonly titlePage?: boolean; // 是否标题页
readonly verticalAlign?: (typeof VerticalAlign)[keyof typeof VerticalAlign]; // 垂直对齐
readonly column?: IColumnsAttributes; // 分栏
readonly type?: (typeof SectionType)[keyof typeof SectionType]; // 部分类型
};
// 文档页眉设置
readonly headers?: {
readonly default?: Header;
readonly first?: Header;
readonly even?: Header;
};
// 文档页脚设置
readonly footers?: {
readonly default?: Footer;
readonly first?: Footer;
readonly even?: Footer;
};
}
1.2 section-chidlren 里允许直接存在的内容
目前我测试了以下类别不需要载体就可直接存在于children中
Paragraph 段落
Table 表格
TableOfContents 目录
Textbox 文本框
TextRun // 有时会导致文件打开报错
名称 | 导入 | 使用 |
---|---|---|
段落 | import { Paragraph } from 'docx' | new Paragraph(<string> or <IParagraphOptions> ) |
表格 | import { Table, TableRow, TableCell } from 'docx' | new Table(<ITableOptions> ) |
目录 | import { TableOfContents } from 'docx' | new TableOfContents(<string:别名> , <ITableOfContentsOptions> ) |
文本框 | import { Textbox } from 'docx' | new Textbox(<ITextboxOptions> ) |
下面是其基本示例
// 基本包
import { Document, Paragraph, TableOfContents, Table, TableRow, TableCell, Packer, Textbox } from 'docx';
// 标记段落标题的包
import { HeadingLevel } from "docx";
const doc = new Document({
sections: [
{
properties: {},
children: [
// 目录
new TableOfContents("目录", {
hyperlink: true, // 目录项带超链接
headingStyleRange: "1-3", // 包含 1 到 3 级标题
}),
// 段落
new Paragraph("hello world"),
// 表格
new Table({
rows: [
new TableRow({
children: [
new TableCell({ children: [new Paragraph("姓名")] }),
new TableCell({ children: [new Paragraph("年龄")] }),
new TableCell({ children: [new Paragraph("职业")] }),
],
}),
new TableRow({
children: [
new TableCell({ children: [new Paragraph("张三")] }),
new TableCell({ children: [new Paragraph("30")] }),
new TableCell({ children: [new Paragraph("工程师")] }),
],
}),
],
width: { size: 100, type: "pct" }, // 表格宽度 100%
}),
new Textbox({
children: [new Paragraph("这是一个文本框")],
width: 200, // 宽度
height: 100, // 高度
border: { color: "000000", size: 2 }, // 边框
}),
],
},
],
});
// 导出文件
Packer.toBlob(doc).then((buffer) => {
saveAs(buffer, `报告.docx`);
});
代码运行效果:
1.3 段落Paragraph的参数 (<string>) 或 (<IParagraphOptions>)
1.3.1 string 直接字符串显示
new Paragraph("这是第一章的内容。")
运行效果
1.3.2 IParagraphOptions 通过配置项显示
提到这个段落,我们回顾一下标准docx文件都提供了哪些选项:
(1) 段落对齐 左对齐,右对齐,两端对齐:对应alignment选项
(2) 行距 段前距,段后距:对应spacing选项
(3) 文本底纹:对应shading选项
(4) …
export declare type IParagraphOptions = {
// 直接设置段落的文本内容
readonly text?: string;
// 段落的子元素(如 TextRun、ImageRun 等)
readonly children?: readonly ParagraphChild[];
// 设置段落的标题级别(如 Heading1、Heading2 等)
readonly heading?: (typeof HeadingLevel)[keyof typeof HeadingLevel];
// 是否启用双向文本支持(用于从右到左的语言,如阿拉伯语)
readonly bidirectional?: boolean;
// 是否在段落前插入分页符
readonly pageBreakBefore?: boolean;
// 设置制表符(Tab)的位置和样式
readonly tabStops?: readonly TabStopDefinition[];
// 设置段落的样式名称
readonly style?: string;
// 设置段落的项目符号或编号
readonly bullet?: {
readonly level: number; // 项目符号的层级
};
// 是否控制段落的孤行(防止段落的第一行或最后一行单独出现在页面上)
readonly widowControl?: boolean;
// 设置段落的框架属性(如位置、大小等)
readonly frame?: IFrameOptions;
// 是否禁止段落的行号显示
readonly suppressLineNumbers?: boolean;
// 是否启用自动换行
readonly wordWrap?: boolean;
// 是否允许标点符号溢出边界
readonly overflowPunctuation?: boolean;
// 设置段落的缩放比例
readonly scale?: number;
// 是否自动调整东亚文本的间距
readonly autoSpaceEastAsianText?: boolean;
// 设置段落中文本的运行属性(如字体、颜色、加粗等)
readonly run?: IRunOptions;
// 设置段落的边框属性
readonly border?: IBordersOptions;
// 设置段落的背景颜色或填充
readonly shading?: IShadingAttributesProperties;
// 设置段落的编号(如有序列表、无序列表)
readonly numbering?: {
readonly reference: string; // 编号的唯一标识符
readonly level: number; // 编号的层级
readonly instance?: number; // 编号的实例
readonly custom?: boolean; // 是否使用自定义编号
} | false; // 设置为 false 表示禁用编号
// 设置段落的对齐方式(如左对齐、居中对齐、右对齐等)
readonly alignment?: (typeof AlignmentType)[keyof typeof AlignmentType];
// 是否在段落后添加主题分隔线
readonly thematicBreak?: boolean;
// 是否启用上下文间距(用于控制段落之间的间距)
readonly contextualSpacing?: boolean;
// 设置段落的右制表符位置
readonly rightTabStop?: number;
// 设置段落的左制表符位置
readonly leftTabStop?: number;
// 设置段落的缩进属性
readonly indent?: IIndentAttributesProperties;
// 设置段落的间距属性(如行距、段前距、段后距等)
readonly spacing?: ISpacingProperties;
// 是否将段落与下一段落保持在同一页
readonly keepNext?: boolean;
// 是否将段落的所有行保持在同一页
readonly keepLines?: boolean;
// 设置段落的大纲级别(用于生成文档结构)
readonly outlineLevel?: number;
};
// 标题级别
import { HeadingLevel } from "docx";
// 对齐方式
import { AlignmentType } from "docx"
// 边框样式
import { BorderStyle } from "docx"
// 此处只保留了部分关键代码
new Paragraph({
text: "一个声明了一级标题并被自定义的段落",
heading: HeadingLevel.HEADING_1, // 一级标题
alignment: AlignmentType.CENTER, // 文字居中
children: [
new TextRun("随便输的,"),
new TextRun("和段落在一行"),
// new Paragraph("和段落在一行"), // 嵌套也可以,不过会丢弃父亲的alignment,有兴趣自行尝试
],
border: {
top: { // 上边框红色实线
style: BorderStyle.SINGLE,
color: "ff0000",
size: 10
},
left: { // 左边框绿色虚线
style: BorderStyle.DASHED,
color: "00ff00",
size: 10
}
},
shading:{
fill: "cccccc" // 浅灰色背景
},
})
运行效果
1.4 表格Table的参数 (<ITableOptions>)
export declare type ITableOptions = {
// 表格的行
readonly rows: readonly TableRow[];
// 表格的宽度
readonly width?: {
readonly size: number | Percentage | UniversalMeasure; // 宽度值
readonly type?: (typeof WidthType)[keyof typeof WidthType]; // 宽度类型(如百分比、固定值等)
};
// 表格的列宽
readonly columnWidths?: readonly number[];
// 表格的边距
readonly margins?: ITableCellMarginOptions;
// 表格的缩进
readonly indent?: ITableWidthProperties;
// 表格的浮动属性(如是否允许表格浮动)
readonly float?: ITableFloatOptions;
// 表格的布局类型(如自动布局、固定布局)
readonly layout?: (typeof TableLayoutType)[keyof typeof TableLayoutType];
// 表格的样式名称
readonly style?: string;
// 表格的边框属性
readonly borders?: ITableBordersOptions;
// 表格的对齐方式(如左对齐、居中对齐、右对齐)
readonly alignment?: (typeof AlignmentType)[keyof typeof AlignmentType];
// 是否从右到左显示表格(用于从右到左的语言,如阿拉伯语)
readonly visuallyRightToLeft?: boolean;
};
使用示例:
// 基础包
import { Document, Packer } from 'docx';
// 表格包
import { Table, TableRow, TableCell } from 'docx';
// 此处只保留了部分关键代码
new Table({
rows: [
new TableRow({
children: [
new TableCell({ children: [new Paragraph({ text: "姓名", alignment: 'center', })] }),// 利用Paragraph实现表格内容居中对齐
new TableCell({ children: [new Paragraph({ text: "年龄", alignment: 'center', })] }),
new TableCell({ children: [new Paragraph({ text: "职业", alignment: AlignmentType.CENTER, })] }),
],
}),
new TableRow({
children: [
new TableCell({ children: [new Paragraph("张三")] }),
new TableCell({ children: [new Paragraph("30")] }),
new TableCell({ children: [new Paragraph("工程师")] }),
],
}),
],
width: {
size: 80, // 表格宽度为 80% (方便看表格对齐效果)
type: WidthType.PERCENTAGE, // 宽度类型为百分比
},
columnWidths: [1000, 3000, 2000], // 列宽分别为 2000 缇
margins: {
top: 100, // 上边距 100 缇
bottom: 100, // 下边距 100 缇
left: 100, // 左边距 100 缇
right: 100, // 右边距 100 缇
},
alignment: AlignmentType.CENTER, // 整个表格居中对齐
borders: {
top: { style: "single", size: 4, color: "000000" }, // 上边框
bottom: { style: "single", size: 4, color: "000000" }, // 下边框
left: { style: "single", size: 4, color: "000000" }, // 左边框
right: { style: "single", size: 4, color: "000000" }, // 右边框
insideHorizontal: { style: "single", size: 2, color: "CCCCCC" }, // 内部水平边框
insideVertical: { style: "single", size: 2, color: "CCCCCC" }, // 内部垂直边框
},
})
代码效果:
1.5 目录TableOfContents的参数 (<string>,<ITableOfContentsOptions>)
第一个参数是目录的别名,第二个重点介绍:
代码示例:
// 基础包
import { Document, Packer, Paragraph } from 'docx';
// 目录包
import { TableOfContents } from 'docx'
// 标题级别
import { HeadingLevel } from "docx";
// 只展示部分关键代码
children: [
new TableOfContents("你看我像目录吗?", {
hyperlink: true, // 目录项带超链接
headingStyleRange: "1-3", // 包含 1 到 3 级标题
}),
new Paragraph({
text: "第一章 介绍",
heading: HeadingLevel.HEADING_1, // 一级标题
}),
new Paragraph("这是第一章的内容。"),
// 标题 2
new Paragraph({
text: "1.1 背景",
heading: HeadingLevel.HEADING_2, // 二级标题
}),
new Paragraph("这是 1.1 节的内容。"),
// 标题 3
new Paragraph({
text: "1.1.1 技术栈",
heading: HeadingLevel.HEADING_3, // 三级标题
}),
new Paragraph("这是 1.1.1 节的内容。"),
// 普通段落
new Paragraph("hello world")
]
代码效果:
1.6 文本框Textbox 的参数 (<ITextboxOptions>)
declare type ITextboxOptions = {
// 文本框的子元素(如 Paragraph、TextRun 等)
readonly children?: readonly ParagraphChild[];
// 文本框的样式配置
readonly style?: {
// 翻转方式(如水平翻转、垂直翻转)
readonly flip?: "x" | "y" | "xy" | "yx";
// 文本框的高度
readonly height?: LengthUnit;
// 文本框的左边距
readonly left?: LengthUnit;
// 文本框的下边距
readonly marginBottom?: LengthUnit;
// 文本框的左边距
readonly marginLeft?: LengthUnit;
// 文本框的右边距
readonly marginRight?: LengthUnit;
// 文本框的上边距
readonly marginTop?: LengthUnit;
// 文本框的水平位置(如绝对位置、左对齐、居中等)
readonly positionHorizontal?: "absolute" | "left" | "center" | "right" | "inside" | "outside";
// 文本框水平位置的参考基准(如页边距、页面、文本等)
readonly positionHorizontalRelative?: "margin" | "page" | "text" | "char";
// 文本框的垂直位置(如绝对位置、顶部对齐、居中等)
readonly positionVertical?: "absolute" | "top" | "center" | "bottom" | "inside" | "outside";
// 文本框垂直位置的参考基准(如页边距、页面、文本等)
readonly positionVerticalRelative?: "margin" | "page" | "text" | "char";
// 文本框底部与周围文本的间距
readonly wrapDistanceBottom?: number;
// 文本框左侧与周围文本的间距
readonly wrapDistanceLeft?: number;
// 文本框右侧与周围文本的间距
readonly wrapDistanceRight?: number;
// 文本框顶部与周围文本的间距
readonly wrapDistanceTop?: number;
// 是否启用文本框的环绕编辑
readonly wrapEdited?: boolean;
// 文本框的环绕样式(如方形环绕、无环绕)
readonly wrapStyle?: "square" | "none";
// 文本框的位置类型(如静态、绝对、相对)
readonly position?: "static" | "absolute" | "relative";
// 文本框的旋转角度
readonly rotation?: number;
// 文本框的顶部位置
readonly top?: LengthUnit;
// 文本框的可见性(如隐藏、继承)
readonly visibility?: "hidden" | "inherit";
// 文本框的宽度
readonly width: LengthUnit;
// 文本框的堆叠顺序(z-index)
readonly zIndex?: "auto" | number;
}
}
使用示例:
// 基础包
import { Document, Packer, Paragraph } from 'docx';
// 文本框包
import { Textbox } from 'docx';
// 展示部分关键代码
new Textbox({
children:[
new Paragraph('我是文本框')
],
style: {
width: 200, // 宽度 200 缇
height: 600, // 高度 600 缇
border: { color: "000000", size: 2 }, // 边框
rotation: 30, // 旋转30度
},
})
代码效果
第四章 花里胡哨——美颜篇
1. 文档美颜
多查文档doge