Робота з розділами

Іноді потрібно, щоб формат документа не був однаковим для всіх сторінок. Наприклад, може знадобитися змінити формат нумерації сторінок, змінити розмір та орієнтацію сторінок або використовувати першу сторінку документа як титульну сторінку без будь-якої нумерації. Цього можна досягти за допомогою розділів.

Розділи-це вузли рівня, які керують верхніми та нижніми колонтитулами, орієнтацією, стовпцями, полями, форматуванням номерів сторінок та іншими параметрами.

Aspose.Words дозволяє керувати розділами, розділяти документ та вносити зміни у форматування, що застосовуються лише до певного розділу. Aspose.Words у розділі “розрив” зберігається інформація про форматування розділів, наприклад, колонтитули, налаштування сторінки та стовпців.

У цій статті пояснюється, як працювати з розділами та розривами розділів.

Що таке розділ і розрив розділу

Розділи документа представлені класами Section і SectionCollection. Об’єкти розділу є безпосередніми дочірніми об’єктами вузла Document, до яких можна отримати доступ за допомогою властивості Sections. Ви можете керувати цими вузлами, використовуючи деякі методи, такі як Remove, Add, IndexOf, та інші.

Розрив розділу-це опція, яка ділить сторінки документа на розділи зі спеціальним макетом.

Типи розриву розділу

Aspose.Words дозволяє розділяти і форматувати документи, використовуючи різні розбиття на розділи в перерахуванні BreakType:

  • SectionBreakContinuous
  • SectionBreakNewColumn
  • SectionBreakNewPage
  • SectionBreakEvenPage
  • SectionBreakOddPage

Ви також можете використовувати перерахування SectionStart, щоб вибрати тип розриву, який застосовується лише для першого розділу, наприклад NewColumn, NewPage, EvenPage, і OddPage.

Управління розділом

Оскільки розділ є звичайним складеним вузлом, для управління розділами можна використовувати всі маніпуляції з вузлами API: додавати, видаляти і виконувати інші операції з розділами. Детальніше про вузли ви можете прочитати в статті Aspose.Words Об’єктна модель документа (DOM).

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

Вставка або видалення розриву розділу

Aspose.Words дозволяє вставити розрив розділу в текст, використовуючи метод InsertBreak.

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

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
void WordToHtmlConverter::InsertSectionBreaks(System::SharedPtr<System::Collections::Generic::List<System::SharedPtr<Paragraph>>> topicStartParas)
{
auto builder = System::MakeObject<DocumentBuilder>(mDoc);
for (const auto& para : topicStartParas)
{
System::SharedPtr<Section> section = para->get_ParentSection();
// Insert section break if the paragraph is not at the beginning of a section already.
if (para != section->get_Body()->get_FirstParagraph())
{
builder->MoveTo(para->get_FirstChild());
builder->InsertBreak(BreakType::SectionBreakNewPage);
// This is the paragraph that was inserted at the end of the now old section.
// We don't really need the extra paragraph, we just needed the section.
section->get_Body()->get_LastParagraph()->Remove();
}
}
}

Використовуйте метод Remove, щоб видалити розрив розділу. Якщо вам не потрібно видаляти розрив певного розділу, а замість цього видалити вміст цього розділу, ви можете скористатися методом ClearContent.

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

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
void RemoveSectionBreaks(SharedPtr<Document> doc)
{
// Loop through all sections starting from the section that precedes the last one and moving to the first section.
for (int i = doc->get_Sections()->get_Count() - 2; i >= 0; i--)
{
// Copy the content of the current section to the beginning of the last section.
doc->get_LastSection()->PrependContent(doc->get_Sections()->idx_get(i));
// Remove the copied section.
doc->get_Sections()->idx_get(i)->Remove();
}
}

Перемістити розділ

Якщо ви хочете перемістити розділ з однієї позиції в іншу у своєму документі, вам потрібно отримати Індекс цього розділу. Aspose.Words дозволяє отримати позицію розділу з SectionCollection. Ви можете використовувати властивість Sections, щоб отримати всі розділи у вашому документі. Але якщо ви хочете отримати лише перший розділ, Ви можете використовувати властивість FirstSection.

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

