网上有很多的关于WORD模板操作的文章,看了后,总是被其中一些关键点给打断了,在经过多次测试后,总算是成功生成了自己的WORD,今天详细分享下,希望能帮到需要的小白们。
首先来看下导出的效果
图片标注的区域,都是通过WORD模板生成的,特别是循环生成区域,估计都是大家想要的。下面就一步步来吧。
第一:引入Aspose.Words.dll ,网上都可以下载,这里不细说了。
第二:WORD模板操作核心方法:
[code]using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Web;using System.IO;//这里的前提,你需要引用Aspose.Words.dll文件using Aspose.Words;using System.Data;///VanClean.Office 是我的命名空间,你可以自己调整namespace VanClean.Office{/// <summary>/// 通过WORD模板导出文档/// </summary>public class WordModelEvent{/// <summary>/// WORD模板操作/// </summary>/// <param name=\"modelDoc\">模板路径</param>/// <param name=\"exptDoc\">导出文件名</param>/// <param name=\"fieldNames\"></param>/// <param name=\"fieldValues\"></param>/// <param name=\"dt\"></param>/// <returns></returns>public static string ExpertWordToModel(string modelDoc,string exptDoc,String[] fieldNames, Object[] fieldValues,DataTable dt){try{//WORD模板存放位置string tempPath = HttpContext.Current.Server.MapPath(\"~/templates/\" + modelDoc + \".docx\");//导出的WORD存放的位置const string saveFold = \"uploads/word/\";string outputPath = HttpContext.Current.Server.MapPath(\"~/\" + saveFold);if (!Directory.Exists(outputPath))Directory.CreateDirectory(outputPath);//生成的WORD文件名string fileName = exptDoc + \"[\" + DateTime.Now.ToString(\"yyyyMMddHHmmssfff\") + \"].docx\";outputPath += fileName;//载入模板Document doc = new Document(tempPath);doc.MailMerge.Execute(fieldNames, fieldValues);//将我们获得的DataTable类型的数据:EduDataTable放入doc方法中做处理doc.MailMerge.ExecuteWithRegions(dt);//获取下载地址String StrVisitURL = saveFold + fileName;//合并模版,相当于页面的渲染doc.MailMerge.Execute(new[] { \"PageCount\" }, new object[] { doc.PageCount });//保存合并后的文档doc.Save(outputPath);return StrVisitURL;}catch (Exception er){return er.Message;}}}}
第三:通过WORD模板生成新文件
return PublicCode.RetTrueMsg(StrVisitURL);我返回的是JSON格式数据,你可直接返回 return StrVisitURL;即下载地址。
[code]using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data;using System.Data.SqlClient;/// <summary>/// 根据WORD模板生成住户基础信息/// </summary>/// <param name=\"houseid\"></param>/// <returns></returns>public static string GetWordEvent(string houseid){try{String[] fieldNames = new String[]{\"Fanghao\",\"RegDate\",\"UserName\",\"Gender\",\"Minzu\",\"Zhengzhimm\",\"IdCard\",\"Qianchudi\",\"Tel\",\"Shuxing\",\"BankZh\",\"Gongyigang\"};PersonBase pb = SelectOne(\"\", houseid);//通过houseid返回PersonBase对象,里面包括了fieldNames需要的字段信息,PersonBase自己定义下吧,SeleectOne()方法自己写一个。if(pb == null){return PublicCode.RetFalseMsg(\"没有查询到户主信息,请检查住户基础登记信息!\");}Object[] fieldValues = new object[fieldNames.Length];fieldValues[0] = FormatFanghao(pb.Fanghao);fieldValues[1] = DateTime.Now.ToString(\"yyyy年MM月dd日\");fieldValues[2] = pb.Name;fieldValues[3] = pb.Xingbie;fieldValues[4] = pb.Minzu;fieldValues[5] = pb.Zhengzhimm;fieldValues[6] = pb.IdCard;fieldValues[7] = pb.qc_Xiangzhen + pb.qc_Xingzhengcun + pb.qc_Cunminxiaozu;fieldValues[8] = pb.Tel;fieldValues[9] = \"\";//属性fieldValues[10] = \"\";//银行账号fieldValues[11] = \"\";//公益岗string sql = \"select Name,Huzhuguanxi,Xingbie,IdCard Card,\'\' Qita,\'\' UserGongyi\";sql += \" from TableName where HouseID=\'\" + houseid + \"\' order by id asc\";DataTable dt = getDataTable(sql);//这里的UserList很关键,要与WORD模板的域设置对应,不是随便写的,后面还会用到dt.TableName = \"UserList\";//VanClean.Office这里命名空间注意修改string StrVisitURL = VanClean.Office.WordModelEvent.ExpertWordToModel(\"model\", pb.Fanghao + pb.Name, fieldNames, fieldValues, dt);return PublicCode.RetTrueMsg(StrVisitURL);}catch(Exception er){return er.Message;}}/// <summary>/// 格式化房号/// </summary>/// <param name=\"fanghao\"></param>/// <returns></returns>private static string FormatFanghao(string fanghao){try{string[] tmp = fanghao.Split(\'-\');string str = Int32.Parse(tmp[0]).ToString() + \"栋\" + Int32.Parse(tmp[1]).ToString() + \"单元\" + Int32.Parse(tmp[2]).ToString() + \"室\";return str;}catch(Exception er){return fanghao;}}/// 通过SQL获得 DataTable/// ConnectionString 你的数据链接字符串private DataTable getDataTable(string sql){SqlConnection cn = new SqlConnection(ConnectionString);SqlDataAdapter da = new SqlDataAdapter(sql, cn);DataTable ds = new DataTable();da.Fill(ds);return ds;}
第四:在运行前,你还需要建立WORD模板。
创建方法:
打开WORD-插入-文档部件-域
如图输入域名,记得与 fieldNames 中字字段对应。
[code]String[] fieldNames = new String[]{\"Fanghao\",\"RegDate\",\"UserName\",\"Gender\",\"Minzu\",\"Zhengzhimm\",\"IdCard\",\"Qianchudi\",\"Tel\",\"Shuxing\",\"BankZh\",\"Gongyigang\"};
循环生成区域插入:输入开始标识:TableStart:UserList,这里的 UserList 要与 dt.TableName = \”UserList\”对应,这样DataTable中的数据才会对应填充到表格中。
再输入其他字段
最后记得同样输入一个结束标识:TableEnd:UserList,把下方多余的行删除,在WORD模板生成时,会自动向下填充的。
第五:完成以上工作,就可以调用了,调用就很简单了。
我使用的WEB服务,然后使用AJAX调用,你也可以直接使用方法就可以调用了。
[code]HTML代码<%@ Page Language=\"C#\" AutoEventWireup=\"true\" CodeFile=\"test.aspx.cs\" Inherits=\"comm_test\" %><!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\"><head runat=\"server\"><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title></title></head><body><form id=\"form1\" runat=\"server\"><div><asp:Button ID=\"Button1\" runat=\"server\" Text=\"Button\" OnClick=\"Button1_Click\" /></div></form></body></html>调用代码protected void Button1_Click(object sender, EventArgs e){string houseid = \"testid\";GetWordEvent(houseid);}