Praca ze stylami

Klasa StyleCollection służy do zarządzania wbudowanymi i stosowania ustawień zdefiniowanych przez użytkownika do stylów.

Jak wyodrębnić zawartość na podstawie stylów

Na prostym poziomie pobieranie zawartości na podstawie stylów z dokumentu Word może być przydatne do identyfikacji, listy i liczenia akapitów i przebiegów tekstu sformatowanego w określonym stylu. Na przykład może być konieczne zidentyfikowanie określonych rodzajów treści w dokumencie, takich jak przykłady, tytuły, odniesienia, słowa kluczowe, nazwy figur i studia przypadków.

Aby zrobić to o kilka kroków dalej, można to również wykorzystać do wykorzystania struktury dokumentu, zdefiniowanej przez używane style, do ponownego przeznaczenia dokumentu na inne dane wyjściowe, takie jak HTML. W rzeczywistości w ten sposób budowana jest dokumentacja Aspose, testując Aspose.Words. Narzędzie zbudowane przy użyciu Aspose.Words pobiera dokumenty źródłowe Word i dzieli je na tematy na określonych poziomach nagłówków. Plik XML jest tworzony przy użyciu Aspose.Words, który służy do zbudowania drzewa nawigacji widocznego po lewej stronie. A następnie Aspose.Words konwertuje każdy temat na HTML.

Rozwiązanie do pobierania tekstu sformatowanego z określonymi stylami w dokumencie Word jest zazwyczaj ekonomiczne i proste przy użyciu Aspose.Words.

Rozwiązanie

Aby zilustrować, jak łatwo Aspose.Words obsługuje pobieranie treści na podstawie stylów, spójrzmy na przykład. W tym przykładzie pobierzemy tekst sformatowany za pomocą określonego stylu akapitu i stylu znaku z przykładowego dokumentu Word. Na wysokim poziomie będzie to obejmować:

  • Otwieranie dokumentu Word przy użyciu klasy Document.
  • Pobieranie kolekcji wszystkich akapitów i wszystkich przebiegów w dokumencie.
  • Wybieranie tylko wymaganych akapitów i przebiegów. W szczególności pobierzemy tekst sformatowany za pomocą stylu akapitu “Heading 1 “i stylu znaku” intensywny nacisk " z tego przykładowego dokumentu Word.

working-with-styles-aspose-words-cpp-1

W tym przykładowym dokumencie tekst sformatowany za pomocą stylu akapitu “Heading 1 " to “Wstaw kartę”, “Szybkie style” i “motyw”, a tekst sformatowany za pomocą stylu znaków “intensywny nacisk” to kilka wystąpień niebieskiego, kursywą, pogrubiony tekst, taki jak “galerie” i “ogólny wygląd”.

Kodeks

Implementacja zapytania opartego na stylu jest dość prosta w modelu obiektowym dokumentu Aspose.Words, ponieważ po prostu używa narzędzi, które już są na miejscu. Dla tego rozwiązania zaimplementowano dwie metody klas:# ParagraphsByStyleName - ta metoda pobiera tablicę tych akapitów w dokumencie, które mają określoną nazwę stylu.# RunsByStyleName - ta metoda pobiera tablicę tych uruchomień w dokumencie, które mają określoną nazwę stylu. Obie te metody są bardzo podobne, jedynymi różnicami są typy węzłów i reprezentacja informacji o stylu w akapicie i węzłach uruchamiania. Oto implementacja ParagraphsByStyleName. Poniżej przykład Znajdź wszystkie akapity sformatowane w określonym stylu.

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

