zoukankan      html  css  js  c++  java
  • 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函数,就完成啦!对比一下需求,这个标题是完!全!一!样!

  • 相关阅读:
    JavaScript 多个空格替换成1个空格
    「DIARY」NOI2021 小结
    kubernetes常用命令总结
    Qt绘图(使用QPainter)翻转图像的两种方法
    android 11 R framework 新特证 开发备忘
    浏览器的缓存机制
    记el-tree 懒加载复选框回显的坑
    VUE根据文件流下载EXC
    西瓜视频播放器VUE
    推荐系统打散算法--权重
  • 原文地址:https://www.cnblogs.com/Pray4U/p/15534738.html
Copyright © 2011-2022 走看看