列と行を操作する

テーブルの動作をより詳細に制御するには、列と行を操作する方法を学習してください。

テーブル要素インデックス {#find-the-index-of-table-elements} を検索する

列、行、セルは、インデックスによって選択したドキュメント ノードにアクセスすることによって管理されます。ノードのインデックスを検索するには、親ノードから要素タイプのすべての子ノードを収集し、IndexOf メソッドを使用してコレクション内の目的のノードのインデックスを検索します。

ドキュメント内の表のインデックスを検索する

場合によっては、ドキュメント内の特定の表に変更を加える必要があるかもしれません。これを行うには、インデックスによってテーブルを参照できます。

次のコード例は、ドキュメント内のテーブルのインデックスを取得する方法を示しています。

// 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);

テーブル内の行のインデックスを検索する

同様に、選択したテーブルの特定の行を変更する必要がある場合があります。これを行うには、インデックスによって行を参照することもできます。

次のコード例は、テーブル内の行のインデックスを取得する方法を示しています。

// 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);

行内のセルのインデックスを見つける

最後に、特定のセルに変更を加える必要がある場合がありますが、これはセル インデックスによって行うこともできます。

次のコード例は、行内のセルのインデックスを取得する方法を示しています。

// 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;
}
view raw column-class.cs hosted with ❤ by GitHub

次のコード例は、テーブルに空の列を挿入する方法を示しています。

// 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");

テーブルと行がページをまたがらないようにする

表の内容を複数のページに分割すべきではない場合があります。たとえば、タイトルが表の上にある場合は、適切な外観を維持するために、タイトルと表を常に同じページ上にまとめて配置する必要があります。

この機能を実現するには、次の 2 つの個別の手法が役立ちます。

  • Allow row break across pages、テーブル行に適用されます
  • Keep with next。表のセル内の段落に適用されます。

デフォルトでは、上記のプロパティは無効になっています。

行がページをまたがらないようにする

これには、行のセル内のコンテンツがページ全体に分割されないように制限することが含まれます。 Microsoft Word では、これはテーブルのプロパティの下に「ページをまたがる行の分割を許可する」オプションとして表示されます。 Aspose.Words では、これは RowRowFormat オブジェクトの下にプロパティ 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");