Lavorare con colonne e righe
Per un maggiore controllo sul funzionamento delle tabelle, scopri come manipolare colonne e righe.
Trova l’indice dell’elemento tabella
Le colonne, le righe e le celle vengono gestite accedendo al nodo del documento selezionato dal relativo indice. Trovare l’indice di qualsiasi nodo comporta la raccolta di tutti i nodi figlio del tipo di elemento dal nodo padre e quindi utilizzare il metodo IndexOf per trovare l’indice del nodo desiderato nella raccolta.
Trovare l’indice di una tabella in un documento
A volte potrebbe essere necessario apportare modifiche a una tabella particolare in un documento. Per fare ciò, puoi fare riferimento a una tabella in base al suo indice.
L’esempio di codice seguente mostra come recuperare l’indice di una tabella in 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); |
Trova l’indice di una riga in una tabella
Allo stesso modo, potrebbe essere necessario apportare modifiche a una riga specifica in una tabella selezionata. Per fare ciò, puoi anche fare riferimento a una riga dal suo indice.
L’esempio di codice seguente mostra come recuperare l’indice di una riga in una tabella:
// 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()); |
Trova l’indice di una cella in una riga
Infine, potrebbe essere necessario apportare modifiche a una cella specifica, e puoi farlo anche per indice di cella.
L’esempio di codice seguente mostra come recuperare l’indice di una cella in una riga:
// 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)); |
Lavorare con le colonne
Nel Aspose.Words Document Object Model (DOM), il nodo Table è costituito da nodi Row e quindi nodi Cell. Pertanto, nel modello a oggetti Document
di Aspose.Words, come nei documenti Word, non esiste il concetto di colonna.
In base alla progettazione, le righe della tabella in Microsoft Word e Aspose.Words sono completamente indipendenti e le proprietà e le operazioni di base sono contenute solo nelle righe e nelle celle della tabella. Questo dà alle tabelle la possibilità di avere alcuni attributi interessanti:
- Ogni riga della tabella può avere un numero completamente diverso di celle
- Verticalmente, le celle di ogni riga possono avere larghezze diverse
- È possibile unire tabelle con diversi formati di riga e numero di celle
Tutte le operazioni eseguite sulle colonne sono in realtà “scorciatoie” che eseguono l’operazione modificando collettivamente le celle di riga in modo tale che sembra che vengano applicate alle colonne. Cioè, è possibile eseguire operazioni su colonne semplicemente iterando sullo stesso indice di cella di riga della tabella.
Il seguente esempio di codice semplifica tali operazioni dimostrando una classe facade che raccoglie le celle che costituiscono una “colonna” di una tabella:
// 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; | |
} | |
}; |
L’esempio di codice seguente mostra come inserire una colonna vuota in una tabella:
// 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))); | |
} | |
L’esempio di codice seguente mostra come rimuovere una colonna da una tabella in 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(); |
Specificare le righe come righe di intestazione
È possibile scegliere di ripetere la prima riga della tabella come riga di intestazione solo nella prima pagina o in ogni pagina se la tabella è divisa in più. In Aspose.Words, è possibile ripetere la riga di intestazione su ogni pagina utilizzando la proprietà HeadingFormat.
È inoltre possibile contrassegnare più righe di intestazione se tali righe si trovano una dopo l’altra all’inizio della tabella. Per fare ciò, è necessario applicare le proprietà HeadingFormat a queste righe.
L’esempio di codice seguente mostra come creare una tabella che include righe di intestazione che si ripetono nelle pagine successive:
// 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"); |
Evitare che tabelle e righe si rompano tra le pagine
Ci sono momenti in cui il contenuto di una tabella non deve essere diviso tra le pagine. Ad esempio, se un titolo è sopra una tabella, il titolo e la tabella dovrebbero sempre essere tenuti insieme sulla stessa pagina per preservare l’aspetto corretto.
Ci sono due tecniche separate che sono utili per raggiungere questa funzionalità:
Allow row break across pages
, che viene applicato alle righe della tabellaKeep with next
, che viene applicato ai paragrafi nelle celle della tabella
Per impostazione predefinita, le proprietà di cui sopra sono disabilitate.
Evitare che una riga si rompa tra le pagine
Ciò comporta la limitazione del contenuto all’interno delle celle di una riga da dividere in una pagina. In Microsoft Word, questo può essere trovato sotto le proprietà della tabella come l’opzione “Consenti alla riga di suddividere le pagine”. In Aspose.Words questo si trova sotto l’oggetto RowFormat di un Row come proprietà RowFormat.AllowBreakAcrossPages.
L’esempio di codice seguente mostra come disabilitare l’interruzione delle righe tra le pagine per ogni riga di una tabella:
// 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"); |
Impedire a una tabella di attraversare le pagine
Per impedire che la tabella si divida tra le pagine, è necessario specificare che vogliamo che il contenuto contenuto all’interno della tabella rimanga insieme.
A tale scopo, Aspose.Words utilizza un metodo che consente agli utenti di selezionare una tabella e abilitare il parametro KeepWithNext su true per ogni paragrafo all’interno delle celle della tabella. L’eccezione è l’ultimo paragrafo della tabella, che dovrebbe essere impostato su false.
Il seguente esempio di codice mostra come impostare una tabella per stare insieme sulla stessa pagina:
// 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"); |