Hi,
I see now, you’re using System.IO.Packaging
to modify the DOCX file’s internal XML.
Try saving that modified document stream into a DOCX file, for example:
// ...
// flush and return
package.Close();
documentStream.Position = 0;
// Save the modified "documentStream" as "modified.docx" file.
File.WriteAllBytes("modified.docx", ((MemoryStream)documentStream).ToArray());
var document = GemBox.Document.DocumentModel.Load(documentStream, GemBox.Document.LoadOptions.DocxDefault);
Now open that “modified.docx” file in Microsoft Word, you’ll see this:
In other words, the interpretation of those newline characters in the older version of GemBox.Document was wrong. As you can see from the above screenshot, Microsoft Word doesn’t treat them as new lines. The newer versions of GemBox.Document have a fix for this.
Anyway, what you need to do is instead of using the ‘\n’ character use the <w:br/>
XML element.
So, instead of this line of code:
placeholder.Element(W.sdtContent).Descendants(W.t).Single().Value = contentDic[tag];
You would need these lines of code:
var textElement = placeholder.Element(W.sdtContent).Descendants(W.t).Single();
var replaceTextElements = new XRaw(string.Join("<w:br/>",
contentDic[tag].Split('\n').Select(line => $"<w:t>{line}</w:t>")));
textElement.ReplaceWith(replaceTextElements);
Also, here is the XRaw
element that I’m using in those lines:
public class XRaw : XText
{
public XRaw(string text) : base(text) { }
public XRaw(XText text) : base(text) { }
public override void WriteTo(XmlWriter writer) => writer.WriteRaw(this.Value);
}
Last, in case you’re interested, to achieve this with just GemBox.Document is much simpler than this.
All you need to do is this:
using System.Collections.Generic;
using GemBox.Document;
using GemBox.Document.CustomMarkups;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
TestGemboxDocument();
}
static void TestGemboxDocument()
{
const string inputFile = "test.docx";
string outputFile = "test_edited";
var document = DocumentModel.Load(inputFile);
var contentDic = new Dictionary<string, string>
{
["variable"] = "foo\vbreak\vfoo2"
};
foreach (IContentControl placeholder in document.GetChildElements(true,
ElementType.InlineContentControl, ElementType.BlockContentControl))
{
string tag = placeholder.Properties.Tag;
if (tag == null || !contentDic.TryGetValue(tag, out string value))
continue;
placeholder.Content.LoadText(value, placeholder.Properties.CharacterFormat);
}
bool saveAsPDF = true;
if (saveAsPDF)
document.Save(outputFile + ".pdf");
else
document.Save(outputFile + ".docx");
}
}
One difference you should note, I replaced the ‘\n’ characters with ‘\v’ because they represent different things.
The first one is a hard break or the paragraph’s end, you get that when using ENTER in Microsoft Word.
The second one is a soft break or the line break character, you get that when using SHIFT + ENTER in Microsoft Word.
I hope this helps, let me know if you have any questions.
Regards,
Mario