C# 高效生成 Word 表格:复杂表格创建实战指南

咖啡半糖
咖啡半糖
发布时间:2026-08-24| 21人浏览过
原创

前言

在报表、合同、统计清单这类办公文档里,表格往往决定了信息是否清晰、输出是否规范。手工在 Word 里逐项调整不仅慢,而且一旦数据量变化,维护成本会迅速上升。本文以 Free Spire.Doc for .NET 为例,按“先理解对象模型,再完成格式化表格,最后处理动态结构和复杂布局”的顺序展开,帮助你判断它是否适合自己的文档生成场景,以及这些 API 分别该用在什么地方。

在报表、合同、统计清单这类办公文档里,表格往往决定了信息是否清晰、输出是否规范。手工在 Word 里逐项调整不仅慢,而且一旦数据量变化,维护成本会迅速上升。本文以 Free Spire.Doc for .NET 为例,按“先理解对象模型,再完成格式化表格,最后处理动态结构和复杂布局”的顺序展开,帮助你判断它是否适合自己的文档生成场景,以及这些 API 分别该用在什么地方。

安装 Free Spire.Doc for .NET:Install-Package FreeSpire.Doc

先理解 Word 表格的对象模型

在开始写代码前,先把 Word 文档里的对象层级理清楚,后面无论是设置样式、插入内容,还是操作某一行某一列,都会更顺手。

  • Document:整个 Word 文档对象
  • Section:文档分节,一个 Section 里可以放段落、表格等内容
  • Table:表格对象
  • TableRow:表格中的行
  • TableCell:表格中的单元格
  • Paragraph:正文或单元格里的段落
  • TextRange:段落中的实际文本内容
  • ParagraphStyle:段落样式,用来统一字体、字号、对齐方式等设置

如果把它看成一棵结构树,通常就是 Document -> Section -> Table -> TableRow -> TableCell -> Paragraph -> TextRange。理解这个结构后,你就能知道样式该挂在哪一层、内容应该追加到哪里,也更容易避免在单元格内重复创建格式配置。

如何创建并格式化一个可直接交付的表格

很多业务表格并不只是“把数据放进去”这么简单,还要兼顾标题、列宽、边框、表头底色、文本对齐等细节。下面这段代码展示了一个完整的销售统计表示例,包含从文档创建到表格填充的主要过程。

Word 表格创建与格式化流程信息图
Word 表格创建与样式配置流程用流程和参数卡片展示 C# 创建 Word 销售统计表时的结构、样式和数据填充顺序。
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System.Drawing;

public class WordTableDemo
{
    public static void CreateFormattedTable(string filePath)
    {
        Document doc = new Document();
        Section sec = doc.AddSection();

        // 添加标题
        Paragraph title = sec.AddParagraph();
        TextRange tr = title.AppendText("2025年度产品销售统计");
        tr.CharacterFormat.FontName = "Yu Gothic UI";
        tr.CharacterFormat.FontSize = 18;
        tr.CharacterFormat.Bold = true;
        title.Format.HorizontalAlignment = HorizontalAlignment.Center;

        sec.AddParagraph().AppendText("n"); // 间距

        // 创建表格
        Table table = sec.AddTable();
        table.ResetCells(5, 4); // 5行4列
        table.TableFormat.Borders.BorderType = BorderStyle.Single;
        table.TableFormat.Borders.LineWidth = 1f;
        table.TableFormat.Borders.Color = Color.DarkGray;

        // 设置列宽
        int[] colWidths = { 80, 200, 100, 120 };
        foreach (TableRow row in table.Rows)
        {
            for (int i = 0; i < colWidths.Length; i++)
                row.Cells[i].SetCellWidth(colWidths[i], CellWidthType.Point);
        }

        // 表头样式
        ParagraphStyle headerStyle = doc.AddParagraphStyle("headerStyle");
        headerStyle.CharacterFormat.Bold = true;
        headerStyle.CharacterFormat.FontName = "Yu Gothic UI";
        headerStyle.CharacterFormat.FontSize = 13;
        headerStyle.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center;

        string[] headers = { "产品编号", "产品名称", "销售数量", "销售金额" };
        for (int i = 0; i < headers.Length; i++)
        {
            TableCell cell = table.Rows[0].Cells[i];
            cell.CellFormat.BackColor = Color.LightSteelBlue;
            cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle;
            Paragraph p = cell.AddParagraph();
            p.AppendText(headers[i]);
            p.ApplyStyle(headerStyle.Name);
        }

        // 数据样式
        ParagraphStyle dataStyle = doc.AddParagraphStyle("dataStyle");
        dataStyle.CharacterFormat.FontName = "Yu Gothic UI";
        dataStyle.CharacterFormat.FontSize = 12;
        dataStyle.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center;

        string[,] data = {
            { "A101", "超薄笔记本", "120", "180000" },
            { "B202", "智能手机", "450", "540000" },
            { "C303", "无线耳机", "300", "90000" },
            { "D404", "智能手表", "200", "80000" }
        };

        for (int r = 0; r < data.GetLength(0); r++)
        {
            for (int c = 0; c < data.GetLength(1); c++)
            {
                TableCell cell = table.Rows[r + 1].Cells[c];
                Paragraph p = cell.AddParagraph();
                p.AppendText(data[r, c]);
                p.ApplyStyle(dataStyle.Name);
                cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle;
            }
        }

        doc.Sa veToFile(filePath, FileFormat.Docx);
        Console.WriteLine($"文档已生成:{filePath}");
    }
}

