aspose.word主要是通过把读取出来的数据放到datatable里,在datable里做相应的格式的调整,再导出到word文档里。mvc和webform最后导出的语句略有不同,在mvc的controller,用的是base.File,对应的是FileContentResult,在webform里用的是Response。写法分别为:
//在WebForm中,保存文档到流中,使用Response. BinaryWrite输出该文件
var docStream = new MemoryStream();
doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc));
Response.ContentType = "application/msword";
Response.AddHeader("content-disposition", "attachment; filename=Template.doc");
Response.BinaryWrite(docStream.ToArray());
Response.End();
//在MVC中采用,保存文档到流中,使用base.File输出该文件
var docStream = new MemoryStream();
doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc));
return base.File(docStream.ToArray(), "application/msword","Template.doc");
本人的项目是基于mvc的,所以采用后者。
首先项目需要对 aspose.word.dll进行添加引用, aspose.word.dll下载破解版的,版本过低会无法使用某些,如Aspose.Words.Saving等的相关属性,就没有SaveOptions.CreateSaveOptions方法,这个可以直接删掉,对基本的导出功能没有影响。之后将贴核心代码,代码都已经封装好,只需调用,传相关参数即可,后面解析代码的功能。
本人创建了一个WordHelper类,定义了公共属性,因为只是当前类调用,所以设为了私有,调用首先需实例化模板,模板就是之前已经写好的word模板,同时还写了相应的方法转化为可以接受中文值,比如性别是数据表里是bool类型,用false or true来代表男女,导出时则需转化为对应的中文值:
WordHelper
本人创建了一个WordHelper类,定义了公共属性,因为只是当前类调用,所以设为了私有,调用首先需实例化模板,模板就是之前已经写好的word模板,同时还写了相应的方法转化为可以接受中文值,比如性别是数据表里是bool类型,用false or true来代表男女,导出时则需转化为对应的中文值:
1 /// <summary> 2 /// 模板 3 /// </summary> 4 private string templateFile { get; set; } 5 private Document doc { get; set; } 6 private DocumentBuilder builder { get; set; } 7 #region 实例化模板 8 public WordHelper(string templateFile) 9 { 10 string templatePath = "Content/templates"; 11 if (Path.GetExtension(templateFile) != ".doc") //如果传的模板参数没有扩展名,则加上扩展名 12 templateFile = templateFile + ".doc"; 13 templateFile = WordFilePath.GetFilePath(templatePath, templateFile); //获取模板路径 14 doc = new Document(templateFile); //载入模板 15 builder = new DocumentBuilder(doc); 16 } 17 #endregion 18 #region 输出文件流 19 public MemoryStream DocStream 20 { 21 get 22 { 23 var docStream = new MemoryStream(); 24 doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc)); 25 return docStream; 26 } 27 } 28 #endregion 29 #region 转化为对应的中文值 30 /// <summary> 31 /// 转化为对应的中文值 32 /// </summary> 33 /// <param name="objName">值名称</param> 34 /// <param name="objValue">对应的值类型</param> 35 /// <returns></returns> 36 public static string SetChinaValue(object objName, object objValue) 37 { 38 object value = ""; 39 if (!string.IsNullOrEmpty(objValue.ToString())) 40 { 41 if (Common.lstDictionaryCodes.Contains(objName)) //字典值 42 { 43 value = Common.GetDicName(Convert.ToInt32(objValue)); 44 } 45 else if (Common.lstUserIDs.Contains(objName)) //人员档案 46 { 47 string[] strValue = objValue.ToString().Split(\',\'); 48 for (int i = 0; i < strValue.Length; i++) 49 { 50 value += Common.GetPersonName(strValue[i]) + ","; 51 } 52 value = !string.IsNullOrEmpty(value.ToString()) ? value.ToString().Substring(0, value.ToString().Length - 1) : ""; 53 } 54 else if (objValue.GetType() == typeof(string)) 55 { 56 value = objValue; 57 } 58 else if (objValue.GetType() == typeof(int) || objValue.GetType() == typeof(int?)) 59 { 60 value = objValue; 61 } 62 else if (objValue.GetType() == typeof(DateTime) || objValue.GetType() == typeof(DateTime?)) 63 { 64 value = Convert.ToDateTime(objValue).ToString("yyyy-MM-dd"); 65 } 66 else if (objValue.GetType() == typeof(decimal) || objValue.GetType() == typeof(decimal?)) 67 { 68 value = objValue; 69 } 70 else if (objValue.GetType() == typeof(bool) || objValue.GetType() == typeof(bool?)) 71 { 72 if (objName.Equals("Sex")) 73 { 74 if (objValue.Equals(false)) 75 value = "男"; 76 else 77 value = "女"; 78 } 79 else 80 { 81 if (objValue.Equals(true)) 82 value = "☑是 □否"; 83 else 84 value = "□是 ☑否"; 85 } 86 } 87 } 88 return value.ToString(); 89 } 90 #endregion 91 #region 保存文件名 92 /// <summary> 93 /// 保存文件名 94 /// </summary> 95 /// <param name="name">姓名</param> 96 /// <param name="value">编号</param> 97 /// <returns></returns> 98 public static string SaveDocName(string name, string value) 99 { 100 string oDoc = ""; 101 if (!string.IsNullOrEmpty(name)) 102 { 103 oDoc = name + "_" + value + ".doc"; 104 } 105 else 106 { 107 oDoc = DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".doc"; 108 } 109 return oDoc; 110 } 111 #endregion 112 #region 保存合并后的文档 113 public MemoryStream ExportDoc() 114 { 115 //保存合并后的文档 116 var docStream = new MemoryStream(); 117 doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc)); 118 return docStream; 119 } 120 #endregion 121 122 #region 通过DataTable导出基本信息 123 /// <summary> 124 /// 获取导出文件的基本信息 125 /// </summary> 126 /// <param name="bllType">bll类</param> 127 /// <param name="dicWhere">查询条件</param> 128 /// <returns></returns> 129 public void GetBasicInfo(Type bllType, Dictionary<string, string> dicWhere) 130 { 131 try 132 { 133 NameValueCollection nvc = new NameValueCollection(); 134 foreach (var item in dicWhere) 135 { 136 if (!string.IsNullOrEmpty(item.Key)) 137 { 138 nvc.Add(item.Key, item.Value); 139 } 140 } 141 Assembly asmBLL = Assembly.Load(typeof(BLL.BLLBase).Namespace); 142 BLL.IBLLBase ibllBase = (BLL.IBLLBase)asmBLL.CreateInstance(bllType.FullName); 143 DataSet ds = ibllBase.GetData(nvc); //数据源 144 DataTable dt = CreateNewTable(bllType, ds.Tables[0]); 145 146 doc.MailMerge.FieldMergingCallback = new HandleMergeFieldInsertDocument(); //图片处理 147 doc.MailMerge.Execute(dt); //合并模版,相当于页面的渲染 148 } 149 catch (Exception) 150 { 151 throw; 152 } 153 } 154 #endregion 155 156 #region 通过二维数组获取基本信息 157 /// <summary> 158 /// 通过二维数组获取基本信息 159 /// </summary> 160 /// <param name="bllType">bll类</param> 161 /// <param name="templateFile">导出模板</param> 162 /// <param name="dicWhere">查询条件</param> 163 /// <param name="lsField">导出的字段</param> 164 /// <returns></returns> 165 public void GetBasicInfo(Type bllType, Dictionary<string, string> dicWhere, List<string> lsField) 166 { 167 try 168 { 169 decimal count = 0; 170 NameValueCollection nvc = new NameValueCollection(); 171 foreach (var item in dicWhere) 172 { 173 if (!string.IsNullOrEmpty(item.Key)) 174 { 175 nvc.Add(item.Key, item.Value); 176 } 177 } 178 Assembly asmBLL = Assembly.Load(typeof(BLL.BLLBase).Namespace); 179 BLL.IBLLBase ibllBase = (BLL.IBLLBase)asmBLL.CreateInstance(bllType.FullName); 180 DataSet ds = ibllBase.GetData(nvc); //数据源 181 182 String[] arrNames = lsField.ToArray(); 183 Object[] objValues = new Object[arrNames.Length]; 184 185 for (int j = 0; j < arrNames.Length; j++) 186 { 187 if (ds.Tables[0].Rows.Count > 0) 188 objValues[j] = SetChinaValue(arrNames[j], ds.Tables[0].Rows[0][arrNames[j]]); 189 else 190 objValues[j] = ""; 191 } 192 doc.MailMerge.Execute(arrNames, objValues); //合并模版,相当于页面的渲染 193 } 194 catch (Exception) 195 { 196 throw; 197 } 198 } 199 #endregion 200 201 #region 通过域循环导出table列表 202 /// <summary> 203 /// 通过域循环导出table列表 204 /// </summary> 205 /// <param name="bllType">bll类</param> 206 /// <param name="dicWhere">查询条件</param> 207 /// <param name="bookmark">模板书签</param> 208 public void GetTableList(Type bllType, Dictionary<string, string> dicWhere, string bookmark) 209 { 210 NameValueCollection nvc = new NameValueCollection(); 211 foreach (var item in dicWhere) 212 { 213 if (!string.IsNullOrEmpty(item.Key)) 214 { 215 nvc.Add(item.Key, item.Value); 216 } 217 } 218 Assembly asmBLL = Assembly.Load(typeof(BLL.BLLBase).Namespace); 219 BLL.IBLLBase ibllBase = (BLL.IBLLBase)asmBLL.CreateInstance(bllType.FullName); 220 DataSet ds = ibllBase.GetData(nvc); //数据源 221 DataTable dt = CreateNewTable(bllType, ds.Tables[0], bookmark); 222 223 //合并模版,相当于页面的渲染 224 doc.MailMerge.ExecuteWithRegions(dt); 225 } 226 #endregion 227 #region 通过书签来循环导出数据列表 228 /// <summary> 229 /// 通过书签来循环导出数据列表 230 /// </summary> 231 /// <param name="bllType">bll类</param> 232 /// <param name="dicWhere">查询条件</param> 233 /// <param name="dicOrderby">排序条件</param> 234 /// <param name="bookmark">模板循环列表书签</param> 235 public void GetListByMark(Type bllType, Dictionary<string, string> dicWhere, Dictionary<string, string> dicOrderby, string bookmark) 236 { 237 NameValueCollection nvc = new NameValueCollection(); 238 foreach (var item in dicWhere) 239 { 240 if (!string.IsNullOrEmpty(item.Key)) 241 { 242 nvc.Add(item.Key, item.Value); 243 } 244 } 245 NameValueCollection orderby = new NameValueCollection(); 246 foreach (var item in dicOrderby) //查询条件 247 { 248 if (!string.IsNullOrEmpty(item.Key)) 249 { 250 orderby.Add(item.Key, item.Value); 251 } 252 } 253 254 Assembly asmBLL = Assembly.Load(typeof(BLL.BLLBase).Namespace); 255 BLL.IBLLBase ibllBase = (BLL.IBLLBase)asmBLL.CreateInstance(bllType.FullName); 256 DataTable dt = ibllBase.GetData(nvc, orderby).Tables[0]; //数据源 257 258 int count = 0; 259 //记录要显示多少列 260 for (var i = 0; i < dt.Columns.Count; i++) 261 { 262 string strMark = dt.Columns[i].ColumnName.Trim(); 263 if (doc.Range.Bookmarks[strMark] != null) 264 { 265 Bookmark mark = doc.Range.Bookmarks[strMark]; 266 mark.Text = ""; 267 count++; 268 } 269 } 270 List<string> listcolumn = new List<string>(count); 271 for (var i = 0; i < count; i++) 272 { 273 builder.MoveToCell(0, 0, i, 0); //移动单元格 274 if (builder.CurrentNode.NodeType == NodeType.BookmarkStart) 275 { 276 listcolumn.Add((builder.CurrentNode as BookmarkStart).Name); 277 } 278 } 279 double width = builder.CellFormat.Width;//获取单元格宽度 280 if (doc.Range.Bookmarks[bookmark] != null) 281 { 282 builder.MoveToBookmark(bookmark); //开始添加值 283 for (var m = 0; m < dt.Rows.Count; m++) 284 { 285 for (var i = 0; i < listcolumn.Count; i++) 286 { 287 builder.InsertCell(); // 添加一个单元格 288 builder.CellFormat.Borders.LineStyle = LineStyle.Single; 289 builder.CellFormat.Borders.Color = System.Drawing.Color.Black; 290 builder.CellFormat.Width = width; 291 builder.CellFormat.VerticalMerge = Aspose.Words.Tables.CellMerge.None; 292 builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;//垂直居中对齐 293 builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;//水平居中对齐 294 builder.Write(dt.Rows[m][listcolumn[i]].ToString()); 295 } 296 builder.EndRow(); 297 } 298 doc.Range.Bookmarks[bookmark].Text = ""; 299 } 300 } 301 #endregion 302 303 #region 创建DataTable,存放处理后的值进新的DataTable里 304 /// <summary> 305 /// 创建datatable 306 /// </summary> 307 /// <param name="dt">数据源</param> 308 /// <param name="bookmark">模板列表书签</param> 309 /// <returns></returns> 310 private DataTable CreateNewTable(Type t, DataTable dt, string bookmark = null) 311 { 312 DataTable TableList = new DataTable(); 313 if (!string.IsNullOrEmpty(bookmark)) 314 { 315 TableList.TableName = bookmark; 316 } 317 string strMark = ""; 318 List<string> lsMark = new List<string>(); 319 for (var i = 0; i < dt.Columns.Count; i++) 320 { 321 strMark = dt.Columns[i].ColumnName.Trim(); 322 TableList.Columns.Add(strMark); 323 //if (doc.Range.Bookmarks[strMark] != null) //按书签添加到新表 324 //{ 325 // Bookmark mark = doc.Range.Bookmarks[strMark]; 326 // mark.Remove(); 327 // TableList.Columns.Add(strMark); 328 // lsMark.Add(strMark); 329 //} 330 } 331 332 if (dt.Rows.Count > 0) 333 { 334 for (int i = 0; i < dt.Rows.Count; i++) 335 { 336 DataRow dr = TableList.NewRow(); 337 for (int j = 0; j < dt.Columns.Count; j++) 338 { 339 dr[j] = SetChinaValue(dt.Columns[j].ColumnName, dt.Rows[i][j]); 340 } 341 TableList.Rows.Add(dr); 342 } 343 } 344 else //没有值时,直接赋值为"",去掉文档里的域值 345 { 346 DataRow dr = TableList.NewRow(); 347 for (int j = 0; j < dt.Columns.Count; j++) 348 { 349 if (t.Name == "PrejobTraining") //岗前培训为空时 350 { 351 dr[j] = "□是 □否"; 352 } 353 else 354 { 355 dr[j] = ""; 356 } 357 } 358 TableList.Rows.Add(dr); 359 } 360 return TableList; 361 } 362 #endregion 363 } 364 #endregion
其它相关辅助类:
HandleMergeFieldInsertDocument 类
1 #region 导出Word处理图片 2 /// <summary> 3 /// 导出Word处理图片 4 /// </summary> 5 public class HandleMergeFieldInsertDocument : IFieldMergingCallback 6 { 7 //文本处理在这里,如果写在这一块,则不起作用 8 void IFieldMergingCallback.FieldMerging(FieldMergingArgs e) 9 { 10 } 11 //图片处理在这里 12 void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args) 13 { 14 if (args.DocumentFieldName.Equals("Photo")) 15 { 16 // 使用DocumentBuilder处理图片的大小 17 DocumentBuilder builder = new DocumentBuilder(args.Document); 18 builder.MoveToMergeField(args.FieldName); 19 if (!string.IsNullOrEmpty((string)args.FieldValue)) 20 { 21 string argsPath = HttpContext.Current.Server.MapPath(args.FieldValue.ToString()); 22 if (System.IO.File.Exists(argsPath)) //找到文件才添加 23 { 24 Shape shape = builder.InsertImage(argsPath); 25 // 设置x,y坐标和高宽. 26 shape.Left = 0; 27 shape.Top = 0; 28 shape.Width = 80; 29 shape.Height = 120; 30 } 31 } 32 } 33 } 34 } 35 #endregion