[英]How do you create multi-level ordered lists with Open XML in ASP.net?
我花了無數個小時試圖理解 Open XML 中的有序列表。 這里是一個多引用。
我發現了一個簡單的文檔創建者的這種難以置信的幫助例子在這里。
另外,如果我可能會抱怨一點,我必須說這是一個痛苦的學習曲線。 創建編號屬性並引用正確的abstractNumberId
並且該列表不斷重復。
有沒有人有在代碼中創建多級列表的完整示例? 我可以在沒有自定義設置的情況下這樣做,就像設置NumberFormatValues.Decimal
。 一旦您想開始控制listType
您就會有很多即時開銷。
以我開始的上述示例為例,我添加了一個level
參數:
public void AddBulletList(List<Run> runList, int level)
我把它合並在這條線上:
var abstractLevel = new Level(new NumberingFormat() {
Val = NumberFormatValues.Decimal}, new LevelText() {Val = "·"}) {LevelIndex = level};
請注意,我將格式類型更改為十進制……方法名稱顯示為 bullet 但我只是在此處進行測試。
我還利用它來處理縮進:
var indentation = new Indentation() { Left = (720 * (level + 1)).ToString(), Hanging = "360" };
因此,在我的測試中,我向傳入0
表示級別的方法發送了幾句話。 然后我再發送一些傳入1
的級別。
我的結果有兩個問題:
1)我不知道如何重置計數器,所以我得到了這個:
1. Sentence 1
2. Sentence 2
3. Sentence 3
4. Sentence 1
5. Sentence 2
6. Sentence 3
我嘗試使用levelRestart
但這沒有用:
abstractLevel.LevelRestart = new LevelRestart(){ Val = 0 } // tried 1 also
我可以讓它重新啟動的唯一方法是在插入第二個句子列表之前插入一個空白段落,但這有樣式問題(間距)。
我遇到的第二個問題是編號出現在 WordDoc 中,但它在 Microsoft Word 中顯示為項目符號。 此外,我在 Microsoft Word 中收到兼容模式警告。
有人會過來說:
使用 Open XML Productivity Tools 並創建一個文檔並查看生成的代碼
好吧,我對此的回應是:
在看了 5,000 行代碼后,我的眼睛在流血,這是一個用來測試的小文檔。
所以我覺得我非常接近。 我的代碼中有很多其他自定義項,這就是為什么我繼續引用我開始的地方。 如果有人可以采用該示例或提供現有示例,我只想創建多級列表並控制使用的編號類型(lowerRoman、decimal 等)。
更新 1
我真的只需要硬着頭皮做一些認真的學習。 在托馬斯的幫助下,我已經能夠繼續前進,但似乎我還有一個棘手的問題。 我的新有序列表不是從“1”開始的。
請注意在圖像中,如果我單擊第一個列表的級別,它只會突出顯示該列表。 我希望它們是分開的,但顯然不是。 下一個列表應該從 1 開始。
對於每個新的有序列表,我都為它分配了一個新的numberId
所以我不知道發生了什么。 這是生成的標記:
<w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14">
<w:abstractNum w:abstractNumId="1" w15:restartNumberingAfterBreak="1">
<w:nsid w:val="191025D9" />
<w:multiLevelType w:val="hybridMultilevel" />
<w:tmpl w:val="48A2E570" />
<w:lvl w:ilvl="0" w:tplc="0409000F">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:start="720" w:hanging="360" />
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1" w:tplc="04090019">
<w:start w:val="1" />
<w:numFmt w:val="lowerLetter" />
<w:lvlText w:val="%2." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:start="1440" w:hanging="360" />
</w:pPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="2" w15:restartNumberingAfterBreak="1">
<w:nsid w:val="191025D9" />
<w:multiLevelType w:val="hybridMultilevel" />
<w:tmpl w:val="48A2E570" />
<w:lvl w:ilvl="0" w:tplc="0409000F">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:start="720" w:hanging="360" />
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1" w:tplc="04090019">
<w:start w:val="1" />
<w:numFmt w:val="lowerLetter" />
<w:lvlText w:val="%2." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:start="1440" w:hanging="360" />
</w:pPr>
</w:lvl>
</w:abstractNum>
<w:num w:numId="1">
<w:abstractNumId w:val="1" />
</w:num>
<w:num w:numId="2">
<w:abstractNumId w:val="2" />
</w:num>
</w:numbering>
這是身體:
<w:body xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph" />
<w:numPr>
<w:ilvl w:val="0" />
<w:numId w:val="1" />
</w:numPr>
</w:pPr>
<w:r>
<w:t>List one item 1</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph" />
<w:numPr>
<w:ilvl w:val="0" />
<w:numId w:val="1" />
</w:numPr>
</w:pPr>
<w:r>
<w:t>List one item 2</w:t>
</w:r>
</w:p>
<w:p>
<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>List two item 1</w:t>
</w:r>
</w:p>
<w:p>
<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>List two item 2</w:t>
</w:r>
</w:p>
</w:body>
雖然我從未使用過 Open XML Productivity Tools,但我經常使用並推薦Open XML Package Editor for Modern Visual Studios 。 使用該包編輯器,您可以查看 Microsoft Word 創建的 Open XML 標記以從中學習。
因此,為了回答您的問題,我已經這樣做了,使用包含多個多級列表的 Word 模板,這些列表的行為與您希望它們的行為完全相同(我希望)。
(a) First paragraph, on outline level 0 (shown as 1 in Word)
(b) Second paragraph, on outline level 0
(1) Third paragraph, on outline level 1 (shown as 2 in Word)
(2) Fourth paragraph, on outline level 1
請注意,您的多級列表的不同級別通常會有不同的編號格式(例如,小寫字母、大寫字母、小寫羅馬字母、大寫羅馬字母、十進制)。
接下來,這是主文檔部分對應的 Open XML 標記:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="ListLowerLetter0"/>
</w:pPr>
<w:r>
<w:t>First paragraph, on outline level 0 (shown as 1 in Word)</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="ListLowerLetter0"/>
</w:pPr>
<w:r>
<w:t>Second paragraph, on outline level 0</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="ListLowerLetter0"/>
<w:numPr>
<w:ilvl w:val="1"/> <!-- This overrides the numbering level -->
<w:numId w:val="43"/> <!-- This references the w:numbering/w:num -->
</w:numPr>
</w:pPr>
<w:r>
<w:t>Third paragraph, on outline level 1 (shown as 2 in Word)</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="ListLowerLetter0"/>
<w:numPr>
<w:ilvl w:val="1"/>
<w:numId w:val="43"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Fourth paragraph, on outline level 1</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
請注意w:pStyle
和w:numPr
元素,它們指定要使用的編號段落樣式,並且在也使用w:numPr
情況下,會覆蓋樣式中指定的編號默認值。
接下來,這是樣式定義部分的 Open XML 標記:
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<!-- This is the paragraph style used in the main document part (w:document) -->
<w:style w:type="paragraph" w:customStyle="1" w:styleId="ListLowerLetter0">
<w:name w:val="List Lower Letter 0"/>
<w:basedOn w:val="Normal"/>
<w:pPr>
<w:numPr>
<w:numId w:val="43"/> <!-- This references the w:numbering/w:num -->
</w:numPr>
</w:pPr>
</w:style>
<!-- This is the list style referenced in the numbering definitions part (w:numbering).
This is optional but helps if you want to use the list in Word. -->
<w:style w:type="numbering" w:customStyle="1" w:styleId="ListLowerLetter0List">
<w:name w:val="List Lower Letter 0 List"/>
<w:basedOn w:val="NoList"/>
<w:pPr>
<w:numPr>
<w:numId w:val="43"/> <!-- This references the w:numbering/w:num -->
</w:numPr>
</w:pPr>
</w:style>
<!-- I've included this for completeness because it is referenced by our
paragraph style below -->
<w:style w:type="paragraph" w:default="1" w:styleId="Normal">
<w:name w:val="Normal"/>
<w:rPr>
<w:kern w:val="16"/>
</w:rPr>
</w:style>
<!-- I've included this for completeness because it is referenced by our
list style below -->
<w:style w:type="numbering" w:default="1" w:styleId="NoList">
<w:name w:val="No List"/>
<w:semiHidden/>
<w:unhideWhenUsed/>
</w:style>
</w:styles>
我只需要ListLowerLetter0
樣式。 ListLowerLetter0List
是可選的列表樣式。 我總是在我的模板中使用它們。 其他兩種風格只是為了完整性和一致性。 顯然,現實生活中的樣式定義部分包含更多樣式和其他元素。
最后,我們有編號定義部分的 Open XML 標記(同樣帶有解釋相關元素作用的注釋):
<w:numbering xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
mc:Ignorable="w14 w15">
<!-- Here's an example multi-level list -->
<w:abstractNum w:abstractNumId="67" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="3E434843" />
<w:multiLevelType w:val="multilevel" />
<w:tmpl w:val="1146F302" />
<!-- The w:styleLink references our list style. This is optional (but I use
it as a best practice in Word) -->
<w:styleLink w:val="ListLowerLetter0List" />
<!-- This defines the first outline level, i.e., 0 in Open XML lingo or 1
when you look at it in Word -->
<w:lvl w:ilvl="0">
<!-- This starts the level at the ordinal number 1, i.e., "a" on this level -->
<w:start w:val="1" />
<!-- This defines the number format on this level -->
<w:numFmt w:val="lowerLetter" />
<!-- This references our paragraph style, which will be the same on each level -->
<w:pStyle w:val="ListLowerLetter0" />
<!-- This defines the level text, e.g., (a), (b), (c), ... -->
<w:lvlText w:val="(%1)" />
<!-- The next elements define alignment, indentation, and color -->
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="851" w:hanging="851" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<!-- This and the following w:lvl elements define levels 1 to 8 (i.e., 2 to 9 in Word) -->
<w:lvl w:ilvl="1">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="(%2)" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="1418" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="2">
<w:start w:val="1" />
<w:numFmt w:val="upperLetter" />
<w:lvlText w:val="(%3)" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="1985" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="3">
<w:start w:val="1" />
<w:numFmt w:val="lowerRoman" />
<w:lvlText w:val="(%4)" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="2552" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="4">
<w:start w:val="1" />
<w:numFmt w:val="lowerLetter" />
<w:lvlText w:val="%5." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="3119" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="5">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%6." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="3686" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="6">
<w:start w:val="1" />
<w:numFmt w:val="lowerLetter" />
<w:lvlText w:val="%7." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="4253" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="7">
<w:start w:val="1" />
<w:numFmt w:val="lowerRoman" />
<w:lvlText w:val="%8." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="4820" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="8">
<w:start w:val="1" />
<w:numFmt w:val="lowerLetter" />
<w:lvlText w:val="%9)" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="5387" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:color w:val="auto" />
</w:rPr>
</w:lvl>
</w:abstractNum>
<!-- This is the w:num referenced from our main document part (w:document) -->
<w:num w:numId="43">
<w:abstractNumId w:val="67" />
</w:num>
</w:numbering>
現在,基於對創建所需效果所需的標記的理解,使用以下任一方法手寫生成該標記的 C# 代碼實際上非常容易:
讓我為這兩個選項提供非常簡短的示例,生成以下標記:
<w:num w:numId="43">
<w:abstractNumId w:val="67" />
</w:num>
下面是使用Open XML SDK的強類型類的代碼:
var num = new NumberingInstance
{
NumberID = 43,
AbstractNumId = new AbstractNumId { Val = 67 }
};
這是使用Open-XML-PowerTools的代碼:
var num =
new XElement(W.num, new XAttribute(W.numId, 43),
new XElement(W.abstractNumId, new XAttribute(W.val, 67)));
在這種情況下,Open-XML-PowerTools 的美妙之處在於您可以逐字復制標簽名稱。 此外,Linq to XML 類的構造函數(例如XElement
)比 Open XML SDK 的構造函數靈活得多,並且 C# 代碼看起來很像 Open XML 標記。 因此,對於像這樣的用例,我對 Open-XML-PowerTools 略有偏好。 但是,我也非常成功地將 Open XML SDK 用於此類情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.