Робота зі стовпцями і рядками

Щоб краще контролювати роботу таблиць, дізнайтеся, як маніпулювати стовпцями та рядками.

Знайдіть індекс елемента таблиці

Управління стовпцями, рядками і осередками здійснюється шляхом звернення до вибраного вузла документа за його індексом. Пошук індексу будь-якого вузла передбачає збір усіх дочірніх вузлів типу element з батьківського вузла, а потім використання методу IndexOf для пошуку індексу потрібного вузла в колекції.

Знайдіть Індекс таблиці в документі

Іноді вам може знадобитися внести зміни до певної таблиці в документі. Для цього ви можете звернутися до таблиці за її індексом.

Наступний приклад коду показує, як отримати Індекс таблиці в документі:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto table = System::ExplicitCast<Table>(doc->GetChild(NodeType::Table, 0, true));
SharedPtr<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-C.git.
int rowIndex = table->IndexOf(table->get_LastRow());

Знайдіть Індекс комірки в рядку

Нарешті, вам може знадобитися внести зміни до певної комірки, і ви також можете зробити це за допомогою індексу комірки.

Наступний приклад коду показує, як отримати Індекс комірки в рядку:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
int cellIndex = row->IndexOf(row->get_Cells()->idx_get(4));

Робота з колонками

В об’єктній моделі документа Aspose.Words (DOM) вузол Table складається з Row вузлів, а потім з Cell вузлів. Таким чином, в об’єктній моделі документа Aspose.Words Document, як і в документах Word, відсутнє поняття стовпця.

За задумом, рядки таблиці в Microsoft Word і Aspose.Words повністю незалежні, а основні властивості і операції містяться тільки в рядках і осередках таблиці. Це дає таблицям можливість мати деякі цікаві атрибути:

  • Кожен рядок таблиці може містити абсолютно різну кількість комірок
  • По вертикалі осередки кожного рядка можуть мати різну ширину
  • Можна об’єднувати таблиці з різними форматами рядків і кількістю осередків

Будь-які операції, що виконуються зі стовпцями, насправді є “скороченнями”, які виконують операцію, колективно змінюючи клітинки рядків таким чином, що виглядає так, ніби вони застосовуються до стовпців. Тобто ви можете виконувати операції зі стовпцями, просто повторюючи Індекс однієї комірки рядка таблиці.

