在React应用中动态生成包含目录的Word文档,能够显著提升数据报告、技术文档或业务材料的专业性与可读性,尤其当处理多章节长文档时,自动化的目录生成机制不仅消除了手动维护章节页码的繁琐,更确保了内容更新时目录与正文的实时同步。通过JavaScript开发者可以直接在前端操作Word文档,特别适合需要离线操作或严格数据管控的企业级应用场景。本文将介绍如何使用JavaScript在React应用中实现插入目录到Word文档。
- 用JavaScript插入默认风格目录到Word文档
- 用JavaScript插入自定义风格目录到Word文档
本文所使用的方法需要用到Spire.Doc for JavaScript,npm:npm i spire.doc
。
用JavaScript插入默认风格目录到Word文档
Spire.Doc for JavaScript通过WebAssembly模块来处理Word文档,我们可以直接在模块中创建文档,也可以将文档读取到虚拟文件系统中来对其进行修改。在插入目录到Word文档时,我们可以直接根据设置好的标题登记在Word文档中插入目录。如果文档没有设置标题级别,可以在插入目录前使用Paragraph.ApplyStyle(BuiltinStyle)
方法设置标题级别。
使用Paragraph.AppendTOC(lowerLevel: int, upperLevel: int)
方法可以在Word文档任意段落插入目录,并指定要显示的标题。需要注意插入目录后,使用Document.UpdateTableOfContents()
方法更新目录,以便正确显示其内容。操作步骤示例如下:
- 加载
Spire.Doc.Base.js
文件以初始化WebAssembly模块。 - 使用
wasmModule.FetchFileToVFS()
方法将Word文件加载到虚拟文件系统。 - 通过调用
wasmModule.Document.Create()
方法创建一个Document
实例。 - 利用
Document.LoadFromFile()
方法将Word文档加载到Document
实例中。 - 使用
Document.AddSection()
方法创建一个新的节。 - 使用
Section.AddParagraph()
方法在节中添加一个段落。 - 使用
Paragraph.AppendTOC()
方法添加目录到段落,并设置目录中展示的最大和最小标题等级。 - 使用
Document.Sections.Insert()
方法将目录节插入到文档合适的位置。 - 使用
Document.UpdateTableOfContents()
方法更新目录。 - 使用
Document.SaveToFile()
将将Word文档保存到虚拟文件系统。 - 读取并下载Word文档,或进行其他处理。
代码示例
import React, { useState, useEffect } from 'react';
function App() {
// State to store the loaded WASM module
const [wasmModule, setWasmModule] = useState(null);
// useEffect hook to load the WASM module when the component mounts
useEffect(() => {
const loadWasm = async () => {
try {
// Access the Module and spiredoc from the global window object
const { Module, spiredoc } = window;
// Set the wasmModule state when the runtime is initialized
Module.onRuntimeInitialized = () => {
setWasmModule(spiredoc);
};
} catch (err) {
// Log any errors that occur during module loading
console.error('Failed to load the WASM module:', err);
}
};
// Create a script element to load the WASM JavaScript file
const script = document.createElement('script');
script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
script.onload = loadWasm;
// Append the script to the document body
document.body.appendChild(script);
// Cleanup function to remove the script when the component unmounts
return () => {
document.body.removeChild(script);
};
}, []);
// 插入默认目录到Word文档的方法
const InsertTOCWord = async () => {
if (wasmModule) {
// 指定输入和输出文件名
const inputFileName = 'Sample94.docx';
const outputFileName = '默认目录.docx';
// 获取字体文件并添加到 VFS
await wasmModule.FetchFileToVFS('HarmonyOS_Sans_SC_Regular.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/`);
// 获取输入文件并添加到 VFS
await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);
// 创建 Document 对象
const doc = wasmModule.Document.Create();
// 加载 Word 文档
doc.LoadFromFile({ fileName: inputFileName });
// 创建一个新的节
const section = doc.AddSection();
// 在节中创建一个段落
const paragraph = section.AddParagraph();
// 插入目录到段落
paragraph.AppendTOC(1, 2);
// 将节插入到封面节之后
doc.Sections.Insert(1, section);
// 更新目录
doc.UpdateTableOfContents();
// 将文档保存到 VFS
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2019})
// 从 VFS 读取文档
const wordArray = await wasmModule.FS.readFile(outputFileName);
// 生成 Blob 对象,并触发下载 Word 文件
const blob = new Blob([wordArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${outputFileName}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中使用 JavaScript 插入默认目录到 Word 文档</h1>
<button onClick={InsertTOCWord} disabled={!wasmModule}>
插入并下载
</button>
</div>
);
}
export default App;
结果
代码示例
我们还可以通过初始化TableOfContent
对象来创建目录,并通过switch对其进行自定义。例如,"{\o \”1-2\” \\1-1}"
表示在目录中显示一级到三级的标题,并省略一级标题的页码。步骤示例如下:
- 加载
Spire.Doc.Base.js
文件以初始化WebAssembly模块。 - 使用
wasmModule.FetchFileToVFS()
方法将Word文件加载到虚拟文件系统。 - 通过调用
wasmModule.Document.Create()
方法创建一个Document
实例。 - 利用
Document.LoadFromFile()
方法将Word文档加载到Document
实例中。 - 使用
Document.AddSection()
方法创建一个新的节。 - 使用
Section.AddParagraph()
方法在节中添加一个段落。 - 使用
Document.Sections.Insert()
方法将节插入到文档合适的位置。 - 使用
wasmModule.TableOfContent.Create()
方法创建TableOfContent
对象。 - 使用
Paragraph.Items.Add()
方法将目录添加到新建的段落中。 - 使用
Paragraph.AppendFieldMark()
方法分别添加字段分隔和结束标记。 - 通过
Document.TOC
属性将该目录设置为当前文档的目录。 - 使用
Document.UpdateTableOfContents()
方法更新目录。 - 使用
Document.SaveToFile()
将将Word文档保存到虚拟文件系统。 - 读取并下载Word文档,或进行其他处理。
代码示例
import React, { useState, useEffect } from 'react';
function App() {
// State to store the loaded WASM module
const [wasmModule, setWasmModule] = useState(null);
// useEffect hook to load the WASM module when the component mounts
useEffect(() => {
const loadWasm = async () => {
try {
// Access the Module and spiredoc from the global window object
const { Module, spiredoc } = window;
// Set the wasmModule state when the runtime is initialized
Module.onRuntimeInitialized = () => {
setWasmModule(spiredoc);
};
} catch (err) {
// Log any errors that occur during module loading
console.error('Failed to load the WASM module:', err);
}
};
// Create a script element to load the WASM JavaScript file
const script = document.createElement('script');
script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
script.onload = loadWasm;
// Append the script to the document body
document.body.appendChild(script);
// Cleanup function to remove the script when the component unmounts
return () => {
document.body.removeChild(script);
};
}, []);
// 插入自定义目录到Word文档的方法
const InsertTOCWord = async () => {
if (wasmModule) {
// 指定输入和输出文件名
const inputFileName = 'Sample94.docx';
const outputFileName = '自定义目录.docx';
// 获取字体文件并添加到 VFS
await wasmModule.FetchFileToVFS('HarmonyOS_Sans_SC_Regular.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/`);
// 获取输入文件并添加到 VFS
await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);
// 创建 Document 对象
const doc = wasmModule.Document.Create();
// 加载 Word 文档
doc.LoadFromFile({ fileName: inputFileName });
// 创建一个新的节
const section = doc.AddSection();
// 在节中创建一个段落
const paragraph = section.AddParagraph();
// 将节插入到封面节之后
doc.Sections.Insert(1, section);
// 创建一个自定义目录
let toc = wasmModule.TableOfContent.Create(doc,`{\\o "1-2" \\n 1-1}`);
// 将目录添加到新建的段落中
paragraph.Items.Add(toc);
// 插入字段分隔符和归档结束标记,以结束 TOC 字段
paragraph.AppendFieldMark(wasmModule.FieldMarkType.FieldSeparator);
paragraph.AppendFieldMark(wasmModule.FieldMarkType.FieldEnd);
// 将该目录设置为文档的目录
doc.TOC = toc;
// 更新目录
doc.UpdateTableOfContents();
// 将文档保存到 VFS
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2019});
// 从 VFS 读取文档
const wordArray = await wasmModule.FS.readFile(outputFileName);
// 生成 Blob 对象,并触发下载 Word 文件
const blob = new Blob([wordArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${outputFileName}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中使用 JavaScript 插入自定义目录到 Word 文档</h1>
<button onClick={InsertTOCWord} disabled={!wasmModule}>
插入并下载
</button>
</div>
);
}
export default App;
结果
本文演示了如何使用JavaScript在Word文档中插入目录。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。