这段示例的重点,不只是能生成一个 5 行 4 列的表格,而是把常见的格式化动作集中做完:

标题和正文区域分开处理

标题通过 Paragraph 和 TextRange 单独设置字体、字号与加粗,再用 HorizontalAlignment.Center 居中。这样做的好处是,表格本身只负责数据展示,文档结构也更清晰。

Word 表格动态增删行列关系图
动态行列操作关系图把增删行列的四个方法拆成结构变化与索引检查两部分,方便读者理解不同 API 的职责。

先定表格骨架,再做样式铺设

table.ResetCells(5, 4) 先创建固定的 5 行 4 列结构,随后统一设置边框样式、线宽和颜色。对于报表类文档,这种“先搭框架、后填内容”的方式更容易维护。

单元格嵌套表格结构示意图
外层表格与内层表格的嵌套结构展示外层表格、目标单元格和内层表格之间的包含关系,以及不同边框样式和数据结构。

列宽和样式尽量统一配置

示例通过 int[] colWidths = { 80, 200, 100, 120 }; 给四列分别指定宽度,再循环写入每一行。这种做法适合列含义固定的业务表格,比如“编号、名称、数量、金额”这类结构明确的数据。

另外,表头和数据区分别定义 headerStyle 与 dataStyle,比在每个单元格里逐项设置字体更稳妥。后续如果要整体换字体、调整字号或对齐方式,也只需要改样式定义。

适合哪些场景

这种创建方式适合结构比较稳定的 Word 输出任务,例如销售统计、库存清单、日报周报、客户列表等。只要列数基本固定,就可以通过数组或数据库结果集把内容批量填入表格,生成速度和一致性都会比手工排版高得多。

数据量不固定时,怎样动态添加或删除行列

真实业务里,表格行数通常不会提前写死,甚至列也可能根据配置变化。这时就不能只靠一次 ResetCells 解决问题,还需要对行列进行增删。

// 添加新行
public static void AddRow(Table table, string[] rowData)
{
    TableRow newRow = table.AddRow();
    newRow.Height = 22;
    newRow.HeightType = TableRowHeightType.Auto;

    for (int i = 0; i < rowData.Length; i++)
    {
        TableCell cell = newRow.Cells[i];
        Paragraph p = cell.AddParagraph();
        p.AppendText(rowData[i]);
        p.Format.HorizontalAlignment = HorizontalAlignment.Center;
        cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle;
    }
}

// 删除行
public static void RemoveRow(Table table, int rowIndex)
{
    if (rowIndex >= 0 && rowIndex < table.Rows.Count)
        table.Rows.RemoveAt(rowIndex);
}

// 添加列
public static void AddColumn(Table table, int colIndex, string[] colData)
{
    for (int r = 0; r < table.Rows.Count; r++)
    {
        TableCell newCell = new TableCell(table.Document);
        table.Rows[r].Cells.Insert(colIndex, newCell);
        Paragraph p = newCell.AddParagraph();
        if (r < colData.Length) p.AppendText(colData[r]);
        p.Format.HorizontalAlignment = HorizontalAlignment.Center;
        newCell.CellFormat.VerticalAlignment = VerticalAlignment.Middle;
    }
}

// 删除列
public static void RemoveColumn(Table table, int colIndex)
{
    for (int r = 0; r < table.Rows.Count; r++)
    {
        if (colIndex >= 0 && colIndex < table.Rows[r].Cells.Count)
            table.Rows[r].Cells.RemoveAt(colIndex);
    }
}

这里可以把四个方法分成两组来看:行操作和列操作。

添加、删除行:适合明细持续增长的表格

AddRow 用 table.AddRow() 新增一行,然后按照传入的 rowData 逐个写入单元格内容,并补上水平居中和垂直居中的格式。这类方法很适合订单明细、流水记录、库存条目等“记录条数不固定”的场景。

RemoveRow 则通过索引判断后调用 table.Rows.RemoveAt(rowIndex) 删除指定行。索引边界判断虽然简单,但在批量处理数据时非常关键,否则很容易因为下标越界直接抛异常。

添加、删除列:适合报表字段按配置变化

AddColumn 的处理方式是遍历所有行,在每一行的指定位置插入一个新的 TableCell。这样可以确保整张表格都同步增加一列,而不是只改某一行导致结构错位。

这里有一个细节值得注意:新增列时使用的是 new TableCell(table.Document),说明单元格对象需要绑定到当前文档上下文里。随后再用 Cells.Insert(colIndex, newCell) 把它插入到目标位置,并根据 colData 按行填值。

