lundi 17 août 2015

Openxml replace multiple content placeholders in same paragraph

I am trying to create a word document from c# MVC application by replacing the ContetnPlaceHolder informations with the text from application data .

I am using the below code to do this and this code will find all content Placeholders in the word document and replace it with the text information's passed from the application .

    using (WordprocessingDocument theDoc = WordprocessingDocument.Open(targetFile, true))
    {
        MainDocumentPart mainPart = theDoc.MainDocumentPart;
        List<SdtBlock> ccWithTable = mainPart.Document.Body.Descendants<SdtBlock>().ToList(); //Get list of RichText COntetncontrols 
        List<SdtRun> ccRun = mainPart.Document.Body.Descendants<SdtRun>().ToList();//get list of Text content controls
        foreach (SdtBlock sdt in ccWithTable)
        {
            //fetch tag name of content control
            string tag_name = sdt.SdtProperties.GetFirstChild<Tag>().Val.ToString().Trim();

            //fetch text to replace based on the tag name from application
            string text_to_replace=GETTextToReplace(tag_name);

            //grab the RunProperties from the SdtBlcok [ existing style information and apply to all new Run instances]
            RunProperties runProp = sdt.SdtProperties.GetFirstChild<RunProperties>();                     

            //Compose new paragraph for teh given tag 
            Paragraph new_paragraph = returnPara(text_to_replace, runProp);
            //insert the new paragraph before the field we're going to remove
            sdt.Parent.InsertBefore(new_paragraph, sdt);
            //remove the SdtBlock to mimic the Remove content control when contents are edited option
            sdt.Remove();
        }
        foreach (SdtRun sdt in ccRun)
        {
            //It will also work but keep contentCOntrol editor as it is 
            //sdt.Descendants<Text>().First().Text = "mynew test";

            //fetch tagname from content control
            string tag_name = sdt.SdtProperties.GetFirstChild<Tag>().Val.ToString();

            //fetch text to replace based on the tag name from application
            string text_to_replace=GETTextToReplace(tag_name);

            //grab the RunProperties from the SdtBlcok [ existing style information and apply to all new Run instances]
            RunProperties runProp = sdt.SdtProperties.GetFirstChild<RunProperties>();

            //Compose new paragraph for teh given tag 
            Paragraph new_paragraph = returnPara(text_to_replace, runProp);

            OpenXmlElement parent = sdt.Parent;
            sdt.Remove(); // delete SdtBlock
            parent.Append(new_paragraph);
        }
        mainPart.Document.Save();
    }


    private Paragraph returnPara(string text_to_replace,RunProperties proprty)
    {
        Paragraph para_itm= new Paragraph();
        Run run_item = new Run();
        if (proprty != null)
        {
            //assign the RunProperties to our new run
            run_item.Append(proprty.CloneNode(true));
        }
        run_item.Append(new Text(text_to_replace));
        para_itm.Append(run_item);
        return para_itm;
    }

The problem with this approach is i am using the Replace and add approach [ to remove placeholder from word document after replacing the text information ]. So if there are multiple placeholders exists in the same line then now all are adding in different different lines

Example: Line 1: Here is my [content1] and in same line my [content2]

Then in the output word document i can see content1 and content2 are going to next to next lines like below

Here is my and in same line my

Content1

content2

Also if i have a placeholder as right aligned in a paragraph then its ocming to left only in generated word document

So how can i iterate through all paragraphs and then find placeholders in paragraph and then replace the content with the text from application.

Aucun commentaire:

Enregistrer un commentaire