Copy Header and Footer to all other Documents OpenXML

半世苍凉 提交于 2019-12-11 13:29:12

问题


We have a master docx with the header and footer in and nothing else (formatted with images). We have 100s of word documents with body content but no header and footer and we want to be able to process these when we populate them and add the header and footer from the master header and footer docx.

I have looked at the MSDN documentation here: https://msdn.microsoft.com/en-us/library/cc546917.aspx but it doesn't seem to work and when I open the target document the formatting is wrong and the images are missing.

Is there a way to make this exactly copy the header and footer from one document to another?


回答1:


I also had to implement this for a client at work. I'll give you the methods I wrote for headers and footers.

I wrote trying to keep all styles, fonts, dimensions and images inside header and footer.

This is the method that i use to attach header to another docx.

Try to understand reading the comments I've written.

headerTemplatePath: path of docx where take header

documentPath: path of docx where append header

    public void PrependHeader(string headerTemplatePath, string documentPath)
    {
        // Open docx where we need to add header
        using (var wdDoc = WordprocessingDocument.Open(documentPath, true))
        {
            var mainPart = wdDoc.MainDocumentPart;

            // Delete exist header
            mainPart.DeleteParts(mainPart.HeaderParts);

            // Create new header
            var headerPart = mainPart.AddNewPart<HeaderPart>();

            // Get id of new header
            var rId = mainPart.GetIdOfPart(headerPart);

            // Open the header document to be copied
            using (var wdDocSource = WordprocessingDocument.Open(headerTemplatePath, true))
            {
                // Get header part
                var firstHeader = wdDocSource.MainDocumentPart.HeaderParts.FirstOrDefault();
                if (firstHeader != null)
                {
                    // Copy content of header to new header
                    headerPart.FeedData(firstHeader.GetStream());
                    // Keep formatting
                    foreach (var childElement in headerPart.Header.Descendants<Paragraph>())
                    {
                        var paragraph = (Paragraph) childElement;
                        if (paragraph.ParagraphProperties.SpacingBetweenLines == null)
                        {
                            paragraph.ParagraphProperties.SpacingBetweenLines = new SpacingBetweenLines
                            {
                                After = "0"
                            };
                            paragraph.ParagraphProperties.ParagraphStyleId = new ParagraphStyleId
                            {
                                Val = "No Spacing"
                            };
                        }
                    }
                    // Get all ids of every 'Parts'
                    var listToAdd = new List<KeyValuePair<Type, Stream>>();
                    foreach (var idPart in firstHeader.Parts)
                    {
                        var part = firstHeader.GetPartById(idPart.RelationshipId);
                        if (part is ImagePart)
                        {
                            headerPart.AddNewPart<ImagePart>("image/png", idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (ImagePart), part.GetStream()));
                        }
                        else if (part is DiagramStylePart)
                        {
                            headerPart.AddNewPart<DiagramStylePart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramStylePart), part.GetStream()));
                        }
                        else if (part is DiagramColorsPart)
                        {
                            headerPart.AddNewPart<DiagramColorsPart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramColorsPart),
                                part.GetStream()));
                        }
                        else if (part is DiagramDataPart)
                        {
                            headerPart.AddNewPart<DiagramDataPart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramDataPart), part.GetStream()));
                        }
                        else if (part is DiagramLayoutDefinitionPart)
                        {
                            headerPart.AddNewPart<DiagramStylePart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramStylePart), part.GetStream()));
                        }
                        else if (part is DiagramPersistLayoutPart)
                        {
                            headerPart.AddNewPart<DiagramPersistLayoutPart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramPersistLayoutPart),
                                part.GetStream()));
                        }
                    }
                    // Foreach Part, copy stream to new header
                    var i = 0;
                    foreach (var idPart in headerPart.Parts)
                    {
                        var part = headerPart.GetPartById(idPart.RelationshipId);
                        if (part.GetType() == listToAdd[i].Key)
                        {
                            part.FeedData(listToAdd[i].Value);
                        }
                        i++;
                    }
                }
                else
                {
                    mainPart.DeleteParts(mainPart.HeaderParts);
                    var sectToRemovePrs = mainPart.Document.Body.Descendants<SectionProperties>();
                    foreach (var sectPr in sectToRemovePrs)
                    {
                        // Delete reference of old header
                        sectPr.RemoveAllChildren<HeaderReference>();
                    }
                    return;
                }
            }

            // Get all sections, and past header to each section (Page)
            var sectPrs = mainPart.Document.Body.Descendants<SectionProperties>();
            foreach (var sectPr in sectPrs)
            {
                // Remove old header reference 
                sectPr.RemoveAllChildren<HeaderReference>();
                // Add new header reference
                sectPr.PrependChild(new HeaderReference { Id = rId });
            }
        }
    }

