在实际的文档开发中,表格的结构往往需要根据数据动态调整——报表数据行数不确定时需要动态添加行,字段调整时需要新增或移除列,冗余数据行需要一键删除。Spire.Doc for JavaScript 基于 WebAssembly 在浏览器端直接完成 Word 文档的编辑,通过虚拟文件系统(VFS)管理字体和文件资源,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript。以下示例默认已安装 Spire.Doc 并完成 WebAssembly 模块初始化。
添加和删除行
在报表生成和数据展示场景中,表格的行数通常是动态变化的。Spire.Doc 提供了 Rows.RemoveAt 方法删除指定行,Rows.Insert 方法在指定位置插入新行,以及 AddRow 方法在表格末尾追加行。核心流程分为三个阶段:首先通过 FetchFileToVFS 将字体文件和目标 Word 文件载入 WASM 虚拟文件系统;然后实例化 Document 加载文件,获取目标表格后调用行列操作方法;最后将文档保存并从 VFS 读取生成的文件,封装为 Blob 后触发浏览器下载。
function App() {
const AddOrDeleteRow = async () => {
// 获取 Spire.Doc WASM 模块
const wasmModule = window.wasmModule?.spiredoc;
// 检查模块是否就绪
if (!wasmModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 将字体和文档文件载入 VFS
await window.spire.FetchFileToVFS('msyh.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// 将示例 Word 文件载入 VFS
let inputFileName = "TableSample.docx";
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 加载文档
let doc = new wasmModule.Document();
doc.LoadFromFile(inputFileName);
let section = doc.Sections.get_Item(0);
let table = section.Tables.get_Item(0);
// 删除第 8 行
table.Rows.RemoveAt(7);
// 创建一个新行并插入到指定位置(第 2 行之后)
let row = new wasmModule.TableRow(doc);
for (let i = 0; i < table.Rows.get_Item(0).Cells.Count; i++) {
let tc = row.AddCell();
let paragraph = tc.AddParagraph();
paragraph.Format.HorizontalAlignment = wasmModule.HorizontalAlignment.Center;
paragraph.AppendText("Added");
}
table.Rows.Insert(2, row);
// 在表格末尾追加一行
table.AddRow();
// 定义输出文件名
const outputFileName = "AddOrDeleteRow_output.docx";
// 保存文档
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013 });
// 释放资源
doc.Close();
doc.Dispose();
// 从 VFS 读取生成的文件,触发下载
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>单击以下按钮以在 Word 表格中添加和删除行。</h1>
<button onClick={AddOrDeleteRow}>
Generate
</button>
</div>
);
}
export default App;
上述代码在已有表格上执行了三种行操作:删除第 8 行、在第 2 行之后插入一个包含 "Added" 文字的新行、在表格末尾追加一个空行,生成的 Word 文档效果如下:

添加和删除列
在表格结构调整场景中,经常需要新增字段列或移除冗余列。由于 Spire.Doc 的表格列操作是通过逐行操作单元格来实现的,因此需要自定义 AddColumn 和 RemoveColumn 辅助函数:添加列时遍历每一行并在指定索引处插入一个新的空白单元格;删除列时遍历每一行并移除指定索引处的单元格。
function AddColumn(table, columnIndex) {
let wasmModule = window.wasmModule.spiredoc;
for (let r = 0; r < table.Rows.Count; r++) {
let addCell = new wasmModule.TableCell(table.Document);
table.Rows.get_Item(r).Cells.Insert(columnIndex, addCell);
}
}
function RemoveColumn(table, columnIndex) {
for (let r = 0; r < table.Rows.Count; r++) {
table.Rows.get_Item(r).Cells.RemoveAt(columnIndex);
}
}
function App() {
const AddOrRemoveColumn = async () => {
// 获取 Spire.Doc WASM 模块
const wasmModule = window.wasmModule?.spiredoc;
// 检查模块是否就绪
if (!wasmModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 将示例文件载入 VFS
let inputFileName = "TableSample.docx";
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 加载文档
let doc = new wasmModule.Document();
doc.LoadFromFile(inputFileName);
// 获取第一个节和第一个表格
let section = doc.Sections.get_Item(0);
let table = section.Tables.get_Item(0);
// 在第 0 列之前添加一个空白列
let columnIndex1 = 0;
AddColumn(table, columnIndex1);
// 删除第 2 列
let columnIndex2 = 2;
RemoveColumn(table, columnIndex2);
// 定义输出文件名
const outputFileName = "AddOrRemoveColumn_output.docx";
// 保存文档
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013 });
// 释放资源
doc.Close();
doc.Dispose();
// 从 VFS 读取生成的文件,触发下载
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>单击以下按钮以在 Word 表格中添加和删除列。</h1>
<button onClick={AddOrRemoveColumn}>
Generate
</button>
</div>
);
}
export default App;
上述代码在表格第 0 列插入了一个空白列,同时删除了第 2 列,生成的 Word 文档效果如下:

常见问题
删除行后表格数据错乱
原因:表格中存在合并单元格时,直接按索引删除行会导致后续行的索引偏移,破坏合并结构。
解决:删除前检查目标行是否参与了合并。如果行中有合并单元格,可先解除合并再执行删除操作:
// 删除前检查单元格的合并状态
let cell = table.Rows.get_Item(rowIndex).Cells.get_Item(0);
let verticalMerge = cell.CellFormat.VerticalMerge;
if (verticalMerge === wasmModule.CellMerge.None) {
table.Rows.RemoveAt(rowIndex);
} else {
console.warn("该行包含合并单元格,建议先处理合并状态");
}
添加列后新列在文档中显示为空白
原因:AddColumn 函数仅插入了空白 TableCell 对象,未向新单元格中添加段落和文字内容。
解决:插入单元格后,遍历新列并添加段落和文字:
function AddColumn(table, columnIndex) {
let wasmModule = window.wasmModule.spiredoc;
for (let r = 0; r < table.Rows.Count; r++) {
let addCell = new wasmModule.TableCell(table.Document);
let paragraph = addCell.AddParagraph();
paragraph.AppendText("New Column");
table.Rows.get_Item(r).Cells.Insert(columnIndex, addCell);
}
}
删除列时索引越界
原因:传入的列索引超过了当前表格的最大列数,或者表格各行的列数不一致。
解决:删除前获取表格第一行的列数作为参考,确保索引不超出范围:
let maxColIndex = table.Rows.get_Item(0).Cells.Count - 1;
if (columnIndex <= maxColIndex) {
RemoveColumn(table, columnIndex);
}
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







