将页眉和页脚复制到所有其他文档OpenXML

时间:2017-10-04 08:25:26

标签: c# ms-word openxml-sdk

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

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

有没有办法让这个页眉和页脚完全从一个文档复制到另一个文档?

1 个答案:

答案 0 :(得分:1)

我还必须为工作中的客户实施此操作。 我会给你我为页眉和页脚编写的方法。

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

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

尝试理解阅读我写的评论。

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

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

再见。