Vue2 + docx@9.5.1 表格生成入门教程

🛠️ 环境准备

1. 安装依赖

1
2
# 在 Vue2 项目中安装必要的依赖
npm install docx@9.5.1 file-saver --save

2. 基础项目结构

1
2
3
4
src/
├── components/
│ └── WordGenerator.vue
└── main.js

📖 基础概念

核心类说明

类名 作用 示例
Document 创建 Word 文档对象 new Document({...})
Paragraph 创建段落 new Paragraph({text: "内容"})
Table 创建表格 new Table({rows: [...]})
TableRow 表格行 new TableRow({children: [...]})
TableCell 表格单元格 new TableCell({children: [...]})
TextRun 带样式的文本 new TextRun({text: "文字", color: "FF0000"})

常用导入

1
2
3
4
5
import { 
Document, Paragraph, Table, TableRow, TableCell, TextRun,
WidthType, AlignmentType, BorderStyle, VerticalAlign, Packer
} from "docx";
import { saveAs } from "file-saver";

📋 简单表格生成

基础表格示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<template>
<div>
<button @click="generateSimpleTable">生成简单表格</button>
</div>
</template>

<script>
import { Document, Paragraph, Table, TableRow, TableCell, Packer } from "docx";
import { saveAs } from "file-saver";

export default {
methods: {
async generateSimpleTable() {
// 1. 创建表格
const table = new Table({
rows: [
// 表头行
new TableRow({
children: [
new TableCell({ children: [new Paragraph({ text: "姓名" })] }),
new TableCell({ children: [new Paragraph({ text: "年龄" })] }),
new TableCell({ children: [new Paragraph({ text: "职业" })] }),
],
}),
// 数据行
new TableRow({
children: [
new TableCell({ children: [new Paragraph({ text: "张三" })] }),
new TableCell({ children: [new Paragraph({ text: "28" })] }),
new TableCell({ children: [new Paragraph({ text: "工程师" })] }),
],
}),
],
});

// 2. 创建文档
const doc = new Document({
sections: [{ children: [table] }],
});

// 3. 生成并下载
const blob = await Packer.toBlob(doc);
saveAs(blob, "简单表格.docx");
},
},
};
</script>

🏗️ 复杂表格处理

合并单元格示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const table = new Table({
rows: [
// 第一行:包含跨列单元格
new TableRow({
children: [
new TableCell({
children: [new Paragraph({ text: "个人信息" })],
columnSpan: 2, // 横跨2列
}),
new TableCell({
children: [new Paragraph({ text: "教育背景" })],
rowSpan: 2, // 纵跨2行
}),
],
}),
// 第二行
new TableRow({
children: [
new TableCell({ children: [new Paragraph({ text: "姓名" })] }),
new TableCell({ children: [new Paragraph({ text: "年龄" })] }),
// 注意:第三列被上一行的 rowSpan 占用,这里不需要定义
],
}),
],
});

复杂表头结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 类似 Excel 的多级表头
new TableRow({
children: [
new TableCell({
children: [new Paragraph({ text: "基本信息" })],
rowSpan: 2
}),
new TableCell({
children: [new Paragraph({ text: "学校统计" })],
columnSpan: 2
}),
],
}),
new TableRow({
children: [
// 第一个单元格被上一行的 rowSpan 占用
new TableCell({ children: [new Paragraph({ text: "结果" })] }),
new TableCell({ children: [new Paragraph({ text: "摘要" })] }),
],
}),

🎨 样式和格式

1. 表格边框和宽度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const table = new Table({
width: {
size: 100,
type: WidthType.PERCENTAGE, // 百分比宽度
},
borders: {
top: { style: BorderStyle.SINGLE, size: 1 },
bottom: { style: BorderStyle.SINGLE, size: 1 },
left: { style: BorderStyle.SINGLE, size: 1 },
right: { style: BorderStyle.SINGLE, size: 1 },
insideHorizontal: { style: BorderStyle.SINGLE, size: 1 },
insideVertical: { style: BorderStyle.SINGLE, size: 1 },
},
});

自定义宽度,不使用适配宽度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const table = new Table({
width: {
size: 100,
type: WidthType.PERCENTAGE, // 百分比宽度
},
columnWidths: [500,1000,1000,2000,2000], //定义各列宽度(单位:DXA)
layout: TableLayoutType.FIXED, // 关键:固定列宽,不随内容变化
borders: {
top: { style: BorderStyle.SINGLE, size: 1 },
bottom: { style: BorderStyle.SINGLE, size: 1 },
left: { style: BorderStyle.SINGLE, size: 1 },
right: { style: BorderStyle.SINGLE, size: 1 },
insideHorizontal: { style: BorderStyle.SINGLE, size: 1 },
insideVertical: { style: BorderStyle.SINGLE, size: 1 },
},
});

2. 文本样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 正确的方式:样式分开设置
new TableCell({
children: [
new Paragraph({
children: [
new TextRun({
text: "红色加粗文字",
color: "FF0000", // 字体颜色
bold: true, // 加粗
size: 24, // 字体大小
})
],
alignment: AlignmentType.CENTER // 段落对齐(水平)
})
],
shading: { fill: "F0F0F0" }, // 单元格背景色
verticalAlign: VerticalAlign.CENTER // 单元格垂直对齐
}),

