Робота зі стилями
Клас StyleCollection використовується для управління вбудованими та застосування налаштувань Користувача до стилів.
Як витягти контент на основі стилів
На простому рівні вилучення вмісту на основі стилів із документа Word може бути корисним для ідентифікації, складання списку та підрахунку абзаців та фрагментів тексту, відформатованих у певному стилі. Наприклад, вам може знадобитися визначити певні типи вмісту в документі, такі як приклади, заголовки, посилання, ключові слова, назви малюнків та тематичні дослідження.
Якщо зробити ще кілька кроків вперед, це також може бути використано для вдосконалення структури документа, визначеної використовуваними стилями, для перепризначення документа для іншого виводу, наприклад HTML. Насправді саме так створюється документація Aspose, що дозволяє протестувати Aspose.Words. Інструмент, створений за допомогою Aspose.Words, бере оригінальні документи Word і розбиває їх на теми з певними рівнями заголовків. За допомогою Aspose.Words створюється файл XML, який використовується для побудови дерева навігації, яке ви можете бачити зліва. А потім Aspose.Words перетворює кожну тему на HTML.
Рішення для вилучення тексту, відформатованого за певними стилями, у документі Word, Як правило, є економічним та простим за допомогою Aspose.Words.
Рішення
Щоб проілюструвати, як легко Aspose.Words обробляє пошук вмісту на основі стилів, давайте розглянемо приклад. У цьому прикладі ми збираємося витягти текст, відформатований за допомогою певного стилю абзацу та стилю символів, із зразка документа Word. На високому рівні це вимагатиме:
- Відкриття документа Word за допомогою класу
Document
. - Отримання колекцій всіх абзаців і всіх прогонів в документі.
- Вибираємо тільки потрібні абзаци і запускаємо. Зокрема, ми витягуємо текст, відформатований у стилі абзацу “Heading 1” та стилі символів “інтенсивний акцент”, із цього зразка документа Word.
У цьому прикладі документа текст, відформатований у стилі абзацу “Heading 1”, містить “вставка вкладки”, “швидкі стилі” та “Тема”, а текст, відформатований у стилі символів “інтенсивний акцент”, - це кілька варіантів тексту, виділеного синім, курсивом, жирним шрифтом, наприклад ‘галереї’ та ‘загальний вигляд’.
Код
Реалізація запиту на основі стилю в об’єктній моделі документа Aspose.Words досить проста, оскільки вона просто використовує вже наявні інструменти. Для цього рішення реалізовано два методи класу:# ParagraphsByStyleName – цей метод витягує масив тих абзаців у документі, які мають певну назву стилю.# RunsByStyleName - цей метод витягує масив тих фрагментів у документі, які мають певну назву стилю. Обидва ці методи дуже схожі, єдиними відмінностями є типи вузлів та представлення інформації про стиль у вузлах абзацу та запуску. Ось реалізація ParagraphsByStyleName. У наведеному нижче прикладі знайдіть усі абзаци, відформатовані у вказаному стилі.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
std::vector<System::SharedPtr<Paragraph>> ParagraphsByStyleName(System::SharedPtr<Document> doc, System::String const &styleName) | |
{ | |
// Create an array to collect paragraphs of the specified style. | |
std::vector<System::SharedPtr<Paragraph>> paragraphsWithStyle; | |
// Get all paragraphs from the document. | |
System::SharedPtr<NodeCollection> paragraphs = doc->GetChildNodes(NodeType::Paragraph, true); | |
// Look through all paragraphs to find those with the specified style. | |
for (System::SharedPtr<Paragraph> paragraph : System::IterateOver<System::SharedPtr<Paragraph>>(paragraphs)) | |
{ | |
if (paragraph->get_ParagraphFormat()->get_Style()->get_Name() == styleName) | |
{ | |
paragraphsWithStyle.push_back(paragraph); | |
} | |
} | |
return paragraphsWithStyle; | |
} |
Ця реалізація також використовує метод Document.GetChildNodes
класу Document
, який повертає колекцію всіх вузлів із зазначеним типом, який у цьому випадку міститься у всіх абзацах.
Зверніть увагу, що другому параметру методу Document.GetChildNodes присвоєно значення true. Це змушує метод Document.GetChildNodes рекурсивно вибирати з усіх дочірніх вузлів, а не вибирати лише безпосередні дочірні вузли.
Варто також зазначити, що колекція paragraphs не створює негайних накладних витрат, оскільки абзаци завантажуються до цієї колекції лише тоді, коли ви отримуєте доступ до елементів у них. Потім все, що вам потрібно зробити, це переглянути колекцію, використовуючи стандарт для кожного оператора, і додати абзаци, що мають вказаний стиль, до масиву paragraphsWithStyle. Назву стилю Paragraph
можна знайти у властивості Style. Name об’єкта Paragraph.ParagraphFormat
. Реалізація RunsByStyleName майже однакова, хоча ми, очевидно, використовуємо NodeType.Run
для вилучення вузлів запуску. Властивість Font.Style
об’єкта Run
використовується для доступу до інформації про стиль у вузлах Run. У прикладі below code знайдені всі прогони, відформатовані відповідно до зазначеного стилю.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
std::vector<System::SharedPtr<Run>> RunsByStyleName(System::SharedPtr<Document> doc, System::String const &styleName) | |
{ | |
// Create an array to collect runs of the specified style. | |
std::vector<System::SharedPtr<Run>> runsWithStyle; | |
// Get all runs from the document. | |
System::SharedPtr<NodeCollection> runs = doc->GetChildNodes(NodeType::Run, true); | |
// Look through all runs to find those with the specified style. | |
for (System::SharedPtr<Run> run : System::IterateOver<System::SharedPtr<Run>>(runs)) | |
{ | |
if (run->get_Font()->get_Style()->get_Name() == styleName) | |
{ | |
runsWithStyle.push_back(run); | |
} | |
} | |
return runsWithStyle; | |
} |
Коли обидва запити будуть реалізовані, все, що вам потрібно зробити, це передати об’єкт document і вказати назви стилів вмісту, який ви хочете отримати: у наведеному нижче прикладі виконуйте запити та відображайте результати. Ви можете завантажити файл шаблону для цього прикладу тут.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// The path to the documents directory. | |
System::String inputDataDir = GetInputDataDir_WorkingWithStyles(); | |
// Open the document. | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"TestFile.doc"); | |
// Define style names as they are specified in the Word document. | |
const System::String paraStyle = u"Heading 1"; | |
const System::String runStyle = u"Intense Emphasis"; | |
// Collect paragraphs with defined styles. | |
// Show the number of collected paragraphs and display the text of this paragraphs. | |
std::vector<System::SharedPtr<Paragraph>> paragraphs = ParagraphsByStyleName(doc, paraStyle); | |
std::cout << "Paragraphs with \"" << paraStyle.ToUtf8String() << "\" styles (" << paragraphs.size() << "):" << std::endl; | |
for (System::SharedPtr<Paragraph> paragraph : paragraphs) | |
{ | |
std::cout << paragraph->ToString(SaveFormat::Text).ToUtf8String(); | |
} | |
std::cout << std::endl; | |
// Collect runs with defined styles. | |
// Show the number of collected runs and display the text of this runs. | |
std::vector<System::SharedPtr<Run>> runs = RunsByStyleName(doc, runStyle); | |
std::cout << "Runs with \"" << runStyle.ToUtf8String() << "\" styles (" << runs.size() << "):" << std::endl; | |
for (System::SharedPtr<Run> run : runs) | |
{ | |
std::cout << run->get_Range()->get_Text().ToUtf8String() << std::endl; | |
} |
Кінцевий результат
Коли все буде зроблено, при запуску прикладу відобразиться наступний результат:
Як бачите, це дуже простий приклад, що показує кількість та текст зібраних абзаців та прогонів у зразку документа Word.
Інструкція по вставці поля змісту і роботі з ним
Часто доводиться працювати з документами, що містять Зміст (TOC). Використовуючи Aspose.Words, ви можете вставити власний зміст або повністю відновити існуючий зміст у документі, використовуючи лише кілька рядків коду. У цій статті описується, як працювати з полем змісту, і демонструється:
- Як вставити абсолютно новий
TOC
- Оновіть нові або існуючі TOCs у документі.
- Вкажіть параметри для управління форматуванням і загальною структурою TOC.
- Як змінити стилі і зовнішній вигляд змісту.
- Як видалити все поле
TOC
разом з усіма записами з документа цілком.
Вставити TC полів
Часто для TOC
призначається певний рядок тексту, який позначається полем TC
. Простий спосіб зробити це в MS Word - виділити текст і натиснути ALT+SHIFT+O. При цьому автоматично створюється поле TC
з використанням виділеного тексту. Той самий метод може бути реалізований за допомогою коду. Наведений нижче код знайде текст, що відповідає введеним даним, і Вставить поле TC
в тому ж місці, що і текст. Код заснований на тому ж методі, який використовувався в статті. У наведеному нижче прикладі показано, як знайти та вставити поле TC
у текст документа.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(); | |
System::SharedPtr<FindReplaceOptions> options = System::MakeObject<FindReplaceOptions>(); | |
// Highlight newly inserted content. | |
options->get_ApplyFont()->set_HighlightColor(System::Drawing::Color::get_DarkOrange()); | |
options->set_ReplacingCallback(System::MakeObject<InsertTCFieldHandler>(u"Chapter 1", u"\\l 1")); | |
// Insert a TC field which displays "Chapter 1" just before the text "The Beginning" in the document. | |
doc->get_Range()->Replace(System::MakeObject<System::Text::RegularExpressions::Regex>(u"The Beginning"), u"", options); |
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
class InsertTCFieldHandler : public IReplacingCallback | |
{ | |
typedef InsertTCFieldHandler ThisType; | |
typedef IReplacingCallback BaseType; | |
typedef ::System::BaseTypesInfo<BaseType> ThisTypeBaseTypesInfo; | |
public: | |
InsertTCFieldHandler(const System::String& text, const System::String& switches) | |
: mFieldText(text), mFieldSwitches(switches) {} | |
InsertTCFieldHandler(const System::String& switches) | |
: mFieldText(System::String::Empty), mFieldSwitches(switches) {} | |
ReplaceAction Replacing(System::SharedPtr<ReplacingArgs> args) override; | |
private: | |
System::String mFieldText; | |
System::String mFieldSwitches; | |
}; | |
ReplaceAction InsertTCFieldHandler::Replacing(System::SharedPtr<ReplacingArgs> args) | |
{ | |
// Create a builder to insert the field. | |
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(System::DynamicCast<Document>(args->get_MatchNode()->get_Document())); | |
// Move to the first node of the match. | |
builder->MoveTo(args->get_MatchNode()); | |
// If the user specified text to be used in the field as display text then use that, otherwise use the | |
// Match string as the display text. | |
System::String insertText; | |
if (!System::String::IsNullOrEmpty(mFieldText)) | |
{ | |
insertText = mFieldText; | |
} | |
else | |
{ | |
insertText = args->get_Match()->get_Value(); | |
} | |
// Insert the TC field before this node using the specified string as the display text and user defined switches. | |
builder->InsertField(System::String::Format(u"TC \"{0}\" {1}", insertText, mFieldSwitches)); | |
// We have done what we want so skip replacement. | |
return ReplaceAction::Skip; | |
} |
Змінити зміст
Змініть форматування стилів
Форматування записів у TOC
не використовує оригінальні стилі позначених записів, натомість кожен рівень форматується за допомогою еквівалентного стилю TOC
. Наприклад, перший рівень в TOC
відформатований в стилі TOC1, другий рівень відформатований в стилі TOC2 і так далі. Це означає, що для зміни зовнішнього вигляду TOC
ці стилі повинні бути змінені. У Aspose.Words ці стилі представлені незалежними від мови параметрами (StyleIdentifier.TOC1
до StyleIdentifier.TOC9
) і можуть бути вилучені з колекції Document.Styles
за допомогою цих ідентифікаторів. Як тільки відповідний стиль документа буде отримано, форматування для цього стилю може бути змінено. Будь-які зміни в цих стилях будуть автоматично відображені в TOCs документі. У прикладі below code змінюється властивість форматування, що використовується в стилі першого рівня TOC
.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(); | |
// Retrieve the style used for the first level of the TOC and change the formatting of the style. | |
doc->get_Styles()->idx_get(StyleIdentifier::Toc1)->get_Font()->set_Bold(true); |
Також корисно зазначити, що будь-яке пряме форматування абзацу (визначене в самому абзаці, а не в стилі), позначене для включення як TOC
, буде скопійовано до запису в TOC. Наприклад, якщо стиль Heading 1 використовується для виділення вмісту для TOC
, і цей стиль має напівжирне оформлення, тоді як до абзацу також безпосередньо застосовується курсивне форматування. Отриманий запис TOC
не буде виділений жирним шрифтом, оскільки це частина стилістичного оформлення, однак він буде виділений курсивом, оскільки він безпосередньо відформатований в абзаці. Ви також можете керувати форматуванням роздільників, що використовуються між кожним записом та номером сторінки. За замовчуванням це пунктирна лінія, яка перетинається з нумерацією сторінок за допомогою символу табуляції та правої точки табуляції, розташованої поруч із правим полем.
Використовуючи клас Style
, отриманий для певного рівня TOC
, який ви хочете змінити, ви також можете змінити його відображення в документі. Щоб змінити його відображення, спочатку потрібно викликати Style.ParagraphFormat
, щоб отримати форматування абзацу для стилю. З цього можна витягти значення табуляції, викликавши команду ParagraphFormat.TabStops
і змінивши відповідне значення табуляції. Використовуючи цей же метод, можна перемістити або повністю видалити саму табуляцію. У прикладі below code показано, як змінити положення правої кнопки табуляції в TOC
відповідних абзацах. Ви можете завантажити файл шаблону для цього прикладу тут.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// The path to the documents directories. | |
System::String inputDataDir = GetInputDataDir_WorkingWithStyles(); | |
System::String outputDataDir = GetOutputDataDir_WorkingWithStyles(); | |
// Open the document. | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"Document.TableOfContents.doc"); | |
// Iterate through all paragraphs in the document | |
for (System::SharedPtr<Paragraph> para : System::IterateOver<System::SharedPtr<Paragraph>>(doc->GetChildNodes(NodeType::Paragraph, true))) | |
{ | |
// Check if this paragraph is formatted using the TOC result based styles. This is any style between TOC and TOC9. | |
if (para->get_ParagraphFormat()->get_Style()->get_StyleIdentifier() >= StyleIdentifier::Toc1 && para->get_ParagraphFormat()->get_Style()->get_StyleIdentifier() <= StyleIdentifier::Toc9) | |
{ | |
// Get the first tab used in this paragraph, this should be the tab used to align the page numbers. | |
System::SharedPtr<TabStop> tab = para->get_ParagraphFormat()->get_TabStops()->idx_get(0); | |
// Remove the old tab from the collection. | |
para->get_ParagraphFormat()->get_TabStops()->RemoveByPosition(tab->get_Position()); | |
// Insert a new tab using the same properties but at a modified position. | |
// We could also change the separators used (dots) by passing a different Leader type | |
para->get_ParagraphFormat()->get_TabStops()->Add(tab->get_Position() - 50, tab->get_Alignment(), tab->get_Leader()); | |
} | |
} | |
System::String outputPath = outputDataDir + u"ChangeTOCTabStops.doc"; | |
doc->Save(outputPath); |
Видалення змісту з документа
Зміст можна видалити з документа, видаливши всі вузли, що знаходяться між вузлами FieldStart
і FieldEnd поля TOC
. Наведений нижче код демонструє це. Видалення поля TOC
простіше, ніж звичайного поля, оскільки ми не відстежуємо вкладені поля. Натомість ми перевіряємо, що вузол FieldEnd
має тип FieldType.FieldTOC
, Що означає, що ми зіткнулися з кінцем поточного TOC. Цей метод можна використовувати в цьому випадку, не турбуючись про будь-які вкладені поля, оскільки ми можемо припустити, що будь-який добре сформований документ не матиме повністю вкладеного поля TOC
всередині іншого поля TOC
. Спочатку збираються і зберігаються вузли FieldStart
кожного поля TOC
. Вказаний TOC
потім перераховується, щоб усі вузли в полі були відвідані та збережені. Потім вузли видаляються з документа. У прикладі below code показано, як видалити вказаний TOC
з документа. Ви можете завантажити файл шаблону для цього прикладу тут.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// The path to the documents directories. | |
System::String inputDataDir = GetInputDataDir_WorkingWithStyles(); | |
System::String outputDataDir = GetOutputDataDir_WorkingWithStyles(); | |
// Open a document which contains a TOC. | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"Document.TableOfContents.doc"); | |
// Remove the first table of contents from the document. | |
RemoveTableOfContents(doc, 0); | |
System::String outputPath = outputDataDir + u"RemoveTOCFromDocument.doc"; | |
// Save the output. | |
doc->Save(outputPath); |
Вставте роздільник стилів для розміщення різних стилів абзаців
Роздільник стилів можна додати до кінця абзацу за допомогою комбінації клавіш Ctrl + Alt + Enter у MS Word. Ця функція дозволяє використовувати два різні стилі абзацу в одному логічному друкованому абзаці. Якщо ви хочете, щоб зміст відображав текст із початку певного заголовка, але не весь заголовок, ви можете скористатися цією функцією. У прикладі below code показано, як вставити роздільник стилів, щоб використовувати різні стилі абзаців.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(); | |
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc); | |
System::SharedPtr<Style> paraStyle = builder->get_Document()->get_Styles()->Add(StyleType::Paragraph, u"MyParaStyle"); | |
paraStyle->get_Font()->set_Bold(false); | |
paraStyle->get_Font()->set_Size(8); | |
paraStyle->get_Font()->set_Name(u"Arial"); | |
// Append text with "Heading 1" style. | |
builder->get_ParagraphFormat()->set_StyleIdentifier(StyleIdentifier::Heading1); | |
builder->Write(u"Heading 1"); | |
builder->InsertStyleSeparator(); | |
// Append text with another style. | |
builder->get_ParagraphFormat()->set_StyleName(paraStyle->get_Name()); | |
builder->Write(u"This is text with some other formatting "); | |
System::String outputPath = outputDataDir + u"InsertStyleSeparator.doc"; | |
// Save the document to disk. | |
doc->Save(outputPath); |
Скопіюйте всі стилі з шаблону
Бувають випадки, коли потрібно скопіювати всі стилі з одного документа в інший. Ви можете використовувати метод Document.CopyStylesFromTemplate
для копіювання стилів із зазначеного шаблону в документ. При копіюванні стилів із шаблону в документ стилі з однаковими іменами в документі замінюються відповідно до описів стилів у шаблоні. Унікальні стилі з шаблону копіюються в документ. Унікальні стилі в документі залишаються незмінними. У прикладі below code показано, як копіювати стилі з одного документа в інший.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::String fileName = inputDataDir + u"template.docx"; | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(fileName); | |
// Open the document. | |
System::SharedPtr<Document> target = System::MakeObject<Document>(inputDataDir + u"TestFile.doc"); | |
target->CopyStylesFromTemplate(doc); | |
System::String outputPath = outputDataDir + u"CopyStyles.doc"; | |
doc->Save(outputPath); |