none
Copy Header content from an AutoText entry RRS feed

  • Question

  • Hi Cindy

    Sorry for delay, but the schedule is full..

    I've finally had time to look into this.
    I have located the XML-parts of the template and the corresponding headier/footer in a document.
    The documents 1:st header for instance are located in the /word/header1.xml file.
    In the template this part is located in /word/glossary/document.xml, together with all the other AutoText-entries in the template.
    If I was to copy and paste XML-code I can see the logic, but my intention is to use Open XML SDK, and I can't find any reference or help on how I retrieve the specified docPart from the template.
    The MSDN documentation only shows declarations and totally useless code samples.

    The links you referred to handles copying of existing headers and also the section-setting part. The latter which I believe is the last step after inserting the headers and footers in the document.

    Can you assist me in the right direction?
    How can I retrieve for instance the AutoText called Header1Sv from the Glossary docParts collection?

    Thanks in advance


    Best Regards Peter Karlström Midrange AB, Sweden

    • Split by Cindy Meister MVPModerator Wednesday, January 23, 2013 2:08 PM new question; split from http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/65229a52-bdd3-4cb8-ab8c-203286aa87b4#ae77e5dc-32cd-4e18-8951-3b88fc31b33d
    Tuesday, January 22, 2013 2:30 PM

Answers

  • Hi Peter

    Here's some code (sorry, C# again) that opens a template, checks for the Glossary and searches an entry named Header1Sv. It stores the InnerXML as a string.

    It also reads the Header style definition. This would be necessary if you want to override the style definition in the target document with what's saved with the AutoText (and assuming that was the Header style).

    The target document is opened, the style definitions are copied to the Header style in the target (this code assumes that style is present in the document). Then the header content is copied to the first Header part in the document. (It's quite late, here, so I didn't do a search for a specific header, such as the first header reference in the document - I just took the first header part.)

    private void btnHeaderFromAutoText_Click(object sender, EventArgs e)
    {
        string targetPath = @"C:\Test\TestCopiedHeaderFromAT.docx";
        string sourcePath = @"C:\Test\TestOXML_BB.dotx";
    
        using (WordprocessingDocument sourcePkg = WordprocessingDocument.Open(sourcePath, false))
        {
            MainDocumentPart mainSourcePart = sourcePkg.MainDocumentPart;
            if (mainSourcePart.GetPartsCountOfType<GlossaryDocumentPart>() > 0)
            {
                GlossaryDocument glossDoc = mainSourcePart.GetPartsOfType<GlossaryDocumentPart>().FirstOrDefault().GlossaryDocument;
                DocPart glossPart = glossDoc.Descendants<DocPart>().Where(g => g.DocPartProperties.DocPartName.Val.ToString() == "Header1Sv").FirstOrDefault();
                StyleDefinitionsPart glossStyle = mainSourcePart.GetPartsOfType<GlossaryDocumentPart>().FirstOrDefault().StyleDefinitionsPart;
                Style hStyle = glossStyle.Styles.Descendants<Style>().Where(s => s.StyleId.Value.ToString() == "Header").FirstOrDefault();
                StyleParagraphProperties paraProps = hStyle.StyleParagraphProperties;
                StyleRunProperties runProps = hStyle.StyleRunProperties;
                string headerXML = glossPart.DocPartBody.InnerXml;
                //System.Diagnostics.Debug.Print(headerXML);
                using (WordprocessingDocument targetPkg = WordprocessingDocument.Open(targetPath, true))
                {
                    MainDocumentPart mainTargetPart = targetPkg.MainDocumentPart;
                    StyleDefinitionsPart docStyle = mainTargetPart.StyleDefinitionsPart;
                    Style hTargetStyle = docStyle.Styles.Descendants<Style>().Where(s => s.StyleId.Value.ToString() == "Header").FirstOrDefault();
                    StyleParagraphProperties paraTargetProps = hTargetStyle.StyleParagraphProperties;
                    StyleRunProperties runTargetProps = hTargetStyle.StyleRunProperties;
                    paraTargetProps.InnerXml = paraProps.InnerXml;
                    runTargetProps.InnerXml = runProps.InnerXml;
                    
                    Header h = mainTargetPart.HeaderParts.FirstOrDefault().Header;
                    h.InnerXml = headerXML;
                }
            }
            else System.Diagnostics.Debug.Print("No Glossary part found.");
        }
    
    }


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, January 22, 2013 9:36 PM
    Moderator
  • You need to put new questions in a new discussion thread so that there is one topic / discussion and we can close discussions.

    <<Do you know a way of getting the relation copied?>>

    If you look for my discussion with Heel Tar, in this forum, I cover how to pick up the reference to a graphic from a Header, look up the graphic and copy it to a different file in the code done for that discussion. I'm not sure whether it's in the discussion or in the code sample I did for my blog (a link in a reply). As the code was created for transferring headers between documents it will probably need some adjustments for working between glossary and document, but the principles should remain the same.

    For future questions it would be a good idea for you to more carefully analyse exactly what it is you need - my schedule is full, too :-)


    Cindy Meister, VSTO/Word MVP, my blog

    Wednesday, January 23, 2013 2:13 PM
    Moderator

