OpenXml SDK学习笔记(3):设置样式
作者:互联网
看日志的时间间隔基本就知道我的开发时间了,就样式这一点做了我近1个半小时。所谓设置样式,针对到Word里,大致有这样的内容:
你把平时用不到的内容一去,那么必须要做的功能就列出来了:
字体:设置字体,设置字号,粗体,斜体,下划线
段落:设置对齐方式,设置首行缩进,设置段前,设置段后
这里我特意分了两行。可以看到第一行,是在Word的是“字体”的设置。第二行则是在“段落”这个窗口里设置。针对到代码里,很容易可以发现,其实第一个就是针对Run,第二个就是针对Paragraph来的。所以,在WordprocessingML里,也有专门用来修饰这两个的标签,也就是RunProperties和ParagraphProperties。他们应当是各自母标签的第一个子标签。并且在一个段落和连续文本内,不应该出现两次。
所以,可以根据这样的代码初始化一个ParagraphProperties
1 public override void InitializeElement() 2 { 3 Properties = Run.GetFirstChild<RunProperties>(); 4 if (Properties == null) 5 { 6 Properties = new RunProperties(); 7 Run.PrependChild(Properties); 8 } 9 }
这里必须先找元素再加入,否则如果出现了两个就不太好了。另外,由于大部分组件都有对应的Properties对象,所以这个初始化元素函数就加到CompositeElementBase这个类里,以防之后遗漏。之后就是一个无聊的工作了,按照规定把所有代码都敲完就完整了。在这里,有几个注意点:
1. 处理字号的时候,字号的点数和保存的值的关系是:value = size * 2。并且,这个数是要小于1600的。当然具体的值是1600多一些,记的不是很清楚了,取1600绝对没有问题。所以,字号就是这样的:
public override CompositeElementBase SetFontSize(int sizePoint) { if (sizePoint < 0 || sizePoint > 800) { throw new InvalidOperationException("字体大小必须大于0,并且小于800"); } DefaultRunProperties.FontSize = new DocumentFormat.OpenXml.Wordprocessing.FontSize() { Val = (sizePoint * 2).ToString() }; return SetPropertiesToChildren(); }
2. 一些常用的字号可以用枚举,那由于枚举对应的值只能是int。而常用字号里有几个是有 0.5 的。所以,直接存双倍数就可以。
public enum FontSize : int { ch初号 = 84, xc小初 = 72, yh一号 = 52, xy小一 = 48, eh二号 = 44, xe小二 = 36, sh三号 = 32, xs小三 = 30, sh四号 = 28, xs小四 = 24, hh五号 = 21, xh小五 = 18, lh六号 = 15, xl小六 = 13, qh七号 = 11, bh八号 = 10 }
这里,写中文是为了方便识别。前面带两个拼音是为了打字方便。
3. 字体分为中文字体和西文字体,这两个可以分开设置。Ascii就是西文字体,EastAsia就是中文字体。
public override CompositeElementBase SetFontFamily(string zwFamily, string asciiFamily) { DefaultRunProperties.RunFonts = new RunFonts() { Ascii = asciiFamily, EastAsia = zwFamily }; return SetPropertiesToChildren(); }
4. 下划线是通过一个枚举设置的:UnderlineValues。这个枚举可以查看文档:https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.underlinevalues 。但是在编码的时候,为了可以让最终使用者完全不认识 DocumentFormat.OpenXml.Wordprocessing 这个命名空间,所以,要通过代码对其进行封装。那自己写一个枚举,然后转换一下就行了。注意,这里绝对不推荐图省事直接用“UnderlineValues”,如果直接用了这个东西,那就封了个寂寞。
5. 水平对齐方式不是TextAlignment,这个是垂直对齐。水平对齐的那个属性叫“Justification”对应枚举的MSDN文档是:https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.justificationvalues 。不过,我Html做的比较多,所以函数还是用SetAlign了。同样的,这个枚举也要封装。
6. 在Word里,缩进其实有四种:左缩进,右缩进,首行缩进和悬挂缩进。对应的MSDN文档:https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.indentation 。我常用的只有首行缩进两字符,所以我只留了这个函数:
public override CompositeElementBase SetFirstLineIndent(float chars = 2) { if (chars < 0) { throw new InvalidOperationException("参数chars必须大于 0"); } Properties.Indentation = new Indentation() { FirstLineChars = (int)(chars * 100) }; return this; }
在这里,“FirstLineChars”这个属性的值是字符数乘以100的整数。
7. 段前,段后间距以及行距的 MSDN文档是:https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.spacingbetweenlines 。在这个对象里可以设置上述三种值。间距的单位“磅”在文档里写的是“twentieths”,也就是20分之一。即如果写了10磅。那这个值就是 200,乘以20的关系。而行距一般使用倍数。几倍行距则是 240的多少倍,比如单倍行距,则Line设置为240,两倍行距就是480这样。如果要设置成“最小值”或者“固定值”则需要配合LineRule这个属性。这是一个枚举,也非常简单相信一看就懂。同样的,如果代码要用,那就建议封装一下。
public override CompositeElementBase SetLineHeight(double times) { var sbl = Properties.SpacingBetweenLines; if (sbl == null) { sbl = new SpacingBetweenLines(); Properties.SpacingBetweenLines = sbl; } sbl.Line = (times * 240).ToString(); return this; } public override CompositeElementBase SetLineBefore(int pt) { var sbl = Properties.SpacingBetweenLines; if (sbl == null) { sbl = new SpacingBetweenLines(); Properties.SpacingBetweenLines = sbl; } sbl.Before = (pt * 20).ToString(); return this; } public override CompositeElementBase SetLineAfter(int pt) { var sbl = Properties.SpacingBetweenLines; if (sbl == null) { sbl = new SpacingBetweenLines(); Properties.SpacingBetweenLines = sbl; } sbl.After = (pt * 20).ToString(); return this; }
最后,改一下Main函数,就完成啦!对比一下需求,这个标题是完!全!一!样!
标签:笔记,public,设置,SpacingBetweenLines,new,OpenXml,Properties,sbl,SDK 来源: https://www.cnblogs.com/Pray4U/p/15534738.html