使用列和行

要更好地控制表的工作方式,请了解如何操作列和行。

查找表元素索引

列,行和单元格通过其索引访问所选文档节点来管理。 查找任何节点的索引涉及从父节点收集元素类型的所有子节点,然后使用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);

在表{#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-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中,这是在RowRowFormat对象下作为属性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");