Warto również zauważyć, że kolekcja akapitów nie tworzy natychmiastowego narzutu, ponieważ akapity są ładowane do tej kolekcji tylko wtedy, gdy uzyskujesz dostęp do elementów w nich zawartych. Następnie wszystko, co musisz zrobić, to przejść przez kolekcję, używając standardu dla każdego operatora i dodać akapity o określonym stylu do tablicy paragraphsWithStyle. Nazwę stylu Paragraph można znaleźć w stylu. Właściwość nazwy obiektu Paragraph.ParagraphFormat. Implementacja RunsByStyleName jest prawie taka sama, chociaż oczywiście używamy NodeType.Run do pobierania węzłów run. Właściwość Font.Style obiektu Run służy do uzyskiwania dostępu do informacji o stylu w węzłach Run. Przykład below code Znajdź wszystkie przebiegi sformatowane w określonym stylu.

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

Po zaimplementowaniu obu zapytań wystarczy przekazać obiekt dokumentu i określić nazwy stylów treści, którą chcesz pobrać: poniżej przykład uruchom zapytania i wyświetl wyniki. Możesz pobrać plik szablonu tego przykładu stąd.

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

Efekt Końcowy

Gdy wszystko zostanie zrobione, uruchomienie próbki wyświetli następujące dane wyjściowe:

working-with-styles-aspose-words-cpp-2

Jak widać, jest to bardzo prosty przykład, pokazujący liczbę i tekst zebranych akapitów i działa w przykładowym dokumencie Word.

Jak wstawić i pracować z polem spis treści

Często będziesz pracować z Dokumentami zawierającymi spis treści (TOC). Za pomocą Aspose.Words możesz wstawić własny spis treści lub całkowicie przebudować istniejący spis treści w dokumencie za pomocą zaledwie kilku wierszy kodu. W tym artykule opisano, jak pracować z polem spis treści i pokazano:

  • Jak wstawić nowy TOC
  • Zaktualizuj nowy lub istniejący TOCs w dokumencie.
  • Określ przełączniki, aby kontrolować formatowanie i ogólną strukturę F TOC.
  • Jak zmodyfikować style i wygląd spisu treści.
  • Jak usunąć całe pole TOC wraz ze wszystkimi wpisami z dokumentu.

Wstaw Pola TC

Często określony wiersz tekstu jest oznaczony dla TOC i jest oznaczony polem TC. Prostym sposobem na zrobienie tego w MS Word jest podświetlenie tekstu i naciśnięcie ALT+SHIFT+O. Spowoduje to automatyczne utworzenie pola TC przy użyciu zaznaczonego tekstu. Tę samą technikę można osiągnąć za pomocą kodu. Poniższy kod znajdzie tekst pasujący do danych wejściowych i wstawi pole TC w tej samej pozycji co tekst. Kod oparty jest na tej samej technice zastosowanej w artykule. Poniższy przykład pokazuje, jak znaleźć i wstawić pole TC w tekście w dokumencie.

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

Zmodyfikuj spis treści

Zmień formatowanie stylów

Formatowanie wpisów w TOC nie wykorzystuje oryginalnych stylów oznaczonych wpisów, zamiast tego każdy poziom jest formatowany przy użyciu równoważnego stylu TOC. Na przykład pierwszy poziom w TOC jest sformatowany w stylu TOC1, drugi poziom sformatowany w stylu TOC2 i tak dalej. Oznacza to, że aby zmienić wygląd TOC, te style muszą zostać zmodyfikowane. W Aspose.Words Style te są reprezentowane przez niezależne od ustawień regionalnych od StyleIdentifier.TOC1 do StyleIdentifier.TOC9 i można je pobrać z kolekcji Document.Styles za pomocą tych identyfikatorów. Po pobraniu odpowiedniego stylu dokumentu formatowanie tego stylu można zmodyfikować. Wszelkie zmiany w tych stylach zostaną automatycznie odzwierciedlone na TOCs w dokumencie. Przykład below code zmienia właściwość formatowania używaną w stylu pierwszego poziomu 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);

