Trabajar con Columnas y Filas

Para tener más control sobre el funcionamiento de las tablas, aprenda a manipular columnas y filas.

Buscar el Índice del Elemento de la Tabla

Las columnas, filas y celdas se administran accediendo al nodo de documento seleccionado por su índice. Encontrar el índice de cualquier nodo implica recopilar todos los nodos secundarios del tipo de elemento del nodo principal y luego usar el método IndexOf para encontrar el índice del nodo deseado en la colección.

Buscar el Índice de una Tabla en un Documento

A veces, es posible que deba realizar cambios en una tabla en particular de un documento. Para hacer esto, puede hacer referencia a una tabla por su índice.

El siguiente ejemplo de código muestra cómo recuperar el índice de una tabla en un documento:

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

Hallar el Índice de una Fila en una Tabla

Del mismo modo, es posible que deba realizar cambios en una fila específica de una tabla seleccionada. Para hacer esto, también puede hacer referencia a una fila por su índice.

El siguiente ejemplo de código muestra cómo recuperar el índice de una fila en una tabla:

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

Encuentra el Índice de una Celda en una Fila

Finalmente, es posible que deba realizar cambios en una celda específica, y también puede hacerlo mediante el índice de celda.

El siguiente ejemplo de código muestra cómo recuperar el índice de una celda en una fila:

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

Trabajar con Columnas

En el Aspose.Words Modelo de Objetos de documento (DOM), el nodo Table consta de Row nodos y luego Cell nodos. Por lo tanto, en el Modelo de Objetos de Documento de Aspose.Words, como en los documentos de Word, no existe el concepto de columna.

Por diseño, las filas de la tabla en Microsoft Word y Aspose.Words son completamente independientes, y las propiedades y operaciones básicas están contenidas solo en las filas y celdas de la tabla. Esto le da a las tablas la capacidad de tener algunos atributos interesantes:

  • Cada fila de la tabla puede tener un número completamente diferente de celdas
  • Verticalmente, las celdas de cada fila pueden tener diferentes anchos.
  • Es posible unir tablas con diferentes formatos de fila y número de celdas

Cualquier operación realizada en columnas son en realidad “accesos directos” que realizan la operación cambiando colectivamente las celdas de la fila de tal manera que parece que se están aplicando a las columnas. Es decir, puede realizar operaciones en columnas simplemente iterando sobre el mismo índice de celda de fila de tabla.

El siguiente ejemplo de código simplifica dichas operaciones al probar una clase facade que recopila las celdas que componen una “columna” de una tabla:

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

El siguiente ejemplo de código muestra cómo insertar una columna en blanco en una tabla:

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

El siguiente ejemplo de código muestra cómo eliminar una columna de una tabla en un documento:

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

Especificar Filas como Filas de Encabezado

Puede optar por repetir la primera fila de la tabla como Fila de encabezado solo en la primera página o en cada página si la tabla está dividida en varias. En Aspose.Words, puede repetir la fila del encabezado en cada página utilizando la propiedad HeadingFormat.

También puede marcar varias filas de encabezado si dichas filas se encuentran una tras otra al principio de la tabla. Para hacer esto, debe aplicar las propiedades HeadingFormat a estas filas.

El siguiente ejemplo de código muestra cómo crear una tabla que incluya filas de encabezado que se repitan en las páginas siguientes:

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

Evite que las Tablas y Filas se Dividan en Páginas

Hay ocasiones en las que el contenido de una tabla no debe dividirse en páginas. Por ejemplo, si un título está encima de una tabla, el título y la tabla siempre deben mantenerse juntos en la misma página para preservar la apariencia adecuada.

Hay dos técnicas separadas que son útiles para lograr esta funcionalidad:

  • Allow row break across pages, que se aplica a las filas de la tabla
  • Keep with next, que se aplica a párrafos en celdas de tabla

De forma predeterminada, las propiedades anteriores están deshabilitadas.

Evita que una Fila se Rompa En las Páginas

Esto implica restringir el contenido dentro de las celdas de una fila para que no se divida en una página. En Microsoft Word, esto se puede encontrar en Propiedades de la tabla como la opción “Permitir que la fila se divida entre páginas”. En Aspose.Words esto se encuentra debajo del objeto RowFormat de a Row como la propiedad RowFormat.AllowBreakAcrossPages.

El siguiente ejemplo de código muestra cómo deshabilitar la división de filas en páginas para cada fila de una tabla:

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

Evita que una Tabla se Divida en Páginas

Para evitar que la tabla se divida en páginas, debemos especificar que queremos que el contenido contenido en la tabla permanezca unido.

Para hacer esto, Aspose.Words usa un método que permite a los usuarios seleccionar una tabla y habilitar el parámetro KeepWithNext en verdadero para cada párrafo dentro de las celdas de la tabla. La excepción es el último párrafo de la tabla, que debe establecerse en falso.

El siguiente ejemplo de código muestra cómo configurar una tabla para que permanezcan juntas en la misma página:

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