3. 颜色对照表

颜色 十六进制值 示例
红色 FF0000 color: "FF0000"
绿色 008000 color: "008000"
蓝色 0000FF color: "0000FF"
黄色 FFFF00 color: "FFFF00"
灰色 808080 color: "808080"

❓ 常见问题

Q1: 为什么文本不居中?

错误写法:

1
2
3
4
new TextRun({ 
text: "文字",
alignment: AlignmentType.CENTER // ❌ 错位位置
})

正确写法:

1
2
3
4
new Paragraph({
children: [new TextRun({ text: "文字" })],
alignment: AlignmentType.CENTER // ✅ 在 Paragraph 设置
})

Q2: 如何设置垂直居中?

1
2
3
4
new TableCell({
children: [new Paragraph({ text: "内容" })],
verticalAlign: VerticalAlign.CENTER // 垂直居中
})

📦 完整示例

最终完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<template>
<div class="word-generator">
<h2>Word 表格生成器</h2>
<button @click="generateWord" class="generate-btn">
生成复杂表格文档
</button>
</div>
</template>

<script>
import {
Document, Paragraph, Table, TableRow, TableCell, TextRun,
WidthType, AlignmentType, BorderStyle, VerticalAlign, Packer
} from "docx";
import { saveAs } from "file-saver";

export default {
name: "WordGenerator",
methods: {
async generateWord() {
try {
// 创建复杂表格
const table = this.createComplexTable();

// 创建文档
const doc = new Document({
sections: [{
children: [
new Paragraph({
text: "员工信息统计表",
heading: "Title",
alignment: AlignmentType.CENTER,
spacing: { after: 400 },
}),
table,
new Paragraph({
text: `生成时间: ${new Date().toLocaleString()}`,
alignment: AlignmentType.RIGHT,
spacing: { before: 400 },
}),
],
}],
});

// 生成并下载
const blob = await Packer.toBlob(doc);
saveAs(blob, "员工信息表.docx");

this.$message.success("文档生成成功!");
} catch (error) {
console.error("生成失败:", error);
this.$message.error("文档生成失败");
}
},

createComplexTable() {
return new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
columnWidths: [500,1000,1000,2000,2000], //定义各列宽度(单位:DXA)
layout: TableLayoutType.FIXED, // 关键:固定列宽,不随内容变化
borders: {
top: { style: BorderStyle.SINGLE, size: 1 },
bottom: { style: BorderStyle.SINGLE, size: 1 },
left: { style: BorderStyle.SINGLE, size: 1 },
right: { style: BorderStyle.SINGLE, size: 1 },
insideHorizontal: { style: BorderStyle.SINGLE, size: 1 },
insideVertical: { style: BorderStyle.SINGLE, size: 1 },
},
rows: [
// 表头行
new TableRow({
children: [
new TableCell({
children: [this.createStyledParagraph("序号", "FF0000")],
rowSpan: 2,
shading: { fill: "F0F0F0" },
verticalAlign: VerticalAlign.CENTER,
}),
new TableCell({
children: [new Paragraph({ text: "基本信息" })],
columnSpan: 2,
shading: { fill: "E6F3FF" },
verticalAlign: VerticalAlign.CENTER,
}),
],
}),
new TableRow({
children: [
new TableCell({
children: [new Paragraph({ text: "姓名" })],
shading: { fill: "F5F5F5" },
}),
new TableCell({
children: [new Paragraph({ text: "部门" })],
shading: { fill: "F5F5F5" },
}),
],
}),
// 数据行
new TableRow({
children: [
new TableCell({
children: [this.createStyledParagraph("1", "FF0000")],
verticalAlign: VerticalAlign.CENTER,
}),
new TableCell({
children: [
new Paragraph(
// { text: reasonstr, alignment: AlignmentType.CENTER }
{
children:[
// 第一部分:普通黑色文字
new TextRun({
text: 文档文献,
color: "000000" // 黑色(默认颜色)
}),
// 第二部分:蓝色页码文字
new TextRun({
text: ` [相关页码:${pagearr.join(',')}页]`,
color: "0000FF", // 蓝色
bold: false // 可选:加粗
})
],

alignment: AlignmentType.CENTER
}
)],
verticalAlign: 'center',
}),
new TableCell({
children: [new Paragraph({ text: "技术部" })],
}),
],
}),
],
});
},

createStyledParagraph(text, color) {
return new Paragraph({
children: [
new TextRun({
text: text,
color: color,
bold: true,
})
],
alignment: AlignmentType.CENTER,
});
},
},
};
</script>

<style scoped>
.word-generator {
padding: 20px;
text-align: center;
}

.generate-btn {
padding: 12px 24px;
background-color: #409EFF;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}

.generate-btn:hover {
background-color: #66b1ff;
}
</style>

🎯 学习建议

  1. 循序渐进:从简单表格开始,逐步尝试复杂功能
  2. 多调试:使用浏览器开发者工具查看错误信息
  3. 参考文档:遇到问题时查阅 docx 官方文档
  4. 实践练习:多写几个不同样式的表格来熟悉 API

这个教程涵盖了 Vue2 + docx@9.5.1 表格生成的基础知识和常见用法,希望能帮助你快速上手!