OpenXml SDK學習筆記(4):設定檔案級別的樣式

bluesky234發表於2021-11-10

觀察上一段日記最後的程式碼:

 

 

 

這裡的樣式基本可以理解為行內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方法用來處理這些情況,非常尷尬。所以,做的時候讀需求非常重要。另外開發過程中,為了保證使用簡單,我把程式碼重構了好幾次,倒也花了不少時間。最坑的是還不是這些,下篇筆記會講這裡的除錯。

相關文章