استخراج محتوا بین گره ها در یک سند
هنگام کار با اسناد، مهم است که بتوانید به راحتی محتوای یک محدوده خاص را در یک سند استخراج کنید. با این حال، محتوا ممکن است شامل عناصر پیچیده ای مانند پاراگراف ها، جداول، تصاویر و غیره باشد.
صرف نظر از اینکه چه محتوایی باید استخراج شود، روش استخراج آن محتوا همیشه تعیین می شود که کدام گره ها برای استخراج محتوا بین آنها انتخاب می شوند. این می تواند کل متن بدن و یا متن ساده اجرا می شود.
موقعیت های احتمالی زیادی وجود دارد و بنابراین انواع گره های مختلفی برای استخراج محتوا وجود دارد. برای مثال، ممکن است بخواهید محتوای بین:
- دو پاراگراف خاص
- اجراهای خاص متن
- زمینه های مختلف مانند زمینه های ادغام
- محدوده شروع و پایان یک نشانه یا نظر
- مجموعه های مختلف متن موجود در بخش های جداگانه
در برخی شرایط، حتی ممکن است لازم باشد انواع گره های مختلف مانند استخراج محتوا بین یک پاراگراف و یک فیلد یا بین یک اجرا و یک نشانه را ترکیب کنید.
این مقاله پیاده سازی کد برای استخراج متن بین گره های مختلف و همچنین نمونه هایی از سناریوهای رایج را ارائه می دهد.
چرا محتوا را استخراج کنیم
اغلب هدف از استخراج محتوا این است که آن را به طور جداگانه در یک سند جدید تکرار یا ذخیره کنید. به عنوان مثال، شما می توانید محتوا را استخراج کنید و:
- آن را در یک سند جداگانه کپی کنید
- تبدیل یک قسمت خاص از یک سند به PDF یا تصویر
- محتوای موجود در سند را بارها تکرار کنید
- کار با محتوای استخراج شده جدا از بقیه سند
این کار را می توان با استفاده از Aspose.Words و پیاده سازی کد زیر به راحتی انجام داد.
الگوریتم استخراج محتوا
کد در این بخش به تمام موقعیت های احتمالی که در بالا توضیح داده شد با یک روش عمومی و قابل استفاده مجدد می پردازد. طرح کلی این تکنیک شامل:
- جمع آوری گره هایی که منطقه محتوایی را که از سند شما استخراج می شود، تعیین می کند. بازیابی این گره ها توسط کاربر در کد آنها بر اساس آنچه که می خواهند استخراج شوند، انجام می شود.
- انتقال این گره ها به روش ExtractContent ارائه شده در زیر. شما همچنین باید یک پارامتر بولی را عبور دهید که بیان می کند آیا این گره ها، به عنوان نشانگر عمل می کنند، باید در استخراج گنجانده شوند یا نه.
- بازیابی لیستی از محتوای کلون شده (گره های کپی شده) مشخص شده برای استخراج. شما می توانید از این لیست گره ها به هر روش قابل اجرا استفاده کنید، به عنوان مثال، ایجاد یک سند جدید که فقط حاوی محتوای انتخاب شده است.
نحوه استخراج محتوا
ما با سند زیر در این مقاله کار خواهیم کرد. همانطور که می بینید حاوی محتوای متنوعی است. همچنین توجه داشته باشید که این سند شامل بخش دوم است که در وسط صفحه اول شروع می شود. یک نشانه و نظر نیز در سند وجود دارد اما در تصویر زیر قابل مشاهده نیست.
برای استخراج محتوا از سند خود باید روش ExtractContent
زیر را فراخوانی کنید و پارامترهای مناسب را منتقل کنید.
اساس اساسی این روش شامل یافتن گره های سطح بلوک (پاراگراف ها و جداول) و شبیه سازی آنها برای ایجاد نسخه های یکسان است. اگر گره های نشانگر عبور شده در سطح بلوک باشند، روش می تواند به سادگی محتوای آن سطح را کپی کند و آن را به آرایه اضافه کند.
با این حال، اگر گره های نشانگر خطی باشند (فرزند یک پاراگراف)، وضعیت پیچیده تر می شود، زیرا لازم است پاراگراف را در گره خطی تقسیم کنید، چه اجرا شود، زمینه های نشانه گذاری و غیره. محتوای در گره های والدین کلون شده که بین نشانگرها وجود ندارد حذف می شود. این فرآیند برای اطمینان از اینکه گره های خطی هنوز قالب بندی پاراگراف اصلی را حفظ می کنند، استفاده می شود.
این روش همچنین چک هایی را در گره های منتقل شده به عنوان پارامترها اجرا می کند و اگر هر یک از گره ها نامعتبر باشد، یک استثنا را پرتاب می کند. پارامترهایی که باید به این روش منتقل شوند عبارتند از:
-
StartNode و EndNode. دو پارامتر اول گره هایی هستند که تعریف می کنند که استخراج محتوا به ترتیب در کجا شروع و پایان می یابد. این گره ها می توانند هر دو سطح بلوک (Paragraph، Table) یا سطح خطی (به عنوان مثال Run, FieldStart, BookmarkStart و غیره):
- برای عبور از یک فیلد باید از شیء FieldStart مربوطه عبور کنید.
- برای عبور از نشانه ها، گره های BookmarkStart و BookmarkEnd باید منتقل شوند.
- برای عبور از نظرات، باید از گره های CommentRangeStart و CommentRangeEnd استفاده شود.
-
IsInclusive. مشخص می کند که آیا نشانگرها در استخراج گنجانده شده اند یا نه. اگر این گزینه به false تنظیم شود و همان گره یا گره های متوالی منتقل شوند، یک لیست خالی بازگردانده می شود:
- اگر یک گره FieldStart منتقل شود، این گزینه تعریف می کند که آیا کل فیلد باید شامل یا حذف شود.
- اگر یک گره BookmarkStart یا BookmarkEnd منتقل شود، این گزینه تعریف می کند که آیا علامت گذاری شامل شده است یا فقط محتوای بین محدوده علامت گذاری است.
- اگر یک گره CommentRangeStart یا CommentRangeEnd منتقل شود، این گزینه تعریف می کند که آیا خود نظر باید شامل شود یا فقط محتوای در محدوده نظر.
پیاده سازی روش ExtractContent که می توانید پیدا کنید اینجا. این روش در سناریوهای این مقاله ذکر خواهد شد.
ما همچنین یک روش سفارشی برای تولید آسان یک سند از گره های استخراج شده تعریف خواهیم کرد. این روش در بسیاری از سناریوهای زیر استفاده می شود و به سادگی یک سند جدید ایجاد می کند و محتوای استخراج شده را وارد آن می کند.
مثال کد زیر نشان می دهد که چگونه یک لیست از گره ها را بگیرید و آنها را در یک سند جدید قرار دهید:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
public static Document generateDocument(Document srcDoc, ArrayList<Node> nodes) throws Exception | |
{ | |
Document dstDoc = new Document(); | |
// Remove the first paragraph from the empty document. | |
dstDoc.getFirstSection().getBody().removeAllChildren(); | |
// Import each node from the list into the new document. Keep the original formatting of the node. | |
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); | |
for (Node node : nodes) | |
{ | |
Node importNode = importer.importNode(node, true); | |
dstDoc.getFirstSection().getBody().appendChild(importNode); | |
} | |
return dstDoc; | |
} |
استخراج محتوا بین پاراگراف ها
این نشان می دهد که چگونه از روش بالا برای استخراج محتوا بین پاراگراف های خاص استفاده کنید. در این حالت می خواهیم بدنه نامه موجود در نیمه اول سند را استخراج کنیم. ما می توانیم بگوییم که این بین پاراگراف های 7 و 11 است.
کد زیر این کار را انجام می دهد. پاراگراف های مناسب با استفاده از روش getChild در سند استخراج می شوند و شاخص های مشخص شده را منتقل می کنند. سپس این گره ها را به روش ExtractContent منتقل می کنیم و بیان می کنیم که این ها باید در استخراج گنجانده شوند. این روش محتوای کپی شده بین این گره ها را که سپس در یک سند جدید وارد می شوند، باز می گرداند.
مثال کد زیر نشان می دهد که چگونه محتوای بین پاراگراف های خاص را با استفاده از روش ExtractContent
بالا استخراج کنیم:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
Paragraph startPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 6, true); | |
Paragraph endPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 10, true); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startPara, endPara, true); | |
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphs.docx"); |
سند خروجی شامل دو پاراگراف است که استخراج شده است.
استخراج محتوا بین انواع مختلف گره ها
ما می توانیم محتوا را بین هر ترکیبی از گره های سطح بلوک یا خطی استخراج کنیم. در این سناریو زیر ما محتوای بین پاراگراف اول و جدول در بخش دوم را به طور کامل استخراج خواهیم کرد. ما گره های نشانگر را با فراخوانی روش getFirstParagraph و getChild در بخش دوم سند برای بازیابی گره های مناسب Paragraph و Table دریافت می کنیم. برای یک تغییر کوچک بیایید به جای آن محتوای را تکرار کنیم و آن را زیر اصل قرار دهیم.
مثال کد زیر نشان می دهد که چگونه محتوای بین یک پاراگراف و جدول را با استفاده از روش ExtractContent استخراج کنیم:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
Paragraph startPara = (Paragraph) doc.getLastSection().getChild(NodeType.PARAGRAPH, 2, true); | |
Table endTable = (Table) doc.getLastSection().getChild(NodeType.TABLE, 0, true); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startPara, endTable, true); | |
// Let's reverse the array to make inserting the content back into the document easier. | |
Collections.reverse(extractedNodes); | |
for (Node extractedNode : extractedNodes) | |
// Insert the last node from the reversed list. | |
endTable.getParentNode().insertAfter(extractedNode, endTable); | |
doc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBlockLevelNodes.docx"); |
محتوای بین پاراگراف و جدول در زیر تکرار شده است نتیجه است.
استخراج محتوا بین پاراگراف ها بر اساس سبک
ممکن است لازم باشد محتوای بین پاراگراف های سبک یکسان یا متفاوت مانند بین پاراگراف هایی که با سبک های عنوان مشخص شده اند را استخراج کنید.
کد زیر نشان می دهد که چگونه این کار را انجام دهید. این یک مثال ساده است که محتوای بین اولین نمونه از سبک های “Heading 1” و “Header 3” را بدون استخراج عناوین نیز استخراج می کند. برای انجام این کار ما آخرین پارامتر را به false تنظیم می کنیم، که مشخص می کند که گره های نشانگر نباید شامل شوند.
در یک پیاده سازی مناسب، این باید در یک حلقه اجرا شود تا محتوای بین تمام پاراگراف های این سبک ها از سند استخراج شود. محتوای استخراج شده در یک سند جدید کپی می شود.
مثال کد زیر نشان می دهد که چگونه محتوای بین پاراگراف ها را با سبک های خاص با استفاده از روش ExtractContent استخراج کنیم:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
// Gather a list of the paragraphs using the respective heading styles. | |
ArrayList<Paragraph> parasStyleHeading1 = paragraphsByStyleName(doc, "Heading 1"); | |
ArrayList<Paragraph> parasStyleHeading3 = paragraphsByStyleName(doc, "Heading 3"); | |
// Use the first instance of the paragraphs with those styles. | |
Node startPara1 = parasStyleHeading1.get(0); | |
Node endPara1 = parasStyleHeading3.get(0); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startPara1, endPara1, false); | |
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphStyles.docx"); |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
public static ArrayList<Paragraph> paragraphsByStyleName(Document doc, String styleName) | |
{ | |
// Create an array to collect paragraphs of the specified style. | |
ArrayList<Paragraph> paragraphsWithStyle = new ArrayList<Paragraph>(); | |
NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); | |
// Look through all paragraphs to find those with the specified style. | |
for (Paragraph paragraph : (Iterable<Paragraph>) paragraphs) | |
{ | |
if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) | |
paragraphsWithStyle.add(paragraph); | |
} | |
return paragraphsWithStyle; | |
} |
در زیر نتیجه عملیات قبلی است.
استخراج محتوا بین اجراهای خاص
شما می توانید محتوا را بین گره های خطی مانند Run نیز استخراج کنید. Runs از پاراگراف های مختلف می تواند به عنوان نشانگر منتقل شود. کد زیر نشان می دهد که چگونه متن خاص را بین همان گره Paragraph استخراج کنیم.
مثال کد زیر نشان می دهد که چگونه محتوای بین اجراهای خاص همان پاراگراف را با استفاده از روش ExtractContent استخراج کنیم:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 7, true); | |
Run startRun = para.getRuns().get(1); | |
Run endRun = para.getRuns().get(4); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startRun, endRun, true); | |
for (Node extractedNode : extractedNodes) | |
System.out.println(extractedNode.toString(SaveFormat.TEXT)); |
متن استخراج شده در کنسول نمایش داده می شود.
استخراج محتوا با استفاده از یک فیلد
برای استفاده از یک فیلد به عنوان یک نشانگر، گره FieldStart
باید منتقل شود. آخرین پارامتر به روش ExtractContent
تعریف خواهد کرد که آیا کل فیلد باید شامل شود یا نه. بیایید محتوای بین فیلد ادغام “FullName” و یک پاراگراف در سند را استخراج کنیم. ما از روش moveToMergeField کلاس DocumentBuilder استفاده می کنیم. این گره FieldStart را از نام فیلد ادغام به آن منتقل می کند.
در مورد ما بیایید آخرین پارامتر منتقل شده به روش ExtractContent را به false تنظیم کنیم تا فیلد را از استخراج حذف کنیم. ما محتوای استخراج شده را به PDF ارائه خواهیم داد.
مثال کد زیر نشان می دهد که چگونه محتوای بین یک فیلد خاص و پاراگراف در سند با استفاده از روش ExtractContent استخراج شود:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
// Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field. | |
// We could also get FieldStarts of a field using GetChildNode method as in the other examples. | |
builder.moveToMergeField("Fullname", false, false); | |
// The builder cursor should be positioned at the start of the field. | |
FieldStart startField = (FieldStart) builder.getCurrentNode(); | |
Paragraph endPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 5, true); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startField, endPara, false); | |
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentUsingField.docx"); |
محتوای استخراج شده بین فیلد و پاراگراف، بدون گره های نشانگر فیلد و پاراگراف به PDF ارائه شده است.
استخراج محتوا از یک نشانک
در یک سند، محتوایی که در یک نشانه تعریف شده است توسط گره های BookmarkStart
و BookmarkEnd بسته بندی شده است. محتوای موجود بین این دو گره نشانک را تشکیل می دهد. شما می توانید هر یک از این گره ها را به عنوان هر نشانگر، حتی آنهایی که از نشانه های مختلف هستند، عبور دهید، تا زمانی که نشانگر شروع قبل از نشانگر پایان در سند ظاهر شود.
در نمونه سند ما، ما یک نشانه داریم، به نام"Bookmark1". محتوای این نشانک در سند ما برجسته شده است:
ما این محتوا را با استفاده از کد زیر به یک سند جدید استخراج خواهیم کرد. گزینه پارامتر IsInclusive نشان می دهد که چگونه علامت گذاری را حفظ یا دور بریزید.
مثال کد زیر نشان می دهد که چگونه محتوای ارجاع شده را با استفاده از روش ExtractContent استخراج کنیم:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
Bookmark bookmark = doc.getRange().getBookmarks().get("Bookmark1"); | |
BookmarkStart bookmarkStart = bookmark.getBookmarkStart(); | |
BookmarkEnd bookmarkEnd = bookmark.getBookmarkEnd(); | |
// Firstly, extract the content between these nodes, including the bookmark. | |
ArrayList<Node> extractedNodesInclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, true); | |
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx"); | |
// Secondly, extract the content between these nodes this time without including the bookmark. | |
ArrayList<Node> extractedNodesExclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, false); | |
dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx"); |
خروجی استخراج شده با پارامتر IsInclusive
به true تنظیم شده است. نسخه هم علامت کتاب رو حفظ ميکنه
خروجی استخراج شده با پارامتر IsInclusive به false تنظیم شده است. نسخه شامل محتوا است اما بدون علامت کتاب.
استخراج مطالب از یک نظر
یک نظر از گره های CommentRangeStart، CommentRangeEnd و نظر تشکیل شده است. همه این گره ها خطی هستند. دو گره اول محتوای سند را که توسط نظر ارجاع داده شده است، همانطور که در تصویر زیر دیده می شود، خلاصه می کند.
خود گره Comment یک InlineStory است که می تواند شامل پاراگراف ها و اجرا شود. این پیام نظر را به عنوان یک حباب نظر در صفحه بررسی نشان می دهد. از آنجا که این گره خطی است و از نسل یک بدن است شما همچنین می توانید محتوای داخل این پیام را نیز استخراج کنید.
در سند ما یک نظر داریم. بیایید آن را با نشان دادن نشانه گذاری در برگه بررسی نمایش دهیم:
این نظر عنوان، پاراگراف اول و جدول را در بخش دوم خلاصه می کند. بیایید این نظر را به یک سند جدید تبدیل کنیم. گزینه IsInclusive تعیین می کند که آیا خود نظر حفظ شده یا رد شده است.
مثال کد زیر نشان می دهد که چگونه این کار را انجام دهید در زیر است:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
CommentRangeStart commentStart = (CommentRangeStart) doc.getChild(NodeType.COMMENT_RANGE_START, 0, true); | |
CommentRangeEnd commentEnd = (CommentRangeEnd) doc.getChild(NodeType.COMMENT_RANGE_END, 0, true); | |
// Firstly, extract the content between these nodes including the comment as well. | |
ArrayList<Node> extractedNodesInclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, true); | |
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx"); | |
// Secondly, extract the content between these nodes without the comment. | |
ArrayList<Node> extractedNodesExclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, false); | |
dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive); | |
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx"); |
اول خروجی استخراج شده با پارامتر IsInclusive
به true تنظیم شده است. نسخه شامل نظر هم خواهد بود.
دوم خروجی استخراج شده با isInclusive به false تنظیم شده است. نسخه شامل محتوا است اما بدون نظر.
استخراج محتوا با استفاده از DocumentVisitor
Aspose.Words می تواند نه تنها برای ایجاد Microsoft Word اسناد با ساخت آنها به صورت پویا یا ادغام قالب ها با داده ها، بلکه برای تجزیه اسناد به منظور استخراج عناصر سند جداگانه مانند سرصفحه ها، پای صفحه ها، پاراگراف ها، جداول، تصاویر و دیگران استفاده شود. یکی دیگر از وظایف ممکن این است که تمام متن قالب بندی یا سبک خاص را پیدا کنید.
برای اجرای این سناریوی استفاده از کلاس DocumentVisitor استفاده کنید. این کلاس با الگوی طراحی بازدید کننده شناخته شده مطابقت دارد. با DocumentVisitor می توانید عملیات سفارشی را که نیاز به شمارش بر روی درخت سند دارند تعریف و اجرا کنید.
DocumentVisitor مجموعه ای از روش های VisitXXX را فراهم می کند که هنگام برخورد با یک عنصر سند خاص (گره) فراخوانده می شود. به عنوان مثال، VisitParagraphStart زمانی فراخوانده می شود که ابتدای یک پاراگراف متنی پیدا شود و VisitParagraphEnd زمانی فراخوانده می شود که پایان یک پاراگراف متنی پیدا شود. هر روش DocumentVisitor.VisitXXX شیء مربوطه را که با آن روبرو می شود قبول می کند تا بتوانید در صورت نیاز از آن استفاده کنید (به عنوان مثال بازیابی قالب بندی)، به عنوان مثال هر دو شیء VisitParagraphStart و VisitParagraphEnd یک شیء Paragraph را قبول کنید.
هر روش DocumentVisitor.VisitXXX یک مقدار VisitorAction را باز می گرداند که شمارش گره ها را کنترل می کند. شما می توانید درخواست کنید که یا شمارش را ادامه دهید، گره فعلی را حذف کنید (اما شمارش را ادامه دهید)، یا شمارش گره ها را متوقف کنید.
این گام هایی است که باید برای تعیین و استخراج بخش های مختلف یک سند به صورت برنامه ریزی شده دنبال کنید:
- یک کلاس مشتق از DocumentVisitor ایجاد کنید.
- رد کردن و ارائه پیاده سازی برای برخی یا همه روش های DocumentVisitor.VisitXXX برای انجام برخی از عملیات سفارشی.
- Node.accept را در گره ای که می خواهید شمارش را از آن شروع کنید، فراخوانی کنید. به عنوان مثال، اگر می خواهید کل سند را فهرست کنید، از accept(DocumentVisitor) استفاده کنید.
DocumentVisitor پیاده سازی های پیش فرض برای تمام روش های DocumentVisitor.VisitXXX را فراهم می کند. این کار ایجاد بازدید کنندگان جدید سند را آسان تر می کند زیرا تنها روش های مورد نیاز برای بازدید کننده خاص باید نادیده گرفته شود. لازم نیست که تمام روش های بازدید کننده را نادیده بگیریم.
مثال زیر نشان می دهد که چگونه از الگوی بازدید کننده برای اضافه کردن عملیات جدید به مدل شیء Aspose.Words استفاده کنیم. در این حالت، ما یک مبدل سند ساده به قالب متن ایجاد می کنیم:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Extract content.docx"); | |
ConvertDocToTxt convertToPlainText = new ConvertDocToTxt(); | |
// Note that every node in the object model has the accept method so the visiting | |
// can be executed not only for the whole document, but for any node in the document. | |
doc.accept(convertToPlainText); | |
// Once the visiting is complete, we can retrieve the result of the operation, | |
// That in this example, has accumulated in the visitor. | |
System.out.println(convertToPlainText.getText()); |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
/// <summary> | |
/// Simple implementation of saving a document in the plain text format. Implemented as a Visitor. | |
/// </summary> | |
static class ConvertDocToTxt extends DocumentVisitor { | |
public ConvertDocToTxt() { | |
mIsSkipText = false; | |
mBuilder = new StringBuilder(); | |
} | |
/// <summary> | |
/// Gets the plain text of the document that was accumulated by the visitor. | |
/// </summary> | |
public String getText() { | |
return mBuilder.toString(); | |
} | |
/// <summary> | |
/// Called when a Run node is encountered in the document. | |
/// </summary> | |
public int visitRun(Run run) { | |
appendText(run.getText()); | |
// Let the visitor continue visiting other nodes. | |
return VisitorAction.CONTINUE; | |
} | |
/// <summary> | |
/// Called when a FieldStart node is encountered in the document. | |
/// </summary> | |
public int visitFieldStart(FieldStart fieldStart) { | |
// In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows | |
// after a field start character. We want to skip field codes and output field. | |
// Result only, therefore we use a flag to suspend the output while inside a field code. | |
// Note this is a very simplistic implementation and will not work very well. | |
// If you have nested fields in a document. | |
mIsSkipText = true; | |
return VisitorAction.CONTINUE; | |
} | |
/// <summary> | |
/// Called when a FieldSeparator node is encountered in the document. | |
/// </summary> | |
public int visitFieldSeparator(FieldSeparator fieldSeparator) { | |
// Once reached a field separator node, we enable the output because we are | |
// now entering the field result nodes. | |
mIsSkipText = false; | |
return VisitorAction.CONTINUE; | |
} | |
/// <summary> | |
/// Called when a FieldEnd node is encountered in the document. | |
/// </summary> | |
public int visitFieldEnd(FieldEnd fieldEnd) { | |
// Make sure we enable the output when reached a field end because some fields | |
// do not have field separator and do not have field result. | |
mIsSkipText = false; | |
return VisitorAction.CONTINUE; | |
} | |
/// <summary> | |
/// Called when visiting of a Paragraph node is ended in the document. | |
/// </summary> | |
public int visitParagraphEnd(Paragraph paragraph) { | |
// When outputting to plain text we output Cr+Lf characters. | |
appendText(ControlChar.CR_LF); | |
return VisitorAction.CONTINUE; | |
} | |
public int visitBodyStart(Body body) { | |
// We can detect beginning and end of all composite nodes such as Section, Body, | |
// Table, Paragraph etc and provide custom handling for them. | |
mBuilder.append("*** Body Started ***\r\n"); | |
return VisitorAction.CONTINUE; | |
} | |
public int visitBodyEnd(Body body) { | |
mBuilder.append("*** Body Ended ***\r\n"); | |
return VisitorAction.CONTINUE; | |
} | |
/// <summary> | |
/// Called when a HeaderFooter node is encountered in the document. | |
/// </summary> | |
public int visitHeaderFooterStart(HeaderFooter headerFooter) { | |
// Returning this value from a visitor method causes visiting of this | |
// Node to stop and move on to visiting the next sibling node | |
// The net effect in this example is that the text of headers and footers | |
// Is not included in the resulting output | |
return VisitorAction.SKIP_THIS_NODE; | |
} | |
/// <summary> | |
/// Adds text to the current output. Honors the enabled/disabled output flag. | |
/// </summary> | |
private void appendText(String text) { | |
if (!mIsSkipText) | |
mBuilder.append(text); | |
} | |
private StringBuilder mBuilder; | |
private boolean mIsSkipText; | |
} |
فقط متن را استخراج کنید
راه های بازیابی متن از سند عبارتند از:
- از Document.save با SaveFormat برای ذخیره به عنوان متن ساده در یک فایل یا جریان استفاده کنید
- از Node.toString استفاده کنید و پارامتر
SaveFormat.Text
را منتقل کنید. در داخل، این save as text را به یک جریان حافظه فرا می خواند و رشته حاصل را باز می گرداند - برای بازیابی متن با تمام کاراکترهای کنترل Microsoft Word از جمله کدهای فیلد از Node.getText استفاده کنید
- پیاده سازی یک DocumentVisitor سفارشی برای انجام استخراج سفارشی
با استفاده از Node.GetText
و Node.ToString
یک سند ورد می تواند شامل کاراکترهای کنترل باشد که عناصر خاصی مانند فیلد، انتهای سلول، انتهای بخش و غیره را تعیین می کند. لیست کامل کاراکترهای کنترل کلمه ممکن در کلاس ControlChar تعریف شده است. روش GetText متن را با تمام کاراکترهای کاراکتر کنترل موجود در گره باز می گرداند.
فراخوانی ToString نمایش متن ساده سند را تنها بدون کاراکترهای کنترل باز می گرداند. برای اطلاعات بیشتر در مورد صادرات به عنوان متن ساده به Using SaveFormat.Text مراجعه کنید.
مثال کد زیر تفاوت بین فراخوانی روش های GetText و ToString در یک گره را نشان می دهد:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
builder.insertField("MERGEFIELD Field"); | |
// When converted to text it will not retrieve fields code or special characters, | |
// but will still contain some natural formatting characters such as paragraph markers etc. | |
// This is the same as "viewing" the document as if it was opened in a text editor. | |
System.out.println("ToString() Result: " + doc.toString(SaveFormat.TEXT)); |
با استفاده از SaveFormat.Text
این مثال سند را به شرح زیر ذخیره می کند:
- فیلتر کردن کاراکترهای فیلد و کدهای فیلد، شکل، زیرنویس، پایان نامه و مرجع نظرات
- کاراکترهای پایان پاراگراف ControlChar.Cr را با ترکیب ControlChar.CrLf جایگزین می کند
- از کدگذاری UTF8 استفاده می کند
مثال کد زیر نشان می دهد که چگونه یک سند را در فرمت TXT ذخیره کنید:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Document.docx"); | |
doc.save(getArtifactsDir() + "BaseConversions.DocxToTxt.txt"); |
استخراج تصاویر از اشکال
ممکن است برای انجام برخی کارها نیاز به استخراج تصاویر سند داشته باشید. Aspose.Words به شما اجازه می دهد این کار را نیز انجام دهید.
مثال کد زیر نشان می دهد که چگونه تصاویر را از یک سند استخراج کنید:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Images.docx"); | |
NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); | |
int imageIndex = 0; | |
for (Shape shape : (Iterable<Shape>) shapes) { | |
if (shape.hasImage()) { | |
String imageFileName = | |
MessageFormat.format("Image.ExportImages.{0}_{1}", imageIndex, FileFormatUtil.imageTypeToExtension(shape.getImageData().getImageType())); | |
// Note, if you have only an image (not a shape with a text and the image), | |
// you can use shape.getShapeRenderer().save(...) method to save the image. | |
shape.getImageData().save(getArtifactsDir() + imageFileName); | |
imageIndex++; | |
} | |
} |