Наступний приклад коду спрощує такі операції, демонструючи клас facade, який збирає комірки, що складають “стовпець” таблиці:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
/// <summary>
/// Represents a facade object for a column of a table in a Microsoft Word document.
/// </summary>
class Column : public System::Object
{
public:
/// <summary>
/// Returns the cells which make up the column.
/// </summary>
ArrayPtr<SharedPtr<Cell>> get_Cells()
{
return GetColumnCells()->ToArray();
}
/// <summary>
/// Returns a new column facade from the table and supplied zero-based index.
/// </summary>
static SharedPtr<WorkingWithTables::Column> FromIndex(SharedPtr<Table> table, int columnIndex)
{
return WorkingWithTables::Column::MakeObject(table, columnIndex);
}
/// <summary>
/// Returns the index of the given cell in the column.
/// </summary>
int IndexOf(SharedPtr<Cell> cell)
{
return GetColumnCells()->IndexOf(cell);
}
/// <summary>
/// Inserts a brand new column before this column into the table.
/// </summary>
SharedPtr<WorkingWithTables::Column> InsertColumnBefore()
{
ArrayPtr<SharedPtr<Cell>> columnCells = get_Cells();
if (columnCells->get_Length() == 0)
{
throw System::ArgumentException(u"Column must not be empty");
}
// Create a clone of this column.
for (SharedPtr<Cell> cell : columnCells)
{
cell->get_ParentRow()->InsertBefore(cell->Clone(false), cell);
}
// This is the new column.
auto column = WorkingWithTables::Column::MakeObject(columnCells[0]->get_ParentRow()->get_ParentTable(), mColumnIndex);
// We want to make sure that the cells are all valid to work with (have at least one paragraph).
for (SharedPtr<Cell> cell : column->get_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>
void Remove()
{
for (SharedPtr<Cell> cell : get_Cells())
{
cell->Remove();
}
}
/// <summary>
/// Returns the text of the column.
/// </summary>
String ToTxt()
{
auto builder = System::MakeObject<System::Text::StringBuilder>();
for (SharedPtr<Cell> cell : get_Cells())
{
builder->Append(cell->ToString(SaveFormat::Text));
}
return builder->ToString();
}
private:
int mColumnIndex;
SharedPtr<Table> mTable;
Column(SharedPtr<Table> table, int columnIndex) : mColumnIndex(0)
{
if (table == nullptr)
{
throw System::ArgumentException(u"table");
}
mTable = table;
mColumnIndex = columnIndex;
}
MEMBER_FUNCTION_MAKE_OBJECT(Column, CODEPORTING_ARGS(SharedPtr<Table> table, int columnIndex), CODEPORTING_ARGS(table, columnIndex));
/// <summary>
/// Provides an up-to-date collection of cells which make up the column represented by this facade.
/// </summary>
SharedPtr<System::Collections::Generic::List<SharedPtr<Cell>>> GetColumnCells()
{
SharedPtr<System::Collections::Generic::List<SharedPtr<Cell>>> columnCells =
System::MakeObject<System::Collections::Generic::List<SharedPtr<Cell>>>();
for (const auto& row : System::IterateOver<Row>(mTable->get_Rows()))
{
SharedPtr<Cell> cell = row->get_Cells()->idx_get(mColumnIndex);
if (cell != nullptr)
{
columnCells->Add(cell);
}
}
return columnCells;
}
};
view raw column-class.h hosted with ❤ by GitHub

Наступний приклад коду показує, як вставити порожній стовпець у таблицю:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Tables.docx");
auto table = System::ExplicitCast<Table>(doc->GetChild(NodeType::Table, 0, true));
SharedPtr<WorkingWithTables::Column> column = WorkingWithTables::Column::FromIndex(table, 0);
// Print the plain text of the column to the screen.
std::cout << column->ToTxt() << std::endl;
// Create a new column to the left of this column.
// This is the same as using the "Insert Column Before" command in Microsoft Word.
SharedPtr<WorkingWithTables::Column> newColumn = column->InsertColumnBefore();
for (SharedPtr<Cell> cell : newColumn->get_Cells())
{
cell->get_FirstParagraph()->AppendChild(MakeObject<Run>(doc, String(u"Column Text ") + newColumn->IndexOf(cell)));
}

Наступний приклад коду показує, як видалити стовпець із таблиці в документі:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Tables.docx");
auto table = System::ExplicitCast<Table>(doc->GetChild(NodeType::Table, 1, true));
SharedPtr<WorkingWithTables::Column> column = WorkingWithTables::Column::FromIndex(table, 2);
column->Remove();
view raw remove-column.h hosted with ❤ by GitHub

Вкажіть рядки як рядки заголовка

Ви можете повторити перший рядок таблиці як рядок заголовка лише на першій сторінці або на кожній сторінці, якщо таблиця розділена на кілька частин. У Aspose.Words ви можете повторити рядок заголовка на кожній сторінці, використовуючи властивість HeadingFormat.

Ви також можете позначити кілька рядків заголовка, якщо такі рядки розташовані один за одним на початку таблиці. Для цього вам потрібно застосувати до цих рядків властивості HeadingFormat.

Наступний приклад коду показує, як створити таблицю, що містить рядки заголовка, які повторюються на наступних сторінках:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->StartTable();
builder->get_RowFormat()->set_HeadingFormat(true);
builder->get_ParagraphFormat()->set_Alignment(ParagraphAlignment::Center);
builder->get_CellFormat()->set_Width(100);
builder->InsertCell();
builder->Writeln(u"Heading row 1");
builder->EndRow();
builder->InsertCell();
builder->Writeln(u"Heading row 2");
builder->EndRow();
builder->get_CellFormat()->set_Width(50);
builder->get_ParagraphFormat()->ClearFormatting();
for (int i = 0; i < 50; i++)
{
builder->InsertCell();
builder->get_RowFormat()->set_HeadingFormat(false);
builder->Write(u"Column 1 Text");
builder->InsertCell();
builder->Write(u"Column 2 Text");
builder->EndRow();
}
doc->Save(ArtifactsDir + u"WorkingWithTables.RepeatRowsOnSubsequentPages.docx");

Слідкуйте за тим, щоб таблиці і рядки не розбивалися по сторінках

У деяких випадках вміст таблиці не повинно бути розділене по сторінках. Наприклад, якщо заголовок знаходиться над таблицею, заголовок і таблиця завжди повинні розташовуватися разом на одній сторінці, щоб зберегти належний зовнішній вигляд.

Є два окремі методи, які корисні для досягнення цієї функціональності:

  • Allow row break across pages, який застосовується до рядків таблиці
  • Keep with next, що застосовується до абзаців у клітинках таблиці

За замовчуванням вищевказані властивості відключені.

Слідкуйте за тим, щоб рядки не розбивалися на сторінки

Це передбачає обмеження розбиття вмісту всередині комірок рядка на сторінки. У Microsoft Word це можна знайти у властивостях таблиці як параметр “Дозволити розбиття рядка на сторінки”. В Aspose.Words ЦЕ знаходиться під об’єктом RowFormat з Row як властивість RowFormat.AllowBreakAcrossPages.

Наступний приклад коду показує, як вимкнути розбиття рядків на сторінки для кожного рядка таблиці:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Table spanning two pages.docx");
auto table = System::ExplicitCast<Table>(doc->GetChild(NodeType::Table, 0, true));
// Disable breaking across pages for all rows in the table.
for (const auto& row : System::IterateOver<Row>(table->get_Rows()))
{
row->get_RowFormat()->set_AllowBreakAcrossPages(false);
}
doc->Save(ArtifactsDir + u"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-C.git.
auto doc = MakeObject<Document>(MyDir + u"Table spanning two pages.docx");
auto table = System::ExplicitCast<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.
for (const auto& cell : System::IterateOver<Cell>(table->GetChildNodes(NodeType::Cell, true)))
{
cell->EnsureMinimum();
for (const auto& para : System::IterateOver<Paragraph>(cell->get_Paragraphs()))
{
if (!(cell->get_ParentRow()->get_IsLastRow() && para->get_IsEndOfCell()))
{
para->get_ParagraphFormat()->set_KeepWithNext(true);
}
}
}
doc->Save(ArtifactsDir + u"WorkingWithTables.KeepTableTogether.docx");