Warto również zauważyć, że każde bezpośrednie formatowanie akapitu (zdefiniowane w samym akapicie, a nie w stylu) oznaczone jako TOC zostanie skopiowane we wpisie w TOC. Na przykład, jeśli styl Heading 1 jest używany do oznaczania zawartości dla TOC i ten styl ma formatowanie pogrubione, podczas gdy akapit ma również formatowanie kursywą bezpośrednio do niego zastosowane. Wynikowy wpis TOC nie będzie pogrubiony, ponieważ jest to część formatowania stylu, ale będzie kursywą, ponieważ jest to bezpośrednio sformatowane w akapicie. Możesz także kontrolować formatowanie separatorów używanych między każdym wpisem a numerem strony. Domyślnie jest to linia przerywana, która jest rozłożona na numerację stron za pomocą znaku tabulatora i prawego ogranicznika tabulatora ustawionego blisko prawego marginesu.

Korzystając z klasy Style pobranej dla określonego poziomu TOC, który chcesz zmodyfikować, możesz również zmodyfikować sposób ich wyświetlania w dokumencie. Aby zmienić wygląd, najpierw należy wywołać Style.ParagraphFormat, Aby pobrać formatowanie akapitu dla stylu. Z tego można pobrać tabulatory, wywołując ParagraphFormat.TabStops i modyfikując odpowiedni tabulator. Korzystając z tej samej techniki, samą kartę można przenieść lub całkowicie usunąć. Przykład below code pokazuje, jak zmodyfikować położenie prawego tabulatora w paragrafach powiązanych z TOC. Możesz pobrać plik szablonu tego przykładu stąd.

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

Usuwanie spisu treści z dokumentu

Spis treści można usunąć z dokumentu, usuwając wszystkie węzły znajdujące się między węzłem FieldStart i FieldEnd pola TOC. Poniższy kod to pokazuje. Usunięcie pola TOC jest prostsze niż zwykłe pole, ponieważ nie śledzimy zagnieżdżonych pól. Zamiast tego sprawdzamy, czy węzeł FieldEnd jest typu FieldType.FieldTOC, co oznacza, że napotkaliśmy koniec bieżącego TOC. Ta technika może być użyta w tym przypadku bez martwienia się o zagnieżdżone pola, ponieważ możemy założyć, że każdy prawidłowo utworzony dokument nie będzie miał w pełni zagnieżdżonego pola TOC w innym polu TOC. Po pierwsze, węzły FieldStart każdego TOC są gromadzone i przechowywane. Określony TOC jest następnie wyliczany, aby wszystkie węzły w polu były odwiedzane i przechowywane. Węzły są następnie usuwane z dokumentu. Przykład below code pokazuje, jak usunąć określony TOC z dokumentu. Możesz pobrać plik szablonu tego przykładu stąd.

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

Wstaw Separator stylów, aby umieścić różne style akapitów

Separator stylów można dodać na końcu akapitu za pomocą skrótu klawiaturowego Ctrl + Alt + Enter do MS Word. Ta funkcja pozwala na dwa różne style akapitów używane w jednym logicznym drukowanym akapicie. Jeśli chcesz, aby jakiś tekst z początku określonego nagłówka pojawił się w spisie treści, ale nie chcesz, aby cały nagłówek znajdował się w spisie treści, możesz użyć tej funkcji. Przykład below code pokazuje, jak wstawić separator stylów, aby umieścić różne style akapitów.

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

Skopiuj wszystkie style z szablonu

Zdarzają się przypadki, gdy chcesz skopiować wszystkie style z jednego dokumentu do drugiego. Możesz użyć metody Document.CopyStylesFromTemplate, aby skopiować style z określonego szablonu do dokumentu. Gdy style są kopiowane z szablonu do dokumentu, Style o podobnych nazwach w dokumencie są przedefiniowane, aby pasowały do opisów stylów w szablonie. Unikalne style z szablonu są kopiowane do dokumentu. Unikalne style w dokumencie pozostają nienaruszone. Przykład below code pokazuje, jak kopiować style z jednego dokumentu do drugiego.

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