מבוא
מדריך זה בוחן כיצד Aspose.Words FOSS עבור .NET מייצג מסמך Word בזיכרון, ואת ה-API-ים המשמשים לבנייה, ניווט ושינוי ייצוג זה: DocumentBuilder לכתיבה סדרתית, עץ הצמתים (Node, CompositeNode, NodeCollection) לגישה מבנית ישירה, DocumentVisitor לעיבוד כל סוג צומת בפעם אחת, מציאת והחלפה באמצעות Range ו-FindReplaceOptions, והמתודות לשילוב ושכפול מסמכים. Where פוסט ההכרזה מציג את הספרייה כולה, זה מתמקד במודל האובייקטים של המסמך (DOM) — האזור הגדול ביותר במשטח של API — וכיצד חלקיו מתאימים זה לזה.
Aspose.Words FOSS עבור .NET משוחרר ברישיון MIT ללא תלותיות מקומיות; הוא מתמקד ב-.NET Standard 2.0, ולכן ה-DOM המתואר כאן זמין ב-.NET Framework 4.6.2+ וב-.NET 6, 8, ו-10, ב-Windows, Linux ו-macOS. התקינו אותו דרך NuGet, או בנו אותו מהמקור — ראו את Quick Start למטה.
כל משימה המתוארת להלן — כתיבת דוח מאפס, שינוי מבנה של קובץ .docx קיים, מעבר על תוכנו לצורך ניתוח, או חיבור כמה מסמכים למסמך אחד — מתחילה מאותו קבוצת סוגי בסיס: Document, DocumentBuilder, וההיררכיה Node מתחתיהם.
הDocument Object Model
בניית מסמכים עם DocumentBuilder
DocumentBuilder הוא כותב מבוסס סמן שיושב על גבי Document ומוסיף תוכן בצורה סדרתית. Write(text) ו-Writeln(text) מוסיפים טקסט במיקום הנוכחי; InsertParagraph() ו-InsertBreak(breakType) מוסיפים פסקאות ושבירות עמוד/עמודה/קטע. העיצוב הוא בעל מצב: המאפיינים Font, ParagraphFormat, ListFormat ו-PageSetup של הבונה חלים על כל מה שנכתב לאחר מכן, ו-PushFont() / PopFont() שומרים ומשחזרים את מצב הגופן הנוכחי כך ששינוי סגנון זמני אינו צריך לבטלו ידנית. שיטות הניווט ממקמות את הסמן בכל מקום במסמך קיים — MoveToDocumentStart(), MoveToDocumentEnd(), MoveToSection(sectionIndex), MoveToBookmark(bookmarkName), MoveToParagraph(paragraphIndex, characterIndex), והכללית MoveTo(node) — ו-DocumentBuilder.CurrentNode, DocumentBuilder.CurrentParagraph, ו-DocumentBuilder.CurrentSection מדווחים היכן הבונה נמצא כרגע. לחילוץ טקסט לקריאה בלבד כאשר אין צורך ב-DOM מלא, PlainTextDocument מציע נתיב קל יותר: new PlainTextDocument(fileName) חושף רק את המאפיין PlainTextDocument.Text ואת המאפיינים המובנים והמותאמים של המסמך.
עץ הצמתים: מקטעים, פסקאות, ריצות וטבלאות
Document הוא עץ של אובייקטי Node ששורש שלו הוא המסמך עצמו: Section → Body → Paragraph → Run עבור טקסט גוף, עם Table → Row → Cell מתפצל בכל מקום שבו מופיעה טבלה. CompositeNode, מחלקת הבסיס לכל צומת מכולה, חושף CompositeNode.FirstChild, CompositeNode.LastChild, Node.NextSibling, ו-Node.PreviousSibling לניווט ישיר, GetChildNodes(nodeType, isDeep) לאיסוף כל צומת מסוג NodeType נתון (Paragraph, Run, Table וכד’) בכל עומק, ו-GetChild(nodeType, index, isDeep) לחיפוש לפי אינדקס. AppendChild(newChild), InsertBefore(newChild, refChild), InsertAfter(newChild, refChild), ו-RemoveChild(oldChild) משנים את העץ ישירות. CompositeNode.SelectNodes(xpath) ו-SelectSingleNode(xpath) בוחרים צמתים עם ביטוי בסגנון XPath במקום ללכת ידנית בעץ, ועבור מסמכים גדולים מאוד, Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode) עוברים על כל צומת אחד אחרי השני ללא רקורסיה.
DocumentVisitor: עיבוד כל סוג צומת במעבר אחד
ירושה מ-DocumentVisitor היא הדרך לעבד מסמך ללא קידוד קשיח של המבנה שלו. היא מגדירה זוגות של שיטות Visit-Start / Visit-End לכל סוג צומת מורכב, כולל DocumentVisitor.VisitSectionStart, DocumentVisitor.VisitParagraphStart, DocumentVisitor.VisitTableStart, DocumentVisitor.VisitRowStart, DocumentVisitor.VisitCellStart, ו-DocumentVisitor.VisitBookmarkStart — כל אחת עם קריאת סיום תואמת — בנוסף DocumentVisitor.VisitFieldStart, DocumentVisitor.VisitFieldSeparator, DocumentVisitor.VisitFieldEnd, ו-DocumentVisitor.VisitRun עבור ריצות טקסט יחידות. קרא Accept(visitor) על Document, Section או כל צומת אחר כדי להפעיל את המבקר על הצומת הזאת ועל כל מה שמתחתיה; AcceptStart(visitor) ו-AcceptEnd(visitor) מפעילים רק את קריאות הכניסה והיציאה עבור צומת מורכב יחיד. כל שיטת Visit מחזירה ערך VisitorAction שקובע איך ההליכה ממשיכה — Continue לתוך תת-העץ, SkipThisNode לדילוג עליו, או Stop לעצור לחלוטין.
מציאת והחלפת טקסט
Range.Replace(pattern, replacement) מריץ חיפוש-החלפה על ה-Range שבבעלותו — Document שלם, Section, או כל צומת עם מאפיין Range משלו — כאשר תבנית החיפוש מתקבלת כמחרוזת מילולית או ביטוי רגולרי. הגרסה Range.Replace(pattern, replacement, options) מקבלת מופע FindReplaceOptions כדי לשלוט ב-FindReplaceOptions.MatchCase, FindReplaceOptions.FindWholeWordsOnly, כיוון החיפוש FindReplaceOptions.Direction (ערך FindReplaceDirection של Forward או Backward), עיצוב המיושם על טקסט ההחלפה (FindReplaceOptions.ApplyFont, FindReplaceOptions.ApplyParagraphFormat), ואילו תוכן סביבתי להשאיר ללא שינוי (FindReplaceOptions.IgnoreFields, FindReplaceOptions.IgnoreFootnotes, FindReplaceOptions.IgnoreFieldCodes, ודגלי Ignore* קשורים). עבור לוגיקה לכל התאמה מעבר להחלפה פשוטה, מימוש את השיטה Replacing(args) של IReplacingCallback והקצה את המימוש ל-FindReplaceOptions.ReplacingCallback; כל התאמה קוראת חזרה עם ReplacingArgs המתארת את ההתאמה, והערך המוחזר של הקריאה חזרה — ערך ReplaceAction של Replace, Skip, או Stop — מחליט מה קורה עם ההתאמה.
שילוב ושכפול מסמכים
Document.AppendDocument(srcDoc, importFormatMode) מצרף את כל תוכן של מסמך Document אחד אל סוף של מסמך אחר. ארגומנט ה-importFormatMode שלו — ערך של ImportFormatMode של UseDestinationStyles, KeepSourceFormatting, או KeepDifferentStyles — קובע כיצד מתמודדים עם קונפליקטים של סגנונות בין המקור ליעד, והגרסה העודפת Document.AppendDocument(srcDoc, importFormatMode, importFormatOptions) מוסיפה שליטה מדויקת יותר באמצעות ImportFormatOptions (ImportFormatOptions.KeepSourceNumbering, ImportFormatOptions.IgnoreHeaderFooter, ImportFormatOptions.MergePastedLists, ודגלים דומים). כדי להכניס את תוכן של מסמך אחר במיקום ספציפי במקום בסוף, DocumentBuilder.InsertDocument(srcDoc, importFormatMode, importFormatOptions) עושה את המקביל ממיקום הסמן הנוכחי של הבונה, ו-DocumentBuilder.InsertDocumentInline(srcDoc, importFormatMode, importFormatOptions) מכניס את אותו תוכן ללא הוספת פסקה או שבירת קטע בנקודת ההכנסה. Document.ImportNode(srcNode, isImportChildren) מעתיק צומת אחד — באפשרותו עם הצאצאים שלו — ממסמך שונה כדי שניתן יהיה לצרף אותו למסמך הנוכחי, והמתודה Node.Clone(isCloneChildren) הזמינה בכל צומת משכפלת את המבנה בתוך אותו מסמך, למשל שימוש חוזר ב-Section כתבנית לתוכן חוזר.
סימניות ומשתני מסמך
המאפיין Range.Bookmarks חושף BookmarkCollection של עוגנים בשם בתוך הטווח הזה. DocumentBuilder.StartBookmark(bookmarkName) ו-EndBookmark(bookmarkName) מסמנים את היקף הסימנייה בזמן הבנייה; האינדקסר של BookmarkCollection, bookmarks[name], מאחזר אחד מאוחר יותר עבור הניווט DocumentBuilder.MoveToBookmark(bookmarkName) או לקריאת Bookmark.Text. בנפרד, Document.Variables — VariableCollection — מאחסן זוגות מחרוזת שם/ערך שרירותיים ישירות על המסמך עצמו, שימושי להעברת חלקים קטנים של מצב דרך צינור ייצור מסמכים מבלי להוסיף תוכן גלוי.
התחלה מהירה
Aspose.Words FOSS עבור .NET זמינה דרך NuGet:
dotnet add package Aspose.Words.FOSSכדי לבנות מהמקור במקום זאת:
git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git
cd Aspose.Words-FOSS-for-.NET
dotnet build Aspose.Words.sln -c Release
עם רפרנס לפרויקט ל-Aspose.Words.csproj במקום, הדרך הקצרה ביותר למסמך פועלת לפי אותו דפוס שמופיע בכל הפוסט הזה: ליצור Document, לעטוף אותו ב-DocumentBuilder, לקרוא ל-Write() או Writeln() כדי להוסיף טקסט — העיצוב שנקבע על המאפיינים Font ו-ParagraphFormat של הבילדר נושא עצמו לכל כתיבה הבאה — ולקרוא ל-Document.Save(fileName) כדי לשמור אותו כ-.docx, .docm, .dotx, .dotm, Flat OPC, Markdown, או טקסט רגיל. כדי לערוך קובץ קיים במקום להתחיל מאפס, טען אותו ישירות עם new Document(fileName), העבר את הבילדר למיקום ספציפי עם MoveToBookmark(), MoveToParagraph(), או MoveTo(node), והמשך לכתוב משם.
פורמטים נתמכים
| פורמט | סיומת | קריאה | כתיבה |
|---|---|---|---|
| DOCX | .docx | ✓ | ✓ |
| DOCM | .docm | ✓ | ✓ |
| DOTX | .dotx | ✓ | ✓ |
| DOTM | .dotm | ✓ | ✓ |
| Flat OPC (כל הווריאנטים) | (שונים) | ✓ | ✓ |
| Markdown | .md | ✓ | ✓ |
| Text | .txt | ✓ | ✓ |
עץ הצמתים המתואר למעלה זמין באותו אופן ללא תלות בפורמט ממנו נטען המסמך או אליו הוא יישמר — ה-DOM פנימי אינו תלוי בפורמט. מה שאינו נכלל במהדורה זו הוא כל מה שתלוי בפריסת העמוד: אין ייצוא ל-PDF, XPS או תמונה, ואין הדפסה, ולכן ערכי שדות התלויים בפריסה כגון מספרי עמודים מתורגמים למקומזמנים במקום להיות מחושבים. ממירי הפורמט הנוספים (DOC, RTF, ODT, HTML, EPUB, MHTML, MOBI, AZW3, ו-WordML) אינם נקראים או נכתבים, וכן אינן נכללות הרצת מיזוג דואר, LINQ Reporting והשוואת מסמכים. מפתחים הזקוקים ליכולות אלה יכולים לעבור ל-commercial Aspose.Words עבור .NET ללא צורך בכתיבת קוד ה-DOM מחדש כפי שמוצג כאן, מכיוון ששתי המהדורות חולקות את אותו API בסיסי.
קוד פתוח ורישוי
Aspose.Words FOSS עבור .NET משוחרר תחת רישיון MIT, חופשי לשימוש מסחרי ואישי ללא תמלוגים או מגבלות הפצה. המקור, כולל ה- Document, DocumentBuilder, ויישום עץ הצמתים המתואר למעלה, זמין ב- מאגר Aspose.Words FOSS עבור .NET ב-GitHub.