// 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->Write(u"Section 1");
builder->MoveToHeaderFooter(HeaderFooterType::HeaderPrimary);
builder->Write(u"Primary header");
builder->MoveToHeaderFooter(HeaderFooterType::FooterPrimary);
builder->Write(u"Primary footer");
// A Section is a composite node and can contain child nodes,
// but only if those child nodes are of a "Body" or "HeaderFooter" node type.
for (const auto& srcSection : System::IterateOver(doc->get_Sections()->LINQ_OfType<SharedPtr<Section>>()))
{
for (const auto& srcNode : System::IterateOver(srcSection->get_Body()))
{
switch (srcNode->get_NodeType())
{
case NodeType::Body:
{
auto body = System::ExplicitCast<Body>(srcNode);
std::cout << "Body:" << std::endl;
std::cout << std::endl;
std::cout << "\t\"" << body->GetText().Trim() << "\"" << std::endl;
break;
}
case NodeType::HeaderFooter:
{
auto headerFooter = System::ExplicitCast<HeaderFooter>(srcNode);
auto headerFooterType = headerFooter->get_HeaderFooterType();
std::cout << "HeaderFooter type: " << static_cast<std::underlying_type<HeaderFooterType>::type>(headerFooterType) << std::endl;
std::cout << "\t\"" << headerFooter->GetText().Trim() << "\"" << std::endl;
break;
}
default:
{
throw System::Exception(u"Unexpected node type in a section.");
}
}
}
}

Вкажіть розташування розділу

Іноді ви хочете, щоб ваш документ виглядав краще, створюючи креативні макети для різних розділів документа. Якщо ви хочете вказати тип поточної сітки розділів, ви можете вибрати режим макета розділу, використовуючи перерахування SectionLayoutMode:

  • За замовчуванням
  • Сітка
  • LineGrid
  • SnapToChars

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

// 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);
// Enable pitching, and then use it to set the number of lines per page in this section.
// A large enough font size will push some lines down onto the next page to avoid overlapping characters.
builder->get_PageSetup()->set_LayoutMode(SectionLayoutMode::LineGrid);
builder->get_PageSetup()->set_LinesPerPage(15);
builder->get_ParagraphFormat()->set_SnapToGrid(true);
for (int i = 0; i < 30; i++)
builder->Write(u"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ");
doc->Save(ArtifactsDir + u"WorkingWithDocumentOptionsAndSettings.LinesPerPage.docx");

Редагувати розділ

Коли ви додаєте новий розділ до свого документа, у ньому не буде основної частини чи абзацу, які ви могли б відредагувати. Aspose.Words дозволяє гарантувати, що розділ містить основну частину принаймні з одним абзацом, використовуючи метод EnsureMinimum – він автоматично додасть основний вузол (або HeaderFooter) до документа, а потім додасть до нього абзац.

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

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>();
// If we add a new section like this, it will not have a body, or any other child nodes.
doc->get_Sections()->Add(MakeObject<Section>(doc));
// Run the "EnsureMinimum" method to add a body and a paragraph to this section to begin editing it.
doc->get_LastSection()->EnsureMinimum();
doc->get_Sections()->idx_get(0)->get_Body()->get_FirstParagraph()->AppendChild(MakeObject<Run>(doc, u"Hello world!"));

Додавати або доповнювати вміст

Якщо ви хочете намалювати якусь фігуру або додати текст або зображення на початку/кінці розділу, ви можете використовувати методи AppendContent та PrependContent класу Section.

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