All replies

  • Hi Peter

    Here's some code (sorry, C# again) that opens a template, checks for the Glossary and searches an entry named Header1Sv. It stores the InnerXML as a string.

    It also reads the Header style definition. This would be necessary if you want to override the style definition in the target document with what's saved with the AutoText (and assuming that was the Header style).

    The target document is opened, the style definitions are copied to the Header style in the target (this code assumes that style is present in the document). Then the header content is copied to the first Header part in the document. (It's quite late, here, so I didn't do a search for a specific header, such as the first header reference in the document - I just took the first header part.)

    private void btnHeaderFromAutoText_Click(object sender, EventArgs e)
    {
        string targetPath = @"C:\Test\TestCopiedHeaderFromAT.docx";
        string sourcePath = @"C:\Test\TestOXML_BB.dotx";
    
        using (WordprocessingDocument sourcePkg = WordprocessingDocument.Open(sourcePath, false))
        {
            MainDocumentPart mainSourcePart = sourcePkg.MainDocumentPart;
            if (mainSourcePart.GetPartsCountOfType<GlossaryDocumentPart>() > 0)
            {
                GlossaryDocument glossDoc = mainSourcePart.GetPartsOfType<GlossaryDocumentPart>().FirstOrDefault().GlossaryDocument;
                DocPart glossPart = glossDoc.Descendants<DocPart>().Where(g => g.DocPartProperties.DocPartName.Val.ToString() == "Header1Sv").FirstOrDefault();
                StyleDefinitionsPart glossStyle = mainSourcePart.GetPartsOfType<GlossaryDocumentPart>().FirstOrDefault().StyleDefinitionsPart;
                Style hStyle = glossStyle.Styles.Descendants<Style>().Where(s => s.StyleId.Value.ToString() == "Header").FirstOrDefault();
                StyleParagraphProperties paraProps = hStyle.StyleParagraphProperties;
                StyleRunProperties runProps = hStyle.StyleRunProperties;
                string headerXML = glossPart.DocPartBody.InnerXml;
                //System.Diagnostics.Debug.Print(headerXML);
                using (WordprocessingDocument targetPkg = WordprocessingDocument.Open(targetPath, true))
                {
                    MainDocumentPart mainTargetPart = targetPkg.MainDocumentPart;
                    StyleDefinitionsPart docStyle = mainTargetPart.StyleDefinitionsPart;
                    Style hTargetStyle = docStyle.Styles.Descendants<Style>().Where(s => s.StyleId.Value.ToString() == "Header").FirstOrDefault();
                    StyleParagraphProperties paraTargetProps = hTargetStyle.StyleParagraphProperties;
                    StyleRunProperties runTargetProps = hTargetStyle.StyleRunProperties;
                    paraTargetProps.InnerXml = paraProps.InnerXml;
                    runTargetProps.InnerXml = runProps.InnerXml;
                    
                    Header h = mainTargetPart.HeaderParts.FirstOrDefault().Header;
                    h.InnerXml = headerXML;
                }
            }
            else System.Diagnostics.Debug.Print("No Glossary part found.");
        }
    
    }


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, January 22, 2013 9:36 PM
    Moderator
  • Hi Cindy

    Finally I managed to get the procedure to insert headerXML into the new headers.innerXML.

    But a new problem arised...

    The header witch I retrieve from the templates Autotext entries contains an image.

    When I open the document I get an error, and after some search I can se that the relation to the image is not updated in the document.

    Now, I have found sample code of how to copy the image relation from one documents header to another, but this approach does not apply here, since there is no header from where I can get this information, only the innerXML code of the Autotext.

    Do you know a way of getting the relation copied?

    Thanks in advance


    Best Regards Peter Karlström Midrange AB, Sweden

    Wednesday, January 23, 2013 1:59 PM
  • You need to put new questions in a new discussion thread so that there is one topic / discussion and we can close discussions.

    <<Do you know a way of getting the relation copied?>>

    If you look for my discussion with Heel Tar, in this forum, I cover how to pick up the reference to a graphic from a Header, look up the graphic and copy it to a different file in the code done for that discussion. I'm not sure whether it's in the discussion or in the code sample I did for my blog (a link in a reply). As the code was created for transferring headers between documents it will probably need some adjustments for working between glossary and document, but the principles should remain the same.

    For future questions it would be a good idea for you to more carefully analyse exactly what it is you need - my schedule is full, too :-)


    Cindy Meister, VSTO/Word MVP, my blog

    Wednesday, January 23, 2013 2:13 PM
    Moderator