最近在做考试系统,说是要将试卷导出到word文档中,好方便教师打印,其实考试系统这个已经是别人做烂的系统了,我的一个(资深)同事,也说过一个调侃的话,考试系统好做,但是要想做好就不容易。如果你真要做到将一张试卷,(当然是一定的word格式,包含图片,表格等),导入到数据库中,并且能够成功的将其导出到word中来,(样式基本上不能有太大的出入),就说明你做成功了。这个工作就是我现在要攻克的难关,现在只是说一个导出word文档的问题。
思路:我原来是想通过段落 (paragraph)的方式来进行操作,但是,总是插入的图片,不能很好的定位,后来找到问题了,应该是光标的问题。可是我总是不能很好的掌握到光标的问题,可能是我对其了解的还不够吧,也看了一些对光标移动的一些文章http://hi.baidu.com/tyszgkxy/blog/item/d22360f39edaec5c352acce9.html类似的文章,网络上有很多,我也用
object count = 1 ;
object extend = Microsoft.Office.Interop.Word.WdMovementType.wdExtend;
WordApp.Selection.MoveDown ( ref unit, ref count, ref extend );
上面的语句应该就是讲光标移动到段落的末尾,然后再进行换行操作应该就可以了。但是总是不成功,也没有出错。我百思不得其解!
后来我就想直接在文档操作的开始部分就设置光标,然后,只要有操作的时候,就讲光标移动到指定的位置,这样的话,就不会有光标错位的问题了,
这样问题就解决了,但是,接下来的问题,就是牵扯到换行的问题了,类似于光标的移动,我也不能成功的进行换行操作。郁闷!
后来,就用了,插入段落来进行代替。
WordApp.Selection.TypeParagraph();//这样也能完成回车换行的作用。
这样基本上问题都解决了,接下来,就将整个操作完整的写下来。
2 . /// 将试卷导出到word文档中
3 . /// </summary>
4 . /// <param name="table"> 试卷中的大题,小题等内容
5 . /// table中包含"ItemIndex", "quContent", "quMark", "quType", "para_space"几列
6 . /// ItemIndex 相当于是 小题或者大题的题号后面有如 一、1、等
7 . /// quContent 相当如是 题干部分(不包含选项部分)选项部分为下一行的内容
8 . /// quMark 为试题的分数部分
9 . /// quType 为试题的类型,如大题:title; 选项 optiion ;题干:content
10 . /// para_space 为应该为试题留出多大的空间去让答题人答题。
11 . /// </param>
12 . /// <param name="paperName"> 试卷的名称,如:2009-2010上学年期末考试试卷 </param>
13 . /// <param name="totalScore"> 试卷总分 </param>
14 . /// <param name="time_length"> 时间:60分钟 </param>
15 . /// <param name="file"> 要保存的文件的相对路径 </param>
16 . /// <param name="fileTemplate"> 文档模板的相对路径 </param>
17 . private void writeDocument(DataTable table, string paperName, string totalScore, string time_length, string file, string fileTemplate)
18 . {
19 . Microsoft.Office.Interop.Word.Application WordApp = new Microsoft.Office.Interop.Word.ApplicationClass();
20 . Document WordDoc;
21 . string strContent = "" ;
22 . object strFileName = System.Web.HttpContext.Current.Server.MapPath(file);
23 . object fileName = System.Web.HttpContext.Current.Server.MapPath(fileTemplate);
24 . Object oMissing = System.Reflection.Missing.Value;
25 . WordDoc = WordApp.Documents.Add( ref fileName, ref oMissing, ref oMissing, ref oMissing);
26 . WordDoc.Activate();
27 . /// 试卷模板中包含三个标签,"header"、"totalScore"、"content"
28 . /// “header” 用来存储试卷的题目 如:2009-2010上学年期末考试试卷
29 . /// "totalScore"试卷总分+考试时间 如:满分:100分 时间:60分钟
30 . /// "content" 试卷的内容部分
31 . foreach (Bookmark bm in WordDoc.Bookmarks)
32 . {
33 . if (bm.Name == " header " )
34 . {
35 . bm.Select();
36 . bm.Range.Text = paperName;
37 . }
38 . if (bm.Name == " totalScore " )
39 . {
40 . bm.Select();
41 . bm.Range.Text = " 总分: " + totalScore + " 分\t时间: " + time_length + " 分钟 " ;
42 . }
43 . if (bm.Name == " content " )
44 . {
45 . // 讲光标定位到书签内。
46 . bm.Select();
47 .
48 . // 得到光标的位置。
49 . Selection currentSelection = WordApp.Selection;
50 . #region test
51 . foreach (DataRow dr in table.Rows)
52 . {
53 . strContent = dr[ " itemIndex " ].ToString() + dr[ " quContent " ].ToString() + dr[ " quMark " ].ToString();
54 . currentSelection.Range.Font.Name = " 新宋体 " ;
55 . if (dr[ " quType " ].ToString() == " title " )
56 . {
57 . currentSelection.Range.Font.Bold = 1 ;
58 . currentSelection.Range.Font.Size = 16 ;
59 . }
60 . else if (dr[ " quType " ].ToString() == " option " )
61 . {
62 . currentSelection.Range.Font.Bold = 0 ;
63 . currentSelection.Range.Font.Size = 14 ;
64 .
65 . }
66 . else
67 . {
68 . currentSelection.Range.Font.Bold = 0 ;
69 . currentSelection.Range.Font.Size = 14 ;
70 . }
71 . for ( int i = 0 ; i < int .Parse(dr[ " para_space " ].ToString()); i ++ )
72 . {
73 . currentSelection.TypeParagraph();
74 . }
75 . if (Regex.IsMatch(strContent, @" <img[^>]*> " ))
76 . {
77 . string [] matches = Regex.Split(strContent, @" (<img[^>]*>) " );
78 . foreach ( string ma in matches)
79 . {
80 . if (Regex.IsMatch(ma, @" <img[^>]*> " ))
81 . {
82 .
83 . Match match = Regex.Match(ma, @" src=.* " );
84 . string ss = match.Value;
85 . // ss=ma.Replace("\\","");
86 . ss = ss.Replace( " src=\ "" , "" );
87 . ss = ss.Replace( " \ " /> " , "" );//这时的ss就是img的相对路径了
88 . string imgPath = System.Web.HttpContext.Current
89 . .Server.MapPath(ss.Contains( " .. " ) ? ( " ~ " + ss.Substring( 2 )) : ( " ~ " + ss)); // 图片所在路径
90 . object LinkToFile = false ;
91 . object SaveWithDocument = true ;
92 . object Anchor = WordDoc.Application.Selection.Range;
93 . InlineShape li = currentSelection.InlineShapes.AddPicture(imgPath, ref LinkToFile, ref SaveWithDocument, ref Anchor);
94 . Shape s = li.ConvertToShape();
95 . // WordDoc.Application.ActiveDocument.InlineShapes[1].Width = 100f; // 图片宽度
96 . // 将图片设置为四周环绕型
97 . s.WrapFormat.Type = WdWrapType.wdWrapSquare;
98 . }
99 . else
100 . {
101 . currentSelection.TypeText(ma);
102 . }
103 . }
104 . }
105 . else if (Regex.IsMatch(strContent, @" <table.*</table> " ))
106 . {
107 . string [] matches = Regex.Split(strContent, @" (<table.*</table>) " );
108 . foreach ( string ma in matches)
109 . {
110 . if (Regex.IsMatch(ma, @" <table.*</table> " ))
111 . {
112 . MatchCollection matchTR = Regex.Matches(ma, @" <tr[^>]*>[\s\S]*?<\/tr> " );
113 . int rowCount = matchTR.Count;
114 . MatchCollection matchTd = Regex.Matches(matchTR[ 0 ].Value, @" <td.*?>.*?</td> " );
115 . int ColumnCount = matchTd.Count;
116 . Table newTable = WordDoc.Tables.Add(
117 . currentSelection.Range, rowCount, ColumnCount, ref oMissing, ref oMissing);
118 . int i = 1 ;
119 . for (; i <= matchTR.Count; i ++ )
120 . {
121 . matchTd = Regex.Matches(matchTR[i - 1 ].Value, @" <td.*?>.*?</td> " );
122 . for ( int j = 1 ; j <= matchTd.Count; j ++ )
123 . {
124 . /// 讲语句中的 <td> 和 </td> 删除掉
125 . string tdString = matchTd[j - 1 ].Value;
126 . tdString = Regex.Replace(tdString, @" <td.*?> " , "" );
127 . tdString = Regex.Replace(tdString, @" </td> " , "" );
128 . newTable.Cell(i, j).Range.Text = tdString;
129 . currentSelection.Tables[ 1 ].Cell(i, j).Select();
130 . }
131 . }
132 . currentSelection.TypeParagraph();
133 . }
134 . else
135 . {
136 . currentSelection.TypeText(ma);
137 . }
138 . }
139 . }
140 . else
141 . {
142 . currentSelection.TypeText(strContent);
143 . }
144 . currentSelection.TypeParagraph();
145 . }
146 . #endregion
147 . }
148 . }
149 . // 将WordDoc文档对象的内容保存为DOC文档
150 . WordDoc.SaveAs( ref strFileName, ref oMissing, ref oMissing, ref oMissing,
151 . ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
152 . ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
153 . ref oMissing, ref oMissing);
154 . // 关闭WordDoc文档对象
155 . WordDoc.Close( ref oMissing, ref oMissing, ref oMissing);
156 . // 关闭WordApp组件对象
157 . WordApp.Quit( ref oMissing, ref oMissing, ref oMissing);
158 . WordOperate.KillWordProcess();
159 . }
其他的就不在此说明
至此节本上讲功能给完成了,能将图片导入到word中了,简单的表格也可以,但是表格的定位要在斟酌一下,要记得移动光标。
图片的位置,仍然不能进入人意,但是大体上已经完成了。
效果为下图