// 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->Writeln(u"Hello1");
doc->AppendChild(MakeObject<Section>(doc));
builder->Writeln(u"Hello22");
doc->AppendChild(MakeObject<Section>(doc));
builder->Writeln(u"Hello3");
doc->AppendChild(MakeObject<Section>(doc));
builder->Writeln(u"Hello45");
// This is the section that we will append and prepend to.
SharedPtr<Section> section = doc->get_Sections()->idx_get(2);
// This copies the content of the 1st section and inserts it at the beginning of the specified section.
SharedPtr<Section> sectionToPrepend = doc->get_Sections()->idx_get(0);
section->PrependContent(sectionToPrepend);
// This copies the content of the 2nd section and inserts it at the end of the specified section.
SharedPtr<Section> sectionToAppend = doc->get_Sections()->idx_get(1);
section->AppendContent(sectionToAppend);

Клонувати розділ

Aspose.Words дозволяє дублювати розділ, створюючи його повну копію методом Clone.

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

// 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"Document.docx");
SharedPtr<Section> cloneSection = doc->get_Sections()->idx_get(0)->Clone();
view raw clone-section.h hosted with ❤ by GitHub

Копіювання розділів між документами

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

Aspose.Words дозволяє копіювати розділи між документами, використовуючи метод ImportNode.

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

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto srcDoc = MakeObject<Document>(MyDir + u"Document.docx");
auto dstDoc = MakeObject<Document>();
SharedPtr<Section> sourceSection = srcDoc->get_Sections()->idx_get(0);
auto newSection = System::ExplicitCast<Section>(dstDoc->ImportNode(sourceSection, true));
dstDoc->get_Sections()->Add(newSection);
dstDoc->Save(ArtifactsDir + u"WorkingWithSection.CopySection.docx");
view raw copy-section.h hosted with ❤ by GitHub

Робота з верхнім і нижнім колонтитулами розділів

Основні правила відображення верхнього або нижнього колонтитула для кожного розділу досить прості:

  1. Якщо в розділі немає власних колонтитулів певного типу, то він береться з попереднього розділу.
  2. Тип верхнього та нижнього колонтитулів, що відображаються на сторінці, регулюється налаштуваннями розділу “інша перша сторінка” та “різні парні та непарні сторінки” – якщо вони вимкнені, то власні заголовки розділів ігноруються.

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

Якщо ви хочете видалити текст із верхнього та нижнього колонтитулів, не видаляючи HeaderFooter об’єктів у вашому документі, ви можете скористатися методом ClearHeadersFooters. Крім того, ви можете використовувати метод DeleteHeaderFooterShapes, щоб видалити всі фігури з верхнього та нижнього колонтитулів у вашому документі.

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

У наступному прикладі коду показано, як видалити всі фігури з усіх верхніх і нижніх колонтитулів розділу:

Налаштування властивостей сторінки в розділі

Перед друком сторінки або документа може знадобитися налаштувати розмір і оформлення окремої сторінки або всього документа в цілому. За допомогою налаштування сторінки ви можете змінити параметри сторінок документа, такі як поля, орієнтація та розмір, для друку різних перших сторінок або непарних сторінок.

Aspose.Words дозволяє налаштувати властивості сторінок та розділів за допомогою класу PageSetup.

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

// 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->get_PageSetup()->set_Orientation(Orientation::Landscape);
builder->get_PageSetup()->set_LeftMargin(50);
builder->get_PageSetup()->set_PaperSize(PaperSize::Paper10x14);
doc->Save(ArtifactsDir + u"WorkingWithDocumentOptionsAndSettings.PageSetupAndSectionFormatting.docx");

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

// 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->Writeln(u"Hello1");
doc->AppendChild(MakeObject<Section>(doc));
builder->Writeln(u"Hello22");
doc->AppendChild(MakeObject<Section>(doc));
builder->Writeln(u"Hello3");
doc->AppendChild(MakeObject<Section>(doc));
builder->Writeln(u"Hello45");
// It is important to understand that a document can contain many sections,
// and each section has its page setup. In this case, we want to modify them all.
for (const auto& section : System::IterateOver<Section>(doc))
{
section->get_PageSetup()->set_PaperSize(PaperSize::Letter);
}
doc->Save(ArtifactsDir + u"WorkingWithSection.ModifyPageSetupInAllSections.doc");

Дивіться також