Footer method:

footerTemplatePath: path of docx where take footer

documentPath: path of docx where append footer

    public void PrependFooter(string footerTemplatePath, string documentPath)
    {
        // Open docx where append footer
        using (var wdDoc = WordprocessingDocument.Open(documentPath, true))
        {
            var mainPart = wdDoc.MainDocumentPart;

            // Remove exist footer
            mainPart.DeleteParts(mainPart.FooterParts);

            // Create new footer
            var footerParts = mainPart.AddNewPart<FooterPart>();

            // Get Id of new footer
            var rId = mainPart.GetIdOfPart(footerParts);

            // Open the footer document to be copied
            using (var wdDocSource = WordprocessingDocument.Open(footerTemplatePath, true))
            {
                var firstFooter = wdDocSource.MainDocumentPart.FooterParts.LastOrDefault();
                if (firstFooter != null)
                {
                    // Copy content of footer
                    footerParts.FeedData(firstFooter.GetStream());
                    // Keep formatting
                    foreach (var childElement in footerParts.Footer.Descendants<Paragraph>())
                    {
                        var paragraph = (Paragraph) childElement;
                        if (paragraph.ParagraphProperties.SpacingBetweenLines == null)
                        {
                            paragraph.ParagraphProperties.SpacingBetweenLines = new SpacingBetweenLines
                            {
                                After = "0"
                            };
                            paragraph.ParagraphProperties.ParagraphStyleId = new ParagraphStyleId
                            {
                                Val = "No Spacing"
                            };
                        }
                    }
                    // Create list of Parts ID needed to new footer
                    var listToAdd = new List<KeyValuePair<Type, Stream>>();
                    foreach (var idPart in firstFooter.Parts)
                    {
                        var part = firstFooter.GetPartById(idPart.RelationshipId);
                        if (part is ImagePart)
                        {
                            footerParts.AddNewPart<ImagePart>("image/png", idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (ImagePart), part.GetStream()));
                        }
                        else if (part is DiagramStylePart)
                        {
                            footerParts.AddNewPart<DiagramStylePart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramStylePart), part.GetStream()));
                        }
                        else if (part is DiagramColorsPart)
                        {
                            footerParts.AddNewPart<DiagramColorsPart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramColorsPart),
                                part.GetStream()));
                        }
                        else if (part is DiagramDataPart)
                        {
                            footerParts.AddNewPart<DiagramDataPart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramDataPart), part.GetStream()));
                        }
                        else if (part is DiagramLayoutDefinitionPart)
                        {
                            footerParts.AddNewPart<DiagramStylePart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramStylePart), part.GetStream()));
                        }
                        else if (part is DiagramPersistLayoutPart)
                        {
                            footerParts.AddNewPart<DiagramPersistLayoutPart>(idPart.RelationshipId);
                            listToAdd.Add(new KeyValuePair<Type, Stream>(typeof (DiagramPersistLayoutPart),
                                part.GetStream()));
                        }
                    }
                    // Foreach ID, copy stream to new footer
                    var i = 0;
                    foreach (var idPart in footerParts.Parts)
                    {
                        var part = footerParts.GetPartById(idPart.RelationshipId);
                        if (part.GetType() == listToAdd[i].Key)
                        {
                            part.FeedData(listToAdd[i].Value);
                        }
                        i++;
                    }
                }
                else
                {
                    mainPart.DeleteParts(mainPart.FooterParts);
                    var sectToRemovePrs = mainPart.Document.Body.Descendants<SectionProperties>();
                    foreach (var sectPr in sectToRemovePrs)
                    {
                        // Delete reference of footer
                        sectPr.RemoveAllChildren<FooterReference>();
                    }
                    return;
                }
            }

            // Get all sections, and past footer to each section (Page)
            var sectPrs = mainPart.Document.Body.Descendants<SectionProperties>();
            foreach (var sectPr in sectPrs)
            {
                // Delete old reference
                sectPr.RemoveAllChildren<FooterReference>();
                // Add new footer reference
                sectPr.PrependChild(new FooterReference { Id = rId });
            }
        }
    }

Sorry for my English, if you have any questions, let me know.

Bye.



来源:https://stackoverflow.com/questions/46560269/copy-header-and-footer-to-all-other-documents-openxml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!