Search code examples
c#openxml-sdkcarriage-returnlinefeed

OpenXml-SDK: How to insert Plaintext with CarriageReturn/Linefeed


Currently I´m having a Word-Template with an RTF-FormField in it, in this FormField I want to insert Plaintext that comes from a MSSQL-Database.

With this Method I´m setting the Content of any FormField in my Document(including my RTF-FormField)

public static void SetContentControlValue(this WordprocessingDocument doc, string name, string value)
{
    var main = doc.MainDocumentPart;

    var stdRuns = main.Document.Body
                      .Descendants<SdtRun>()
                      .Where(r => r.SdtProperties.GetFirstChild<Tag>().Val.Value.ToLower().Equals(name))
                      .ToList();

    stdRuns.ForEach(c => c.Descendants<Text>().First().Text = value);

    main.Document.Body
                 .Descendants<SdtBlock>()
                 .Where(r => r.SdtProperties.GetFirstChild<Tag>().Val.Value.ToLower().Equals(name))
                 .ToList()
                 .ForEach(c => c.Descendants<Text>().First().Text = value);
}

Unfortunately it swallows CarriageReturn/Linefeed

I tried to do it this way

var run = new SdtRun();

string[] newLineArray = { Environment.NewLine };
string[] textArray = value.Split(newLineArray, StringSplitOptions.None);

bool first = true;
foreach (var line in textArray)
{
    if (!first)
    {
        run.Append(new Break());
    }
    first = false;

    Text txt = new Text();
    txt.Text = line;
    run.Append(txt);
}
main.Document.Body.Append(run);

but unfortunately this breaks the WordDocument and I can´t open it anymore :-/

Anybody here maybe had the same Problem and has an Idea how I can insert the Text without losing the Plaintext-Formatting (CarriageReturns and Linefeeds)?


Solution

  • So finally I found a Solution by myself, you can use AltChunk to Insert Plaintext and not losing your formatting :-)

    Here is the Code maybe it helps someone out who has the same Problem ;-)

    public static void SetNotes(this WordprocessingDocument doc, string value)
    {
        MainDocumentPart main = doc.MainDocumentPart;
        string altChunkId = "AltChunkId" + Guid.NewGuid().ToString().Replace("-", "");
        var chunk = main.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.TextPlain, altChunkId);
    
        using (var mStream = new MemoryStream())
        {
            using (var writer = new StreamWriter(mStream))
            {
                writer.Write(value);
                writer.Flush();
                mStream.Position = 0;
                chunk.FeedData(mStream);
            }
        }
    
        var altChunk = new AltChunk();
        altChunk.Id = altChunkId;
    
        OpenXmlElement afterThat = null;
        foreach (var para in main.Document.Body.Descendants<Paragraph>())
        {
            if (para.InnerText.Equals("Notes:"))
            {
                afterThat = para;
            }
        }
        main.Document.Body.InsertAfter(altChunk, afterThat);
    }