2017-08-17 45 views
1

我正在使用OpenXML API修改docx模板並遇到問題。使用OpenXML中的Word文檔處理OpenXmlElement中的DocumentPart

我需要將圖像插入到某個位置 - 該位置由Content Controll元素定義,該元素可以位於文檔的主要部分,頁腳的頁眉中。

我越來越含量控制研究是這樣的:

static IEnumerable<TElement> GetDecendants<TElement>(OpenXmlPart part) where TElement : OpenXmlElement 
{ 
    var result = part.RootElement 
     .Descendants() 
     .OfType<TElement>(); 

    return result; 
} 

後來下來的管道,我需要現在我的問題是圖像通過該

internal static OpenXmlElement InsertImage(OpenXmlPart documentPart, Stream stream, string fileName, int imageWidth, int imageHeight) 
{ 
    // actual implementation that is tested and works 
} 

插入到文檔的正確部分當我發現一個需要被圖像替換的ContentControl元素時,我沒有對documentPart的引用 - 我只有參考SdtRunSdtBlock

有沒有辦法從SdtRun導航到documentPart?我檢查了.Parent,但找不到從OpenXmlElementOpenXmlPart的方法 - 這些方法處於不同的層次結構中。

回答

2

我推薦以下方法。它採用Ancestor避免recursion工作,從C#6

internal static OpenXmlPart GetMainDocumentPart(OpenXmlElement xmlElement) 
    { 
     return 
     xmlElement?.Ancestors<Document>()?.FirstOrDefault()?.MainDocumentPart as OpenXmlPart ?? 
     xmlElement?.Ancestors<Footer>()?.FirstOrDefault()?.FooterPart as OpenXmlPart ?? 
     xmlElement?.Ancestors<Header>()?.FirstOrDefault()?.HeaderPart as OpenXmlPart; 
    } 
+0

哇優勢短路Null-conditional Operators的!這是很多問號!我將在返回工作時檢查它。謝謝! – trailmax

+1

這通常起作用。但是當'xmlElement'是'Header'或'Document'或'Footer'時失敗 - 它沒有相同類型的祖先。然而,一般的想法和指向我的祖先<>()(我以前不知道的方法)很好 – trailmax

+0

其實'Header','Footer'和'Document'每個都是'OpenXmlPart',而不是'OpenXmlElement',所以用它們調用這個方法甚至不會編譯,更不用說運行了。我認爲這種方法應該適合你。 – Taterhead

1

通過OpenXML的源代碼,我發現了一種方法,做了我所需要的。只有它被標記爲internal,我無法在我的代碼中使用它。

於是我想出了這一點:

using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 
using System; 


internal static class XmlElementHelpers 
{ 
    internal static OpenXmlPart GetDocumentPart(this OpenXmlElement xmlElement) 
    { 
     if (xmlElement == null) 
     { 
      return null; 
     } 
     if (xmlElement is Document document) 
     { 
      return document.MainDocumentPart; 
     } 

     if (xmlElement is Header header) 
     { 
      return header.HeaderPart; 
     } 

     if (xmlElement is Footer footer) 
     { 
      return footer.FooterPart; 
     } 

     return GetDocumentPart(xmlElement.Parent); 
    } 
} 
相關問題