【问题标题】:Copy Header and Footer to all other Documents OpenXML将页眉和页脚复制到所有其他文档 OpenXML
【发布时间】:2018-06-01 21:48:39
【问题描述】:

我们有一个包含页眉和页脚的主 docx,没有其他内容(用图像格式化)。我们有 100 多个带有正文内容但没有页眉和页脚的 word 文档,我们希望能够在填充它们并从主页眉和页脚 docx 添加页眉和页脚时处理这些文档。

我在这里查看了 MSDN 文档:https://msdn.microsoft.com/en-us/library/cc546917.aspx,但它似乎不起作用,当我打开目标文档时,格式错误并且图像丢失。

有没有办法将页眉和页脚从一个文档准确复制到另一个文档?

【问题讨论】:

    标签: c# ms-word openxml-sdk


    【解决方案1】:

    我还必须为工作中的客户实现这一点。 我会给你我为页眉和页脚编写的方法。

    我试图在页眉和页脚中保留所有样式、字体、尺寸和图像。

    这是我用来将标题附加到另一个 docx 的方法。

    试着读懂我写的cmets。

    headerTemplatePath: 获取header的docx路径

    documentPath: docx 的路径,其中追加标题

        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 });
                }
            }
        }
    

    页脚方法:

    footerTemplatePath: docx 的路径

    documentPath:添加页脚的docx路径

        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 });
                }
            }
        }
    

    对不起我的英语,如果您有任何问题,请告诉我。

    再见。

    【讨论】:

    • 如何在标题中插入 html 字符串?
    • 这对我来说效果很好,但是如果它基于样式,它似乎不会从源文档中复制现有的字体和大小
    • 这真是太棒了。我可以看到它取自 MSDN,然后添加到。为什么在地球上这不是微软示例的一部分?干得好。
    • @Kristopher 谢谢老哥,我不知道为什么微软的例子里没有。
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多