InsertAtFound.cs
  1. //
  2. // This code is part of Document Solutions for Word demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.Drawing;
  8. using System.Linq;
  9. using GrapeCity.Documents.Word;
  10.  
  11. namespace DsWordWeb.Demos
  12. {
  13. // This sample shows how to insert the whole body of an existing DOCX into
  14. // another document at a location where an arbitrary search string is found.
  15. // One interesting point in this sample is that the code ensures that the
  16. // insert position is valid, i.e. the source content (all paragraphs of
  17. // the source document) can be inserted at the found point. If necessary,
  18. // the target is split so that there is a content object of a valid type
  19. // at the point where the source is to be inserted.
  20. // In this sample, the target document is JsFrameworkExcerpt.
  21. // The source document inserted is SampleParagraphs, and it is inserted
  22. // on page 2 of the source document, immediately before the string
  23. // "software design principles".
  24. public class InsertAtFound
  25. {
  26. public GcWordDocument CreateDocx()
  27. {
  28. // The string to find. The source document will be inserted before this string:
  29. const string findPattern = "software design principles";
  30.  
  31. // Target document where the source document will be inserted:
  32. var doc = new GcWordDocument();
  33. doc.Load(Path.Combine("Resources", "WordDocs", "JsFrameworkExcerpt.docx"));
  34.  
  35. // Source document that will be inserted into the target:
  36. var sourceDoc = new GcWordDocument();
  37. sourceDoc.Load(Path.Combine("Resources", "WordDocs", "SampleParagraphs.docx"));
  38. // Note: the inserted document starts with a 'Heading 1', which adds a page break.
  39. // We change it to 'Heading 2' to avoid this so that the result is more clear:
  40. sourceDoc.Body.Paragraphs.First.Style = sourceDoc.Styles[BuiltInStyleId.Heading2];
  41.  
  42. // Find the first occurrence of the search string:
  43. var findResult = doc.Body.Find(findPattern, new FindOptions(doc) { IgnoreCase = true }).FirstOrDefault();
  44. if (findResult == null)
  45. throw new Exception("Unexpected: search string not found.");
  46.  
  47. // Find a valid insertion point near the found string:
  48. var insertObject = CreateInsertPoint(findResult);
  49.  
  50. // Copy the source document to the target at insertion point:
  51. sourceDoc.Body.CopyTo(insertObject.GetRange(), InsertLocation.Before);
  52.  
  53. // Done:
  54. return doc;
  55. }
  56.  
  57. // Walk up the parent chain and determine where we are - inside body, cell or contentcontrol.
  58. // Return the original object if we are inside body or cell.
  59. // Return contentcontrol if we are inside contentcontrol.
  60. private static ContentObject GetAnchorObject(ContentObject testedObject)
  61. {
  62. var originalObject = testedObject;
  63. while (true)
  64. {
  65. if (testedObject.ParentContent == null)
  66. return originalObject;
  67. else if (testedObject is Cell)
  68. return originalObject;
  69. else if (testedObject is ContentControl)
  70. return testedObject;
  71. else
  72. testedObject = testedObject.ParentContent;
  73. }
  74. }
  75.  
  76. // This method assumes that testObject is always an entity inside a paragraph.
  77. private static Paragraph GetParentParagraph(ContentObject testObject)
  78. {
  79. while (testObject != null)
  80. {
  81. if (testObject is Paragraph)
  82. return (Paragraph)testObject;
  83. testObject = testObject.ParentContent;
  84. }
  85. throw new ArgumentException("testObject is not inside a paragraph.");
  86. }
  87.  
  88. private static ContentObject CreateInsertPoint(FindResult fr)
  89. {
  90. var anchorObject = GetAnchorObject(fr.Range.First());
  91. var foundParagraph = GetParentParagraph(anchorObject);
  92.  
  93. if (fr.StartIndex > 0 && anchorObject is Text)
  94. anchorObject = ((Text)anchorObject).Split(fr.StartIndex);
  95. if (foundParagraph == anchorObject)
  96. anchorObject = foundParagraph.Split(anchorObject, InsertLocation.End);
  97. else
  98. anchorObject = foundParagraph.Split(anchorObject, InsertLocation.Before);
  99. return anchorObject;
  100. }
  101. }
  102. }
  103.