InsertAtFound.cs
- //
- // This code is part of Document Solutions for Word demos.
- // Copyright (c) MESCIUS inc. All rights reserved.
- //
- using System;
- using System.IO;
- using System.Drawing;
- using System.Linq;
- using GrapeCity.Documents.Word;
-
- namespace DsWordWeb.Demos
- {
- // This sample shows how to insert the whole body of an existing DOCX into
- // another document at a location where an arbitrary search string is found.
- // One interesting point in this sample is that the code ensures that the
- // insert position is valid, i.e. the source content (all paragraphs of
- // the source document) can be inserted at the found point. If necessary,
- // the target is split so that there is a content object of a valid type
- // at the point where the source is to be inserted.
- // In this sample, the target document is JsFrameworkExcerpt.
- // The source document inserted is SampleParagraphs, and it is inserted
- // on page 2 of the source document, immediately before the string
- // "software design principles".
- public class InsertAtFound
- {
- public GcWordDocument CreateDocx()
- {
- // The string to find. The source document will be inserted before this string:
- const string findPattern = "software design principles";
-
- // Target document where the source document will be inserted:
- var doc = new GcWordDocument();
- doc.Load(Path.Combine("Resources", "WordDocs", "JsFrameworkExcerpt.docx"));
-
- // Source document that will be inserted into the target:
- var sourceDoc = new GcWordDocument();
- sourceDoc.Load(Path.Combine("Resources", "WordDocs", "SampleParagraphs.docx"));
- // Note: the inserted document starts with a 'Heading 1', which adds a page break.
- // We change it to 'Heading 2' to avoid this so that the result is more clear:
- sourceDoc.Body.Paragraphs.First.Style = sourceDoc.Styles[BuiltInStyleId.Heading2];
-
- // Find the first occurrence of the search string:
- var findResult = doc.Body.Find(findPattern, new FindOptions(doc) { IgnoreCase = true }).FirstOrDefault();
- if (findResult == null)
- throw new Exception("Unexpected: search string not found.");
-
- // Find a valid insertion point near the found string:
- var insertObject = CreateInsertPoint(findResult);
-
- // Copy the source document to the target at insertion point:
- sourceDoc.Body.CopyTo(insertObject.GetRange(), InsertLocation.Before);
-
- // Done:
- return doc;
- }
-
- // Walk up the parent chain and determine where we are - inside body, cell or contentcontrol.
- // Return the original object if we are inside body or cell.
- // Return contentcontrol if we are inside contentcontrol.
- private static ContentObject GetAnchorObject(ContentObject testedObject)
- {
- var originalObject = testedObject;
- while (true)
- {
- if (testedObject.ParentContent == null)
- return originalObject;
- else if (testedObject is Cell)
- return originalObject;
- else if (testedObject is ContentControl)
- return testedObject;
- else
- testedObject = testedObject.ParentContent;
- }
- }
-
- // This method assumes that testObject is always an entity inside a paragraph.
- private static Paragraph GetParentParagraph(ContentObject testObject)
- {
- while (testObject != null)
- {
- if (testObject is Paragraph)
- return (Paragraph)testObject;
- testObject = testObject.ParentContent;
- }
- throw new ArgumentException("testObject is not inside a paragraph.");
- }
-
- private static ContentObject CreateInsertPoint(FindResult fr)
- {
- var anchorObject = GetAnchorObject(fr.Range.First());
- var foundParagraph = GetParentParagraph(anchorObject);
-
- if (fr.StartIndex > 0 && anchorObject is Text)
- anchorObject = ((Text)anchorObject).Split(fr.StartIndex);
- if (foundParagraph == anchorObject)
- anchorObject = foundParagraph.Split(anchorObject, InsertLocation.End);
- else
- anchorObject = foundParagraph.Split(anchorObject, InsertLocation.Before);
- return anchorObject;
- }
- }
- }
-