觀察上一段日記最後的程式碼:
這裡的樣式基本可以理解為行內CSS。那麼既然有行內的樣式,就肯定有外部的樣式。那這部分就對應筆記1裡說的style.xml檔案。這個檔案對應的是Document.MainDocumentPart.StyleDefinitionsPart這個部分,文件是 https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.packaging.styledefinitionspart 。這部分裡面有一個重要屬性 Styles 。這個屬性裡存著的就是整個文件裡所有用到的樣式,包括顯示在介面上的,和不顯示在介面上的。Styles屬性裡,所有內容都是Style的物件。在學習這個物件前,先要了解Word裡有幾種樣式。在Word中,選擇編輯任何一個樣式,就可以看到:
這樣的介面,他們歸納一下,也就是文件中提到的WordprocessingML的六大樣式:
-
段落樣式
-
字元樣式
-
連結樣式(段落 + 字元)[註釋:通過連結元素實現 (§17.7.4.6)。註釋結束]
-
表樣式
-
編號樣式
-
預設段落 + 字元屬性
其中,在本需求中會用到的就是“段落樣式”和“字元樣式”。所以,只需要學習這兩種樣式的實現方式即可。那麼,再觀察Style物件。這個物件的初始化大致是長這樣的:
ParagraphStyle = new Style()
{
CustomStyle = true,
Type = StyleValues.Paragraph,
StyleName = new StyleName()
{
Val = Name
},
StyleId = paraId,
StyleParagraphProperties = new StyleParagraphProperties(),
StyleRunProperties = new StyleRunProperties()
};
其中,CustomStyle指的是使用者自定義樣式,直接設定為true就可以。Type是樣式的型別,一個列舉,直接設定為Paragraph就可以。再接下來,StyleName就是顯示在視窗中“名稱”一欄的名字。StyleId則是內部用於識別樣式的編號,這個屬性和StyleName都不能重複。接著,StyleParagraphProperties指的是視窗裡下拉欄中“段落”對應的內容,StyleRunProperties指的是視窗裡設定文字字型字號這些內容。
在宣告樣式之後,需要將樣式先儲存在Document.MainDocumentPart.StyleDefinitionsPart.Styles屬性裡。之後,再應用這些樣式。應用時,需要使用到樣式的ID,所以要將Style轉換為樣式ID:
internal ParagraphStyleId ParagraphStyleId => new ParagraphStyleId()
{
Val = ParagraphStyle.StyleId
};
internal RunStyle RunStyleId => new RunStyle()
{
Val = ParagraphStyle.StyleId
};
這兩個屬性分別給誰用是非常明確的。那麼,在WordParagraph裡,書寫一個函式用於適用樣式:
protected override CompositeElementBase SetStyleSafe(WordStyles style)
{
Properties.ParagraphStyleId = style.ParagraphStyleId;
foreach (var item in Children)
{
(item as WordRun)?.SetStyle(style);
}
return this;
}
Run裡面也需要一個這樣的函式,不過用的就是RunStyle,內容是一樣的就不重複了。
最後呢,修改一下AppendParagraph等方法,讓樣式更容易使用就行了。這一篇筆記結束的樣子是這樣的:
和上一章筆記結束時不太一樣的地方是,我發現這個原文居然有左側縮排2.23字元。於是我無奈新加了SetLeftChars和SetRightChars方法用來處理這些情況,非常尷尬。所以,做的時候讀需求非常重要。另外開發過程中,為了保證使用簡單,我把程式碼重構了好幾次,倒也花了不少時間。最坑的是還不是這些,下篇筆記會講這裡的除錯。