Pracuj z kolumnami i wierszami

Aby uzyskać większą kontrolę nad działaniem tabel, dowiedz się, jak manipulować kolumnami i wierszami.

Znajdź indeks elementu tabeli

Zarządzanie kolumnami, wierszami i komórkami odbywa się poprzez dostęp do wybranego węzła dokumentu według jego indeksu. Znalezienie indeksu dowolnego węzła polega na zebraniu wszystkich węzłów podrzędnych typu elementu z węzła nadrzędnego, a następnie zastosowaniu metody IndexOf w celu znalezienia indeksu żądanego węzła w kolekcji.

Znajdź indeks tabeli w dokumencie

Czasami może być konieczne wprowadzenie zmian w określonej tabeli w dokumencie. Aby to zrobić, możesz odwołać się do tabeli po jej indeksie.

Poniższy przykład kodu pokazuje, jak pobrać indeks tabeli w dokumencie:

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

Znajdź indeks wiersza w tabeli

Podobnie może być konieczne wprowadzenie zmian w konkretnym wierszu w wybranej tabeli. Aby to zrobić, możesz także odwołać się do wiersza po jego indeksie.

Poniższy przykład kodu pokazuje, jak pobrać indeks wiersza w tabeli:

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

Znajdź indeks komórki w wierszu

Na koniec może zaistnieć potrzeba wprowadzenia zmian w określonej komórce i można to zrobić również na podstawie indeksu komórki.

Poniższy przykład kodu pokazuje, jak pobrać indeks komórki w wierszu:

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

Pracuj z kolumnami

W Aspose.Words Document Object Model (DOM) węzeł Table składa się z węzłów Row, a następnie węzłów Cell. Zatem w modelu obiektowym Document Aspose.Words, podobnie jak w dokumentach programu Word, nie ma pojęcia kolumny.

Z założenia wiersze tabeli w Microsoft Word i Aspose.Words są całkowicie niezależne, a podstawowe właściwości i operacje zawarte są tylko w wierszach i komórkach tabeli. Dzięki temu tabele mogą mieć kilka interesujących atrybutów:

  • Każdy wiersz tabeli może mieć zupełnie inną liczbę komórek
  • W pionie komórki każdego wiersza mogą mieć różną szerokość
  • Możliwe jest łączenie tabel o różnych formatach wierszy i liczbie komórek

Wszelkie operacje wykonywane na kolumnach są w rzeczywistości “skrótami”, które wykonują operację poprzez zbiorczą zmianę komórek wierszy w taki sposób, że wygląda to tak, jakby były stosowane do kolumn. Oznacza to, że możesz wykonywać operacje na kolumnach, po prostu iterując po tym samym indeksie komórki wiersza tabeli.

Poniższy przykład kodu upraszcza takie operacje, udowadniając klasę fasadową, która zbiera komórki tworzące “kolumnę” tabeli:

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

Poniższy przykład kodu pokazuje, jak wstawić pustą kolumnę do tabeli:

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

Poniższy przykład kodu pokazuje, jak usunąć kolumnę z tabeli w dokumencie:

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

Określ wiersze jako wiersze nagłówka

Możesz powtórzyć pierwszy wiersz tabeli jako wiersz nagłówka tylko na pierwszej stronie lub na każdej stronie, jeśli tabela jest podzielona na kilka. W Aspose.Words możesz powtórzyć wiersz nagłówka na każdej stronie, korzystając z właściwości HeadingFormat.

Można także zaznaczyć wiele wierszy nagłówka, jeśli takie wiersze znajdują się jeden po drugim na początku tabeli. Aby to zrobić, musisz zastosować właściwości HeadingFormat do tych wierszy.

Poniższy przykład kodu pokazuje, jak zbudować tabelę zawierającą wiersze nagłówka powtarzające się na kolejnych stronach:

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

Zapobiegaj rozdzielaniu tabel i wierszy między stronami

Są sytuacje, w których zawartość tabeli nie powinna być dzielona na strony. Na przykład, jeśli tytuł znajduje się nad tabelą, tytuł i tabela powinny być zawsze przechowywane razem na tej samej stronie, aby zachować właściwy wygląd.

Aby osiągnąć tę funkcjonalność, przydatne są dwie oddzielne techniki:

  • Allow row break across pages, który jest stosowany do wierszy tabeli
  • Keep with next, który jest stosowany do akapitów w komórkach tabeli

Domyślnie powyższe właściwości są wyłączone.

Trzymaj awanturę przed przerywaniem stron

Wiąże się to z ograniczeniem podziału treści znajdujących się w komórkach wiersza na stronie. W Microsoft Word można to znaleźć w obszarze Właściwości tabeli jako opcję “Pozwól wierszowi na dzielenie stron”. W Aspose.Words można to znaleźć w obiekcie RowFormat Row jako właściwość RowFormat.AllowBreakAcrossPages.

Poniższy przykład kodu pokazuje, jak wyłączyć dzielenie wierszy na stronach dla każdego wiersza w tabeli:

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

Chroń tabelę przed pękaniem między stronami

Aby zapobiec podziałowi tabeli na strony, musimy określić, że chcemy, aby treść zawarta w tabeli pozostała razem.

Aby to zrobić, Aspose.Words wykorzystuje metodę, która pozwala użytkownikom wybrać tabelę i włączyć parametr KeepWithNext do formatu true dla każdego akapitu w komórkach tabeli. Wyjątkiem jest ostatni akapit w tabeli, który powinien być ustawiony na false.

Poniższy przykład kodu pokazuje, jak ustawić tabelę tak, aby znajdowała się razem na tej samej stronie:

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