VSTO(C#)对Word开发积累

最近有个对于格式检测的需求实现,但是相关资料很是欠缺,往往只能通过参考Java、VBA的相关方法,以及通过花费大量的时间来自我实践验证。深感VSTO对Word开发资料的匮乏,希望这些小总结对你有所帮助。该文基本没有相关理论,希望对你有所帮助。
如果你有好的书籍,希望你能留言推荐给我,谢谢。

一、准备工作

using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools;

1、获取当前Word应用程序

 // 变量声明
 public Word.Application m_app;
 // 方法一:
 m_app = Globals.ThisAddIn.Application;
 // 方法二:
 m_app =(Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");

2、如何获取当前文档

Word.Document doc = m_app.ActiveDocument;

二、如何通过VSTO设置Word正文、标题、目录等的样式?

1、获取所有的样式

int nCount = m_app.ActiveDocument.Styles.Count;
for(int j = 1; j <= nCount; j++)
 {
     Word.Style stl = m_app.ActiveDocument.Styles[j];
 }

2、如何区分这些样式?样式的种类几种?
大的分为段落样式、字符样式、表样式等共5类。但是,段落样式这个分类里可能就包含上百的子样式(姑且这样区分样式)。
Style里面有个类成员变量Type表明了样式的分类,以下是Style接口的成员变量源码:

//Returns the style type. Read-only Microsoft.Office.Interop.Word.Style.
WdStyleType Type { get; }

WdStyleType 是一个枚举变量

public enum WdStyleType
{
    // Paragraph style.
    wdStyleTypeParagraph = 1,

    // Body character style.
    wdStyleTypeCharacter = 2,

    // Table style.
    wdStyleTypeTable = 3,

    // List style.
    wdStyleTypeList = 4,

    // Reserved for internal use.
    wdStyleTypeParagraphOnly = 5,

    // Reserved for internal use.
    wdStyleTypeLinked = 6
}

段落样式:wdStyleTypeParagraph
字符样式:wdStyleTypeCharacter
表样式:wdStyleTypeTable
列表样式:wdStyleTypeList
留作内部使用:wdStyleTypeParagraphOnly
留作内部使用:wdStyleTypeLinked = 6
3、正文、标题、目录这些子样式在哪个分类?
在段落样式分类里(通过测试已经),如果你无法区分哪个样式在那里面,可以调用Style的成员NameLocal,这是一个字符串变量,标明了样式的名字,便于区分。
如何获得正文、标题等样式?

int nCount = m_app.ActiveDocument.Styles.Count;
Word.Style style;
for (int j = 1; j <= nCount; j++)
{
    style = m_app.ActiveDocument.Styles[j];
    // 段落样式
    if (style.Type == Word.WdStyleType.wdStyleTypeParagraph)
    {
        if (style.NameLocal == "正文")// 可以直接设置正文的样式
        {
            // 如果是,就获得了正文的style。然后再通过style获取或者正文的字体格式、段落格式等
        }
        else if(style.NameLocal == "标题 1")
        {
            // 获取标题1 的样式,再进行自己的一些操作
        }
        else if(style.NameLocal == "标题 2")
        {
            ...
        }
        else
        {
            ...
        }
    }
    // 字符样式
    else if(style.Type == Word.WdStyleType.wdStyleTypeCharacter)
    {
        ...
    }
    else
    {
        ...
    }
}

三、VSTO生成Word目录

m_app.Selection.Start = 0;
m_app.Selection.End = 0;
object beginLevel = 1;
object endLevel = 3;
object tightAlignPageNumber = true;
object n = System.Reflection.Missing.Value;
object enableLink = true;

m_app.Selection.Font.Bold = 1;
m_app.Selection.Font.Size = 14;// 四号
m_app.Selection.Font.Name = "黑体";
m_app.Selection.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
m_app.Selection.ParagraphFormat.LineSpacingRule = Word.WdLineSpacing.wdLineSpaceExactly;// 固定值
m_app.Selection.ParagraphFormat.LineSpacing = float.Parse("20");// 20 磅
m_app.Selection.TypeText("目    录");
m_app.Selection.TypeParagraph();// 换行
m_app.Selection.TypeParagraph();// 换行
m_app.Selection.TypeParagraph();// 换行

//插入目录
m_app.ActiveDocument.TablesOfContents.Add(m_app.Selection.Range, ref n, ref beginLevel, ref endLevel, ref n, ref n, ref n, ref n, ref n, ref enableLink, ref n, ref n);

四、如何对现有Word的格式进行矫正?

遍历所有的段落,判断是标题还是正文,如果是标题,则是几级标题,然后对该段落进行相对应的标题格式设置;如果是正文,则对正文进行矫正。
例如下,对标题一、标题二、标题三进行纠正

Word.Paragraphs paras = m_app.ActiveDocument.Paragraphs;
int count = paras.Count;
Word.Paragraph para;

for (int i = 1; i <= count; i++)
{
    switch (paras[i].OutlineLevel)
    {
        // 一级标题
        case Word.WdOutlineLevel.wdOutlineLevel1:
            {
                para = paras[i];
                para.Range.Font.Bold = 0;// 不加粗
                para.Range.Font.Size = float.Parse("15");// 小三
                para.Range.Font.Name = "黑体";// 黑体
                para.Range.Font.Color = Word.WdColor.wdColorBlack;// 黑色
                para.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;// 居中
                para.Range.ParagraphFormat.LineSpacingRule = Word.WdLineSpacing.wdLineSpaceExactly;// 固定值
                para.Range.ParagraphFormat.LineSpacing = float.Parse("20");// 20 磅
            }
            break;

        // 二级标题
        case Word.WdOutlineLevel.wdOutlineLevel2:
            {
                para = paras[i];
                para.Range.Font.Bold = 0;// 不加粗
                para.Range.Font.Size = float.Parse("14");// 四号
                para.Range.Font.Name = "黑体";// 黑体
                para.Range.Font.Color = Word.WdColor.wdColorBlack;// 黑色
                para.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;// 左对齐
                para.Range.ParagraphFormat.LineSpacingRule = Word.WdLineSpacing.wdLineSpaceExactly;// 固定值
                para.Range.ParagraphFormat.LineSpacing = float.Parse("20");// 20 磅
            }
            break;

        // 三级标题
        case Word.WdOutlineLevel.wdOutlineLevel3:
            {
                para = paras[i];
                para.Range.Font.Bold = 0;// 不加粗
                para.Range.Font.Size = float.Parse("12");// 小四
                para.Range.Font.Name = "宋体";// 宋体
                para.Range.Font.Color = Word.WdColor.wdColorBlack;// 黑色
                para.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;// 左对齐
                para.Range.ParagraphFormat.LineSpacingRule = Word.WdLineSpacing.wdLineSpaceExactly;// 固定值
                para.Range.ParagraphFormat.LineSpacing = float.Parse("20");// 20 磅
            }
            break;
        default:
            break;
    }
}

注:字体的大小只能通过数字表示,不能直接写小三、四号等。
源码中是通过段落的OutlineLevel属性判断段落的大纲级别,而OutlineLevel是WdOutlineLevel的枚举变量,WdOutlineLevel枚举原型如下:

public enum WdOutlineLevel
{
    wdOutlineLevel1 = 1,
    wdOutlineLevel2 = 2,
    wdOutlineLevel3 = 3,
    wdOutlineLevel4 = 4,
    wdOutlineLevel5 = 5,
    wdOutlineLevel6 = 6,
    wdOutlineLevel7 = 7,
    wdOutlineLevel8 = 8,
    wdOutlineLevel9 = 9,
    wdOutlineLevelBodyText = 10
}

五、如何对选中的文本进行格式的修改?

首先,如果要对选中的文本格式进行修改,最好是由一个按钮实现。
方法为:通过选中相应的文本后,点击按钮,然后执行对选中文本的更改即可。
如下:

 private void BTN_Click(object sender, RibbonControlEventArgs e)
{
    Word.Selection select = m_app.Selection;
    Word.Range rg = select.Range;

    rg.Font.Bold = 0; // 不加粗
    rg.Font.Size = float.Parse("12"); // 小四
    rg.Font.Name = "宋体";// 宋体
    rg.Font.Color = Word.WdColor.wdColorBlack;// 字体颜色黑色

    select.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphJustify;// 两端对齐
    if (select.ParagraphFormat.CharacterUnitFirstLineIndent == float.Parse("2") || 
        select.ParagraphFormat.FirstLineIndent == rg.Font.Size * 2)// 缩进了两个字符大小
    {
        return;
    }

    select.ParagraphFormat.FirstLineIndent = float.Parse("0");
    select.ParagraphFormat.IndentFirstLineCharWidth(2);// 首行缩进两个字符  
}

既然可以设置正文,同样的能够设置标题格式,通过获取段落的属性进行判断设置即可。

六、进行对Word文档属性的设置

m_doc.PageSetup.TopMargin = m_app.CentimetersToPoints(float.Parse("2.54"));// 上边距
m_doc.PageSetup.BottomMargin = m_app.CentimetersToPoints(float.Parse("2.54"));// 下边距
m_doc.PageSetup.LeftMargin = m_app.CentimetersToPoints(float.Parse("4.17"));// 左边距
m_doc.PageSetup.RightMargin = m_app.CentimetersToPoints(float.Parse("3.17"));// 右边距 

m_doc.PageSetup.Orientation = Word.WdOrientation.wdOrientPortrait;// 页面为纵向
m_doc.PageSetup.GutterPos = Word.WdGutterStyle.wdGutterPosLeft;//装订线位于左侧
m_doc.PageSetup.PageWidth = m_app.CentimetersToPoints(float.Parse("21"));// 纸张宽度
m_doc.PageSetup.PageHeight = m_app.CentimetersToPoints(float.Parse("29.7"));// 纸张高度

m_doc.PageSetup.HeaderDistance = m_app.CentimetersToPoints(float.Parse("1.5"));//页眉顶端距离
m_doc.PageSetup.FooterDistance = m_app.CentimetersToPoints(float.Parse("1.75"));//页脚底端距离

如果需要其他的页面属性,都在PageSetup里面,自己找找就行。
这些成员变量基本都是含有get与set方法,方便进行设置与验证。

开发中找的关于VSTO对Word的资料
Office内置图标的资料(双击可获得图标的id,再外界程序的按钮中填写id即可)

你可能感兴趣的:(word)