说明(2017-12-22 11:20:44):
1. 因为数学脚本的主标题和副标题没有格式,目录导航里不显示,修改的时候不好定位,所以需要改成下图格式:
2. 问题的难点有两个,一个是word的操作,c#操作word本来应该是顺理成章、水到渠成的,不过实际上并没有很好的参考资料,最权威的MSDN虽然很详细,但是内容太多、查找起来太费劲https://msdn.microsoft.com/vba/vba-word。我查到的一个比较精简的word操作,https://www.cnblogs.com/shi2172843/p/5848116.html,应付一般的问题足够了。但是还有很多不常用的设置,比如我这个设置标题,网上根本就查不到了,研究了半天,得出一个终极结论:使用VBA录制宏,然后去VS里通过智能提示,找到C#里对应的方法,基本跟VBA里的名字是一样的,比如:
VBA里的设置标题,和左对齐:
C#里的设置标题,和左对齐:
3. 问题的第二个难点是,C#对文件的操作,因为设计目标是把文件夹里所有的word文件都获取到,但是Directory.GetDirectories和Directory.GetFiles只能获取一层文件夹里的子文件夹和文件,如果里面还有子文件夹的话就拿不到了。这个问题拖了好几天,昨天晚上灵光一现给解决了。似乎是用了递归,因为一直觉得递归挺难的,之前查的资料也是用的递归,但是我看不太懂,http://blog.csdn.net/kwy15732621629/article/details/72085701,我对那种参数很多、封装很好的方法有点抵触,就决定自己试着写了一个,我记得之前好像是蒋坤说的,递归有两个特点,一个是调用自身,一个是要有返回值,特别注意不要出现无限递归。我觉得自己写的这个方法这两点都做到了,反正写完测试了一下,可以正常获取所有子目录文件。代码如下,应该是很通俗易懂了:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.IO; 6 7 namespace _00_Test 8 { 9 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 string path = @"C:\Users\JJW\Desktop\新建文件夹"; 15 List<string> list = GetFile(path); 16 foreach (string l in list) 17 { 18 Console.WriteLine(l); 19 } 20 Console.ReadKey(); 21 } 22 private static List<string> GetFile(string path) 23 { 24 //传入一个路径 25 List<string> list = new List<string>(); 26 //如果路径是文件夹,继续遍历,把新遍历出来的文件夹和文件存到list 27 if (Directory.Exists(path)) 28 { 29 string[] dirs = Directory.GetDirectories(path); 30 if (dirs != null) 31 { 32 foreach (string dir in dirs) 33 { 34 list.AddRange(GetFile(dir)); 35 } 36 } 37 38 string[] files = Directory.GetFiles(path); 39 if (files != null) 40 { 41 list.AddRange(files); 42 } 43 } 44 //如果路径是文件,添加到list 45 else if (File.Exists(path)) 46 { 47 list.Add(path); 48 } 49 return list; 50 } 51 } 52 }
4. 剩下的是完整代码,为了自己以后方便抄的,不放winform的了,反正就拖一下完事:
Form1.cs
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.IO; 10 using msWord = Microsoft.Office.Interop.Word; 11 12 namespace CheckLabel 13 { 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 } 20 21 private void btnOK_Click(object sender, EventArgs e) 22 { 23 //实例化wordapp类 24 msWord.Application app = new msWord.Application(); 25 //操作时显示word,测试时使用,实际使用时隐藏就可以了 26 app.Visible = false; 27 //判断拖入的文件夹是否存在 28 if (Directory.Exists(txtBox.Text)) 29 { 30 //获取路径下所有doc和docx文件,如果拖入的是文件夹,就需要继续遍历文件夹,这里有两种方式,一种是递归遍历,另一种根据文件夹结构读取每个文件夹,反正每个版本就一层文件夹。 31 //string[] paths = Directory.GetFiles(Path.GetDirectoryName(txtBox.Text), "*.doc*"); 32 List<string> files = GetFile(txtBox.Text); 33 //两个泛型,A是标题1,B是副标题 34 List<string> labelA = new List<string> { "课前预习导学", "课后复习巩固", "自我测试及解答", "能力提升" }; 35 List<string> labelB = new List<string> { "定义及说明", "简单例题", "(三)练习", "课堂回顾", "经典例题及解答点拨", "写作业", "中考知识点", "中考真题及解答", "拓展提高及解答" }; 36 37 //遍历所有路径 38 foreach (string file in files) 39 { 40 //判断doc文件是否存在 41 if (File.Exists(file)) 42 { 43 Console.WriteLine(file); 44 //实现wordapp.document接口,打开word 45 msWord.Document doc = app.Documents.Open(file); 46 //获取word全文为字符串,没用上 47 //string temp = doc.Content.Text.Trim(); 48 //遍历所有段落,注意要从1开始,paragraph从1开始而不是从0!! 49 //for (int i = 1; i <= doc.Paragraphs.Count; i++) 50 //{ 51 // Console.WriteLine(doc.Paragraphs[i].Range.Text); 52 //} 53 ///* 54 //用foreach循环也可以 55 foreach (msWord.Paragraph para in doc.Paragraphs) 56 { 57 foreach (string lA in labelA) 58 { 59 //如果段落里包含标题1的文字 60 if (para.Range.Text.Contains(lA)) 61 { 62 //测试一下改颜色 63 //para.Range.Font.ColorIndex = msWord.WdColorIndex.wdBlue; 64 para.Range.set_Style("标题 1"); 65 Console.WriteLine("已处理:" + para.Range.Text); 66 } 67 else 68 { 69 //Console.WriteLine(para.Range.Text + "不包含" + lA); 70 } 71 } 72 foreach (string lB in labelB) 73 { 74 //如果段落里包含标题1的文字 75 if (para.Range.Text.Contains(lB)) 76 { 77 para.Range.set_Style("副标题"); 78 para.Range.ParagraphFormat.Alignment = msWord.WdParagraphAlignment.wdAlignParagraphLeft; 79 Console.WriteLine("已处理:" + para.Range.Text); 80 } 81 else 82 { 83 //Console.WriteLine(para.Range.Text + "不包含" + lB); 84 } 85 } 86 } 87 //*/ 88 doc.Save(); 89 doc.Close(true); 90 } 91 else 92 { 93 MessageBox.Show(file + " ,word文件不存在!"); 94 } 95 } 96 } 97 98 else 99 { 100 MessageBox.Show(txtBox.Text + "文件夹不存在!"); 101 } 102 app.Quit(); 103 MessageBox.Show("修改完毕!"); 104 } 105 106 107 private List<string> GetFile(string path) 108 { 109 //获取所有目录包括子目录的文件 110 //传入一个路径 111 List<string> list = new List<string>(); 112 //如果路径是文件夹,继续遍历,把新遍历出来的文件夹和文件存到list,用了递归 113 if (Directory.Exists(path)) 114 { 115 string[] dirs = Directory.GetDirectories(path); 116 if (dirs != null) 117 { 118 foreach (string dir in dirs) 119 { 120 list.AddRange(GetFile(dir)); 121 } 122 } 123 124 string[] files = Directory.GetFiles(path); 125 if (files != null) 126 { 127 list.AddRange(files); 128 } 129 } 130 //如果路径是文件,添加到list 131 else if (File.Exists(path)) 132 { 133 list.Add(path); 134 } 135 return list; 136 } 137 138 private void btnSelect_DragEnter(object sender, DragEventArgs e) 139 { 140 //拖进文件夹,获取信息 141 if (e.Data.GetDataPresent(DataFormats.FileDrop)) 142 e.Effect = DragDropEffects.All; 143 else 144 e.Effect = DragDropEffects.None; 145 } 146 147 private void btnSelect_DragDrop(object sender, DragEventArgs e) 148 { 149 //拖动松手后,获得路径 150 string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString(); //获得路径 151 txtBox.Text = path; 152 } 153 154 private void btnSelect_Click(object sender, EventArgs e) 155 { 156 //选择文件夹 157 //FolderBrowserDialog fbd = new FolderBrowserDialog(); 158 //fbd.SelectedPath = @"c:\"; 159 //if (fbd.ShowDialog() == DialogResult.OK) 160 //{ 161 // txtBox.Text = fbd.SelectedPath; 162 //} 163 //选择文件 164 OpenFileDialog ofd = new OpenFileDialog(); 165 if (ofd.ShowDialog() == DialogResult.OK) 166 { 167 //C:\Users\JJW\Desktop\新建文件夹\1_负数的引入.doc 168 txtBox.Text = ofd.FileName; 169 } 170 } 171 172 173 } 174 }
设计器:
结束。