Работа с разделами
Иногда требуется, чтобы формат документа не был одинаковым для всех страниц. Например, может потребоваться изменить формат нумерации страниц, изменить размер и ориентацию страниц или использовать первую страницу документа в качестве титульного листа без какой-либо нумерации. Этого можно добиться с помощью разделов.
Разделы - это узлы уровня, которые управляют верхними и нижними колонтитулами, ориентацией, столбцами, полями, форматированием номеров страниц и другими параметрами.
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(); |
Копирование разделов между документами
В некоторых случаях у вас могут быть большие документы с большим количеством разделов, и вы хотите скопировать содержимое раздела из одного документа в другой.
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"); |
Работа с верхним и нижним колонтитулами разделов
Основные правила отображения верхнего или нижнего колонтитула для каждого раздела довольно просты:
- Если в разделе нет собственных колонтитулов определенного типа, то он берется из предыдущего раздела.
- Тип верхнего и нижнего колонтитула, отображаемого на странице, регулируется настройками раздела “Другая первая страница” и “Разные четные и нечетные страницы” – если они отключены, то собственные заголовки раздела игнорируются.
В следующем примере кода показано, как создавать разделы 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"); |