2013-12-22 53 views
2

我正在嘗試將Microsoft Word 2010中的大綱轉換爲Microsoft Excel 2010中的電子表格。我使用DocumentFormat.OpenXml.PackingDocumentformat.OpenXml.Wordprocessing如何使用C#和OpenXml訪問Word文檔中大綱的編號?

我得到的文檔的身體,並用它來獲取所有段落對象的列表:

var allParagraphs = new List<Paragraph>(); 
WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(wordDocPath.Text, false); 
Body body = wordprocessingDocument.MainDocumentPart.Document.Body; 
allParagraphs = body.OfType<Paragraph>().ToList(); 

但我似乎無法找到任何商店該段落旁邊的大綱編號。除了文檔中的段落外,是否需要抓取其他對象以獲取每個段落的大綱數字(如果有的話)?

大綱編號我所說的似乎這些標題的左邊下面的截圖:

outline numbering of an outline

不幸的是,ParagraphProperties.OutlineLevel爲null,儘管我知道這是一個大綱的一部分在word文檔中。

+0

我不知道你通過大綱編號推斷出什麼,你可以發佈一個屏幕截圖,突出顯示它是什麼,然後也許我可以幫助你。 –

+0

@VarunRathore,我添加了我正在談論的屏幕截圖。我的目標是讓這個窗口應用程序處理所有這些,但我相信OpenXml可能沒有我正在尋找的功能。現在我已經轉移到Word文檔中的vba,但肯定會更喜歡使用C#路線。 –

回答

3

既然我已經明白你想要的是什麼,下面是你應該如何解決你的問題。

首先,我建議您從here下載Open XML Productivity工具。一旦你知道底層xml是什麼樣子的文件,它就變得很容易解決這個問題。

<w:p w:rsidR="004265BF" w:rsidP="00AD13B6" w:rsidRDefault="00AD13B6"> 
<w:pPr> 
    <w:pStyle w:val="ListParagraph" /> 
    <w:numPr> 
    <w:ilvl w:val="0" /> 
    <w:numId w:val="2" /> 
    </w:numPr> 
</w:pPr> 
<w:r> 
    <w:t>Requirements</w:t> 
</w:r> 
</w:p> 
<w:p w:rsidR="00AD13B6" w:rsidP="00AD13B6" w:rsidRDefault="00AD13B6"> 
<w:pPr> 
    <w:pStyle w:val="ListParagraph" /> 
    <w:numPr> 
    <w:ilvl w:val="1" /> 
    <w:numId w:val="2" /> 
    </w:numPr> 
    </w:pPr> 
    <w:r> 
    <w:t>Performance</w:t> 
    </w:r> 
</w:p> 

上面你可以看到只有幾個段落的XML。每個段落都有相應的幷包含。

每個單詞文檔都包含許多不同的XML文件,這些文件充當整個文檔正文中使用的樣式和值的引用。對於大綱,有Numbering.xml。

這裏的每個numId引用Numbering.xml中的AbstractNumId,並且該引用又指同一文件中的abstractNum。你可以從那裏得到你的綱要號碼。

我知道這聽起來很乏味,但這是唯一可以完成的方法。

Open Xml Productivity Tool Snapshot

一切順利!

using (WordprocessingDocument doc = WordprocessingDocument.Open("word-wrP.docx", true)) 
     { 
      Body body = doc.MainDocumentPart.Document.Body; 

      //Documents' numbering definition 
      Numbering num = doc.MainDocumentPart.NumberingDefinitionsPart.Numbering; 

      //Get all paragraphs in the document 
      IEnumerable<Paragraph> paragraphs = doc.MainDocumentPart.Document.Body.OfType<Paragraph>(); 
      foreach (Paragraph paragraph in paragraphs) 
      { 
       int tempLevel = 0; 

       //Each paragraph has a reference to a numbering definition that is defined by the numbering ID 
       NumberingId numId = paragraph.ParagraphProperties.NumberingProperties.NumberingId; 

       //NumberingLevelReference defines the outline level or the "indent" of Numbering, index starts at Zero. 
       NumberingLevelReference iLevel = 
        paragraph.ParagraphProperties.NumberingProperties.NumberingLevelReference; 

       //From the numbering reference we get the actual numbering definition to get start value of the outline etc etc. 
       var firstOrDefault = 
        num.Descendants<NumberingInstance>().FirstOrDefault(tag => tag.NumberID == (int)numId.Val); 
       if (firstOrDefault != null) 
       { 
        var absNumId = 
         firstOrDefault.GetFirstChild<AbstractNumId>(); 
        AbstractNum absNum = 
         num.OfType<AbstractNum>().FirstOrDefault(tag => tag.AbstractNumberId == (int)absNumId.Val); 
        if (absNum != null) 
        { 
         StartNumberingValue start = absNum.OfType<StartNumberingValue>().FirstOrDefault(); 
         // once you have the start value its just a matter of counting the paragraphs that have the same numberingId and from the Number 
         //ingLevel you can calculate the actual values that correspond to each paragraph. 
         if (start != null) startValue = start.Val; 
        } 
       } 
       else 
       { 
        Console.WriteLine("Failed!"); 
       } 
      } 
     } 
+0

哇這個工具真棒!它在C#中爲你生成代碼?你應該得到+1。我可能最終會給你答案,一旦我使用它多一點,看看這是否會爲我工作。似乎它會盡管... –

+0

我很高興我能夠幫助:) –

+0

再次感謝您的幫助。如果你不介意的話,你能否以一個例子進一步幫助我。我一直在試圖編寫特定於上述示例的C#代碼,其中大綱與Heading#樣式綁定。我無法找到不同部分(或.xml)文件之間的關聯。如果您有這方面的經驗,您是否介意向我展示如何在示例屏幕截圖中爲每個段落獲得大綱編號? –

相關問題