在现代 Web 开发中,动态生成 Word 文档的需求日益增长,无论是用于报告导出、合同生成,还是数据归档。借助 Spire.Doc for JavaScript,开发者可以直接在 React 应用中轻松实现专业级 Word 文档的创建与编辑。本文将详细介绍如何通过代码添加标题、段落、图片、列表和表格,并自定义样式,帮助您快速掌握从 React 前端生成标准化文档的核心技巧。
安装 Spire.Doc for JavaScript
要在 React 应用程序中创建 Word 文档,首先需要通过官网下载 Spire.Doc for JavaScript,或者通过以下 npm 命令安装:
npm i spire.doc
安装完成后,将 Spire.Doc.Base.js 和 Spire.Doc.Base.wasm 文件复制到项目的 public 文件夹中。此外,还需包含所需的字体文件,以确保文本渲染准确。
更多详细信息,请参阅文档:如何在 React 项目中集成 Spire.Doc for JavaScript
在 React 中添加标题、小标题和段落到Word
要为 Word 文档添加标题、小标题和段落,您主要使用 Spire.Doc for JavaScript 提供的 Document 和 Section 类。AddParagraph() 方法用于创建新段落,而 AppendText() 方法则允许您在段落中插入文本。
段落可以通过内置样式(如 Title、Heading1-4)进行格式化,以确保文档结构统一;也可以通过自定义样式设置特定字体、字号和颜色,实现个性化的文档设计。
在 React 中向 Word 文档添加标题、小标题和段落的步骤如下:
- 导入必要的字体文件到虚拟文件系统(VFS)。
- 使用 wasmModule.Document.Create() 创建 Document 对象。
- 通过 Document.AddSection() 在文档中添加新节。
- 使用 Section.AddParagraph() 向文档添加段落。
- 通过 Paragraph.ApplyStyle() 为特定段落应用内置样式(如 Title、Heading1、Heading2、Heading3)。
- 使用 wasmModule.ParagraphStyle.Create() 定义自定义段落样式,并将其应用到指定段落。
- 将文档保存为 DOCX 文件并触发下载。
- JavaScript
import React, { useState, useEffect } from 'react';
function App() {
// 保存加载的 WASM 模块
const [wasmModule, setWasmModule] = useState(null);
// 在组件挂载时加载 WASM 模块
useEffect(() => {
const loadWasm = async () => {
try {
// 从全局 window 对象访问 Module 和 spiredoc
const { Module, spiredoc } = window;
// 当运行时初始化时设置 wasmModule 状态
Module.onRuntimeInitialized = () => {
setWasmModule(spiredoc);
};
} catch (err) {
// 记录加载过程中发生的任何错误
console.error('加载 WASM 模块失败:', err);
}
};
// 创建一个脚本元素来加载 WASM JavaScript 文件
const script = document.createElement('script');
script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
script.onload = loadWasm;
// 将脚本添加到文档主体
document.body.appendChild(script);
// 清理函数,在组件卸载时移除脚本
return () => {
document.body.removeChild(script);
};
}, []);
// 向 Word 添加文本的函数
const AddText = async () => {
if (wasmModule) {
// 将字体文件加载到虚拟文件系统 (VFS)
await wasmModule.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/`);
// 创建一个新文档
const doc = wasmModule.Document.Create();
// 添加一个章节
let section = doc.AddSection();
// 设置页面边距
section.PageSetup.Margins.All = 60;
// 添加标题段落
let title_para = section.AddParagraph();
let text_range = title_para.AppendText('这是标题');
title_para.ApplyStyle({builtinStyle: wasmModule.BuiltinStyle.Title});
text_range.CharacterFormat.FontName = "宋体";
// 添加小标题段落
let heading_one = section.AddParagraph();
text_range = heading_one.AppendText('这是标题1');
heading_one.ApplyStyle({builtinStyle: wasmModule.BuiltinStyle.Heading1});
text_range.CharacterFormat.FontName = "宋体";
let heading_two = section.AddParagraph();
text_range = heading_two.AppendText('这是标题2');
heading_two.ApplyStyle({builtinStyle: wasmModule.BuiltinStyle.Heading2});
text_range.CharacterFormat.FontName = "宋体";
let heading_three = section.AddParagraph();
text_range = heading_three.AppendText('这是标题3');
heading_three.ApplyStyle({builtinStyle: wasmModule.BuiltinStyle.Heading3});
text_range.CharacterFormat.FontName = "宋体";
let heading_four = section.AddParagraph();
text_range = heading_four.AppendText('这是标题4');
heading_four.ApplyStyle({builtinStyle: wasmModule.BuiltinStyle.Heading4});
text_range.CharacterFormat.FontName = "宋体";
// 添加普通段落
let normal_para = section.AddParagraph();
normal_para.AppendText('这是一个段落。');
// 创建段落样式,指定字体名称、字体大小和文本颜色
let paragraph_style = wasmModule.ParagraphStyle.Create(doc);
paragraph_style.Name = 'newStyle';
paragraph_style.CharacterFormat.FontName = '宋体';
paragraph_style.CharacterFormat.FontSize = 13;
paragraph_style.CharacterFormat.TextColor = wasmModule.Color.get_Blue();
// 将样式添加到文档
doc.Styles.Add(paragraph_style);
// 将样式应用于段落
normal_para.ApplyStyle(paragraph_style.Name);
// 保存文档
const outputFileName = 'output.docx';
doc.SaveToFile({fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013});
// 创建用于下载文件的 Blob
const modifiedFileArray = wasmModule.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
const url = URL.createObjectURL(modifiedFile);
// 触发文件下载
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// 清理资源
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中向 Word 文档添加文本</h1>
<button onClick={AddText} disabled={!wasmModule}>
生成
</button>
</div>
);
}
export default App;
运行代码启动 React 应用(访问 localhost:3000)。点击“生成”按钮后,系统将弹出“另存为”窗口,提示您选择文件夹保存输出的 Word 文档。
下图展示了生成的 Word 文件截图,其中包含一个标题、多个层级标题和一个普通段落:
在 React 中添加图片到 Word
向 Word 文档插入图片需要使用 AppendPicture() 方法,该方法允许您将图片添加到特定段落。操作前需先将图片文件加载至虚拟文件系统(VFS),确保图片可被正常插入。
在 React 中向 Word 文档添加图片的步骤:
- 使用 wasmModule.Document.Create() 创建 Document 对象。
- 通过 Document.AddSection() 为文档添加新节。
- 使用 Section.AddParagraph() 在节中插入新段落。
- 调用 Paragraph.AppendPicture() 方法将已加载的图片添加至段落。
- 将文档保存为 DOCX 文件并触发下载。
- JavaScript
import React, { useState, useEffect } from 'react';
function App() {
// 保存加载的 WASM 模块
const [wasmModule, setWasmModule] = useState(null);
// 在组件挂载时加载 WASM 模块
useEffect(() => {
const loadWasm = async () => {
try {
// 从全局 window 对象访问 Module 和 spiredoc
const { Module, spiredoc } = window;
// 当运行时初始化时设置 wasmModule 状态
Module.onRuntimeInitialized = () => {
setWasmModule(spiredoc);
};
} catch (err) {
// 记录加载过程中发生的任何错误
console.error('加载 WASM 模块失败:', err);
}
};
// 创建一个脚本元素来加载 WASM JavaScript 文件
const script = document.createElement('script');
script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
script.onload = loadWasm;
// 将脚本添加到文档主体
document.body.appendChild(script);
// 清理函数,在组件卸载时移除脚本
return () => {
document.body.removeChild(script);
};
}, []);
// 向 Word 添加图像的函数
const AddImage = async () => {
if (wasmModule) {
// 将图像文件加载到虚拟文件系统 (VFS)
const inputImageFile = 'logo.png';
await wasmModule.FetchFileToVFS(inputImageFile, '', `${process.env.PUBLIC_URL}/`);
// 创建一个新文档
const doc = wasmModule.Document.Create();
// 添加一个章节
let section = doc.AddSection();
// 设置页面边距
section.PageSetup.Margins.All = 60;
// 添加段落
let image_para = section.AddParagraph();
// 向段落中添加图像
image_para.AppendPicture({imgFile: inputImageFile});
// 保存文档
const outputFileName = 'output.docx';
doc.SaveToFile({fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013});
// 创建用于下载文件的 Blob
const modifiedFileArray = wasmModule.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
const url = URL.createObjectURL(modifiedFile);
// 触发下载
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// 清理资源
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中向 Word 文档添加图片</h1>
<button onClick={AddImage} disabled={!wasmModule}>
生成
</button>
</div>
);
}
export default App;
在 React 中添加列表到 Word
要在 Word 文档中创建列表,首先可以使用 ListStyle 类定义列表的外观,例如项目符号或编号格式。然后通过 ApplyStyle() 方法将定义好的列表样式应用到段落,从而确保多个列表项保持统一的格式样式。
在 React 中为 Word 文档添加列表的操作步骤:
- 将所需字体文件加载至虚拟文件系统(VFS)。
- 使用 wasmModule.Document.Create() 创建文档对象。
- 通过 Document.AddSection() 为文档添加节。
- 使用 wasmModule.ListStyle.Create() 定义列表样式。
- 通过 Section.AddParagraph() 在节中插入多个段落。
- 使用 Paragraph.ListFormat.ApplyStyle() 为段落应用定义好的列表样式。
- 将文档保存为 DOCX 格式并触发下载。
- JavaScript
import React, { useState, useEffect } from 'react';
function App() {
// 保存加载的 WASM 模块
const [wasmModule, setWasmModule] = useState(null);
// 在组件挂载时加载 WASM 模块
useEffect(() => {
const loadWasm = async () => {
try {
// 从全局 window 对象访问 Module 和 spiredoc
const { Module, spiredoc } = window;
// 当运行时初始化时设置 wasmModule 状态
Module.onRuntimeInitialized = () => {
setWasmModule(spiredoc);
};
} catch (err) {
// 记录加载过程中发生的任何错误
console.error('加载 WASM 模块失败:', err);
}
};
// 创建一个脚本元素来加载 WASM JavaScript 文件
const script = document.createElement('script');
script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
script.onload = loadWasm;
// 将脚本添加到文档主体
document.body.appendChild(script);
// 清理函数,在组件卸载时移除脚本
return () => {
document.body.removeChild(script);
};
}, []);
// 向 Word 添加列表的函数
const AddList = async () => {
if (wasmModule) {
// 将字体文件加载到虚拟文件系统 (VFS)
await wasmModule.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/`);
// 创建一个新文档
const doc = wasmModule.Document.Create();
// 添加一个章节
let section = doc.AddSection();
// 设置页面边距
section.PageSetup.Margins.All = 60;
// 定义项目符号列表样式
let list_style = wasmModule.ListStyle.Create(doc, wasmModule.ListType.Bulleted);
list_style.Name = 'bulletedList';
list_style.Levels.get_Item(0).BulletCharacter = '\u00B7';
list_style.Levels.get_Item(0).CharacterFormat.FontName = 'Symbol';
list_style.Levels.get_Item(0).CharacterFormat.FontSize = 14;
list_style.Levels.get_Item(0).TextPosition = 20;
// 将列表样式添加到文档
doc.ListStyles.Add(list_style);
// 添加标题段落
let paragraph = section.AddParagraph();
let text_range = paragraph.AppendText('水果:');
paragraph.Format.AfterSpacing = 5;
text_range.CharacterFormat.FontName = '宋体';
text_range.CharacterFormat.FontSize = 14;
// 向项目符号列表添加项目
const fruits = ['苹果', '香蕉', '西瓜', '芒果'];
fruits.forEach(fruit => {
paragraph = section.AddParagraph();
let text_range = paragraph.AppendText(fruit);
paragraph.ListFormat.ApplyStyle(list_style.Name);
paragraph.ListFormat.ListLevelNumber = 0;
text_range.CharacterFormat.FontName = '宋体';
text_range.CharacterFormat.FontSize = 14;
});
// 保存文档
const outputFileName = 'output.docx';
doc.SaveToFile({fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013});
// 创建用于下载文件的 Blob
const modifiedFileArray = wasmModule.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
const url = URL.createObjectURL(modifiedFile);
// 触发文件下载
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// 清理资源
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中向 Word 文档添加列表</h1>
<button onClick={AddList} disabled={!wasmModule}>
生成
</button>
</div>
);
}
export default App;
在 React 中添加表格到 Word
创建表格需使用 AddTable() 方法,并通过 ResetCells() 指定行列数。表格创建后,可结合 AddParagraph() 和 AppendText() 方法为单元格添加文本内容。使用 AutoFit() 方法可自动根据内容调整表格布局,确保数据呈现整洁有序。
在 React 中实现 Word 表格添加的步骤:
- 将所需字体文件加载至虚拟文件系统(VFS)。
- 使用 wasmModule.Document.Create() 初始化文档对象。
- 通过 Document.AddSection() 添加文档节。
- 创建二维数组存储表头和数据内容。
- 调用 Section.AddTable() 创建表格。
- 使用 Table.ResetCells() 根据数据量设定表格行列数。
- 遍历数据数组,通过 TableCell.AddParagraph() 和 Paragraph.AppendText() 填充单元格文本。
- 应用 Table.AutoFit() 实现内容自适应调整。
- 将文档保存为 DOCX 文件并触发下载。
- JavaScript
import React, { useState, useEffect } from 'react';
function App() {
// 保存加载的 WASM 模块
const [wasmModule, setWasmModule] = useState(null);
// 在组件挂载时加载 WASM 模块
useEffect(() => {
const loadWasm = async () => {
try {
// 从全局 window 对象访问 Module 和 spiredoc
const { Module, spiredoc } = window;
// 当运行时初始化时设置 wasmModule 状态
Module.onRuntimeInitialized = () => {
setWasmModule(spiredoc);
};
} catch (err) {
// 记录加载过程中发生的任何错误
console.error('加载 WASM 模块失败:', err);
}
};
// 创建一个脚本元素来加载 WASM JavaScript 文件
const script = document.createElement('script');
script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
script.onload = loadWasm;
// 将脚本添加到文档主体
document.body.appendChild(script);
// 清理函数,在组件卸载时移除脚本
return () => {
document.body.removeChild(script);
};
}, []);
// 向 Word 添加表格的函数
const AddTable = async () => {
if (wasmModule) {
// 将字体文件加载到虚拟文件系统 (VFS)
await wasmModule.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/`);
// 创建一个新文档
const doc = wasmModule.Document.Create();
// 添加一个章节
let section = doc.AddSection();
// 设置页面边距
section.PageSetup.Margins.All = 60;
// 定义表格数据
let data =
[
['产品', '单价', '数量', '小计'],
['A', '290', '120', '34800'],
['B', '350', '110', '38500'],
['C', '680', '140', '95200'],
];
// 添加表格
let table = section.AddTable({showBorder: true});
// 设置行数和列数
table.ResetCells(data.length , data[0].length);
// 将数据写入单元格
for (let r = 0; r < data.length; r++) {
let data_row = table.Rows.get(r);
data_row.Height = 20;
data_row.HeightType = wasmModule.TableRowHeightType.Exactly;
data_row.RowFormat.BackColor = wasmModule.Color.Empty();
for (let c = 0; c < data[r].length; c++) {
let cell = data_row.Cells.get(c);
cell.CellFormat.VerticalAlignment = wasmModule.VerticalAlignment.Middle;
let text_range = cell.AddParagraph().AppendText(data[r][c]);
text_range.CharacterFormat.FontName = '宋体';
text_range.CharacterFormat.FontSize = 14;
}
}
// 自动调整表格大小以适应单元格内容
table.AutoFit(wasmModule.AutoFitBehaviorType.AutoFitToContents);
// 保存文档
const outputFileName = 'output.docx';
doc.SaveToFile({fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013});
// 创建用于下载文件的 Blob
const modifiedFileArray = wasmModule.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
const url = URL.createObjectURL(modifiedFile);
// 触发文件下载
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// 清理资源
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中向 Word 文档添加表格</h1>
<button onClick={AddTable} disabled={!wasmModule}>
生成
</button>
</div>
);
}
export default App;
申请临时 License
如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。