RemoveColumn 的思路与之对应,遍历每一行后删除相同列索引处的单元格。只要索引校验做对,整张表就能保持一致。

动态表格更适合哪些业务

如果你的数据来自数据库查询、接口返回或用户勾选字段,表格结构往往不是固定的。此时,把“表格模板”和“增删逻辑”拆开会更好维护:基础样式负责整体观感,行列操作负责适配不同数据规模。对报表系统、审批单、导出清单来说,这种方式会比提前写死所有单元格更灵活。

复杂文档里,什么时候该用单元格嵌套表格

有些 Word 文档不是简单的二维数据展示,而是需要在一个大单元格内部继续承载子结构,例如合同条款的子项说明、问卷题目的附加选项、分区统计的局部明细等。这个时候,单元格内嵌套表格会比纯文本换行更清晰。

using Spire.Doc;
using Spire.Doc.Documents;

public class WordTableDemo
{
    public static void InsertNestedTable(string filePath)
    {
        Document doc = new Document();
        Section sec = doc.AddSection();

        sec.AddParagraph().AppendText("嵌套表格示例").CharacterFormat.FontSize = 16;
        sec.AddParagraph().AppendText("n");

        Table outer = sec.AddTable();
        outer.ResetCells(2, 2);
        outer.TableFormat.Borders.BorderType = BorderStyle.Single;

        outer.Rows[0].Cells[0].AddParagraph().AppendText("外表格 (0,0)");

        TableCell nestedCell = outer.Rows[0].Cells[1];
        nestedCell.AddParagraph().AppendText("内部表格如下:");

        Table inner = nestedCell.AddTable();
        inner.ResetCells(3, 2);
        inner.TableFormat.Borders.BorderType = BorderStyle.Dot;

        string[,] innerData = {
        { "编号", "名称" },
        { "001", "笔记本" },
        { "002", "手机" }
    };

        for (int r = 0; r < innerData.GetLength(0); r++)
        {
            for (int c = 0; c < innerData.GetLength(1); c++)
            {
                TableCell cell = inner.Rows[r].Cells[c];
                cell.AddParagraph().AppendText(innerData[r, c]);
                cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle;
                cell.Paragraphs[0].Format.HorizontalAlignment = HorizontalAlignment.Center;
            }
        }

        outer.Rows[1].Cells[0].AddParagraph().AppendText("外表格 (1,0)");
        outer.Rows[1].Cells[1].AddParagraph().AppendText("外表格 (1,1)");

        doc.Sa veToFile(filePath, FileFormat.Docx);
        Console.WriteLine($"嵌套表格文档已生成:{filePath}");
    }

    static void Main(string[] args)
    {
        InsertNestedTable("NestedTable.docx");
    }
}

这段代码的关键点在于,先创建一个外层表格 outer,再选中其中一个单元格 nestedCell,随后直接在该单元格里调用 AddTable() 创建内层表格 inner。

外层表格负责布局,内层表格负责明细

外层表格用 outer.ResetCells(2, 2) 构建基础布局,边框样式为 BorderStyle.Single。其中一个单元格作为承载区域,先追加说明文字“内部表格如下:”,再放入真正的子表。

这种结构很适合把“概览”和“细项”放在同一个区域内。例如左侧放条款标题,右侧放条款细目;或者上层单元格放统计分类,下层嵌套表放分类下的具体数据。

内层表格可以独立定义自己的结构和边框

内层表格通过 inner.ResetCells(3, 2) 创建 3 行 2 列,并把边框设为 BorderStyle.Dot。这说明嵌套表格并不是“继承外表格的一部分样式就结束了”,它本身仍然是完整的 Table 对象,可以单独设置边框、对齐和内容。

在示例里,innerData 数组中包含“编号、名称”以及两条明细数据,循环写入时继续设置垂直居中和段落居中。也就是说,嵌套后并不会失去常规表格的控制能力。

哪些文档值得用嵌套表格

如果只是简单的文本说明,直接段落换行通常已经够用;但当一个单元格里需要再表现一组有行列关系的数据时,嵌套表格更合适。常见场景包括合同附件项、问卷结果块、项目拆分清单、带子分类的统计表等。它的优势不在“更炫”,而在于层级更清楚,后续修改也更可控。

这套做法能解决哪些 Word 生成需求

综合来看,使用 C# 配合 Free Spire.Doc for .NET 处理 Word 表格,至少可以覆盖三类高频需求:

  1. 创建格式化表格,并统一设置列宽、行高、背景色和字体样式
  2. 动态添加或删除行列,适配数据量和字段结构变化
  3. 在单元格内嵌套表格,处理更复杂的排版和分层展示

如果你的目标是自动生成报表、合同、汇总文档或导出清单,这些能力已经能覆盖大部分核心环节。进一步结合 Free Spire.Doc 的其他 API,还可以继续扩展图片插入、分页控制、PDF 导出等功能,把原本依赖人工排版的 Word 输出流程改造成可复用的程序化方案。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。