使用列和行
要更好地控制表的工作方式,请了解如何操作列和行。
查找表元素索引
通过索引访问选定的文档节点来管理列、行和单元格。查找任意节点的索引涉及从父节点收集该元素类型的所有子节点,然后使用 IndexOf 方法在集合中查找所需节点的索引。
查找文档 {#find-the-index-of-table-in-a-document} 中表的索引
有时您可能需要对文档中的特定表格进行更改。为此,您可以通过索引引用表。
以下代码示例显示如何检索文档中表的索引:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Table table = (Table) doc.GetChild(NodeType.Table, 0, true); | |
NodeCollection allTables = doc.GetChildNodes(NodeType.Table, true); | |
int tableIndex = allTables.IndexOf(table); |
查找表 {#find-the-index-of-a-row-in-a-table} 中行的索引
同样,您可能需要对选定表中的特定行进行更改。为此,您还可以通过索引引用行。
以下代码示例显示如何检索表中行的索引:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
int rowIndex = table.IndexOf(table.LastRow); |
查找行 {#find-the-index-of-a-cell-in-a-row} 中单元格的索引
最后,您可能需要对特定单元格进行更改,您也可以通过单元格索引来完成此操作。
以下代码示例显示如何检索行中单元格的索引:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
int cellIndex = row.IndexOf(row.Cells[4]); |
使用列
在 Aspose.Words Document Object Model (DOM) 中,Table 节点由 Row 节点和 Cell 节点组成。因此,在 Aspose.Words 的 Document
对象模型中,就像在 Word 文档中一样,没有列的概念。
按照设计,Microsoft Word 和 Aspose.Words 中的表格行是完全独立的,基本属性和操作仅包含在表格的行和单元格中。这使得表能够具有一些有趣的属性:
- 每个表格行可以有完全不同数量的单元格
- 垂直方向上,每行的单元格可以有不同的宽度
- 可以连接具有不同行格式和单元格数量的表格
对列执行的任何操作实际上都是"快捷方式",它们通过集体更改行单元格来执行操作,使得它们看起来像是应用于列。也就是说,您可以通过简单地迭代同一表行单元格索引来对列执行操作。
以下代码示例通过证明一个外观类来简化此类操作,该外观类收集构成表"列"的单元格:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
/// <summary> | |
/// Represents a facade object for a column of a table in a Microsoft Word document. | |
/// </summary> | |
internal class Column | |
{ | |
private Column(Table table, int columnIndex) | |
{ | |
mTable = table ?? throw new ArgumentException("table"); | |
mColumnIndex = columnIndex; | |
} | |
/// <summary> | |
/// Returns a new column facade from the table and supplied zero-based index. | |
/// </summary> | |
public static Column FromIndex(Table table, int columnIndex) | |
{ | |
return new Column(table, columnIndex); | |
} | |
/// <summary> | |
/// Returns the cells which make up the column. | |
/// </summary> | |
public Cell[] Cells => GetColumnCells().ToArray(); | |
/// <summary> | |
/// Returns the index of the given cell in the column. | |
/// </summary> | |
public int IndexOf(Cell cell) | |
{ | |
return GetColumnCells().IndexOf(cell); | |
} | |
/// <summary> | |
/// Inserts a brand new column before this column into the table. | |
/// </summary> | |
public Column InsertColumnBefore() | |
{ | |
Cell[] columnCells = Cells; | |
if (columnCells.Length == 0) | |
throw new ArgumentException("Column must not be empty"); | |
// Create a clone of this column. | |
foreach (Cell cell in columnCells) | |
cell.ParentRow.InsertBefore(cell.Clone(false), cell); | |
// This is the new column. | |
Column column = new Column(columnCells[0].ParentRow.ParentTable, mColumnIndex); | |
// We want to make sure that the cells are all valid to work with (have at least one paragraph). | |
foreach (Cell cell in column.Cells) | |
cell.EnsureMinimum(); | |
// Increase the index which this column represents since there is now one extra column in front. | |
mColumnIndex++; | |
return column; | |
} | |
/// <summary> | |
/// Removes the column from the table. | |
/// </summary> | |
public void Remove() | |
{ | |
foreach (Cell cell in Cells) | |
cell.Remove(); | |
} | |
/// <summary> | |
/// Returns the text of the column. | |
/// </summary> | |
public string ToTxt() | |
{ | |
StringBuilder builder = new StringBuilder(); | |
foreach (Cell cell in Cells) | |
builder.Append(cell.ToString(SaveFormat.Text)); | |
return builder.ToString(); | |
} | |
/// <summary> | |
/// Provides an up-to-date collection of cells which make up the column represented by this facade. | |
/// </summary> | |
private List<Cell> GetColumnCells() | |
{ | |
List<Cell> columnCells = new List<Cell>(); | |
foreach (Row row in mTable.Rows) | |
{ | |
Cell cell = row.Cells[mColumnIndex]; | |
if (cell != null) | |
columnCells.Add(cell); | |
} | |
return columnCells; | |
} | |
private int mColumnIndex; | |
private readonly Table mTable; | |
} |
以下代码示例显示如何将空白列插入表中:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Tables.docx"); | |
Table table = (Table) doc.GetChild(NodeType.Table, 0, true); | |
Column column = Column.FromIndex(table, 0); | |
// Print the plain text of the column to the screen. | |
Console.WriteLine(column.ToTxt()); | |
// Create a new column to the left of this column. | |
// This is the same as using the "Insert Column Before" command in Microsoft Word. | |
Column newColumn = column.InsertColumnBefore(); | |
foreach (Cell cell in newColumn.Cells) | |
cell.FirstParagraph.AppendChild(new Run(doc, "Column Text " + newColumn.IndexOf(cell))); |
以下代码示例演示如何从文档的表中删除列:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Tables.docx"); | |
Table table = (Table) doc.GetChild(NodeType.Table, 1, true); | |
Column column = Column.FromIndex(table, 2); | |
column.Remove(); |
指定行作为标题行
您可以选择仅在第一页或每页(如果表格被拆分为多个)上重复表格中的第一行作为标题行。在 Aspose.Words 中,您可以使用 HeadingFormat 属性在每个页面上重复标题行。
如果多个标题行一个接一个地位于表的开头,您还可以标记多个标题行。为此,您需要将 HeadingFormat 属性应用于这些行。
以下代码示例演示如何构建一个包含在后续页面上重复的标题行的表:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
builder.StartTable(); | |
builder.RowFormat.HeadingFormat = true; | |
builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; | |
builder.CellFormat.Width = 100; | |
builder.InsertCell(); | |
builder.Writeln("Heading row 1"); | |
builder.EndRow(); | |
builder.InsertCell(); | |
builder.Writeln("Heading row 2"); | |
builder.EndRow(); | |
builder.CellFormat.Width = 50; | |
builder.ParagraphFormat.ClearFormatting(); | |
for (int i = 0; i < 50; i++) | |
{ | |
builder.InsertCell(); | |
builder.RowFormat.HeadingFormat = false; | |
builder.Write("Column 1 Text"); | |
builder.InsertCell(); | |
builder.Write("Column 2 Text"); | |
builder.EndRow(); | |
} | |
doc.Save(ArtifactsDir + "WorkingWithTables.RepeatRowsOnSubsequentPages.docx"); |
防止表和行跨页中断
有时,表格的内容不应跨页拆分。例如,如果标题位于表格上方,则标题和表格应始终保持在同一页面上,以保持正确的外观。
有两种单独的技术可用于实现此功能:
Allow row break across pages
,应用于表行Keep with next
,应用于表格单元格中的段落
默认情况下,上述属性被禁用。
防止行跨页中断
这涉及限制行单元格内的内容在页面上拆分。在 Microsoft Word 中,可以在"表属性"下找到"允许跨页断行"选项。在 Aspose.Words 中,可以在 Row 的 RowFormat 对象下找到该属性,作为属性 RowFormat.AllowBreakAcrossPages。
以下代码示例演示如何禁用表中每行的跨页断行:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Table spanning two pages.docx"); | |
Table table = (Table) doc.GetChild(NodeType.Table, 0, true); | |
// Disable breaking across pages for all rows in the table. | |
foreach (Row row in table.Rows) | |
row.RowFormat.AllowBreakAcrossPages = false; | |
doc.Save(ArtifactsDir + "WorkingWithTables.RowFormatDisableBreakAcrossPages.docx"); |
防止表格跨页
为了阻止表格跨页拆分,我们需要指定希望表格中包含的内容保持在一起。
为此,Aspose.Words 使用一种方法,允许用户选择一个表格,并为表格单元格内的每个段落启用 KeepWithNext 参数为 true。表中的最后一段例外,应将其设置为 false。
以下代码示例演示如何将表设置为在同一页面上保持在一起:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Table spanning two pages.docx"); | |
Table table = (Table) doc.GetChild(NodeType.Table, 0, true); | |
// We need to enable KeepWithNext for every paragraph in the table to keep it from breaking across a page, | |
// except for the last paragraphs in the last row of the table. | |
foreach (Cell cell in table.GetChildNodes(NodeType.Cell, true)) | |
{ | |
cell.EnsureMinimum(); | |
foreach (Paragraph para in cell.Paragraphs) | |
if (!(cell.ParentRow.IsLastRow && para.IsEndOfCell)) | |
para.ParagraphFormat.KeepWithNext = true; | |
} | |
doc.Save(ArtifactsDir + "WorkingWithTables.KeepTableTogether.docx"); |