最近在做兼职的时候,客户需要做一个导出导入word的功能。导出word很常见,但是导入word却很少,经过两天的摸索总算折腾出来了。
用的是第三方框架Aspose,不知道为什么在Nuget里下载的时候一直没反应,就在网上找了个dll,点击下载
1. 导出Word:
如果是简单的数据绑定可以用 域 or书签 的方式
微软的word添加域: 点击“插入→文档部件→域”找到MergeField,添加即可.
Wps的word:如图
添加完成后用代码绑定相对应数据
域绑定如下:
string tempPath = Server.MapPath("~/Docs/Temp/Template.doc"); string outputPath = Server.MapPath("~/Docs/Output/Template.doc"); //载入模板 var doc = new Document(tempPath); //提供数据源 String[] fieldNames = new String[] {"UserName", "Gender", "BirthDay", "Address"}; Object[] fieldValues = new Object[] {"张三", "男", "1988-09-02", "陕西咸阳"}; //合并模版,相当于页面的渲染 doc.MailMerge.Execute(fieldNames, fieldValues); //保存合并后的文档 doc.Save(outputPath);//在MVC中采用,保存文档到流中,使用base.File输出该文件 var docStream = new MemoryStream(); doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc)); return base.File(docStream.ToArray(), "application/msword","Template.doc");
书签绑定如下:
var tempPath = Server.MapPath("~/Temp/Doc/Template/Template.doc"); //载入模板 var doc = new Document(tempPath); #region 书签绑定值,用于单个字段 //书签绑定值,用于单个字段 Dictionary<string, string> dictBookMark = new Dictionary<string, string>(); dictBookMark.Add("MedicinalName", "品名-山药"); dictBookMark.Add("MaterieBatchNumber", "物料代码- 000001"); dictBookMark.Add("ProdcutBatchNumber", "产品批号- 20152123456"); dictBookMark.Add("PlanDate", "执行日期- 2017年5月9号"); foreach (string name in dictBookMark.Keys) { var bookmark = doc.Range.Bookmarks[name]; if (bookmark != null) { bookmark.Text = dictBookMark[name]; } } //在MVC中采用,保存文档到流中,使用base.File输出该文件 var docStream = new MemoryStream(); doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc)); return base.File(docStream.ToArray(), "application/msword", "Template.doc");
如果是列表的绑定则如下:
设计如下模板,在循环的列表下添加列表的起始和结束域 : <<TableStart:RawMaterialList>> 和 <<TableEnd:RawMaterialList>> 以及列表中的各项域.
代码操作如下
var rawMaterialList = new List<RawMaterialModel> { new RawMaterialModel { RawMaterialIndex = 1, RawMaterialName="测试物料1", RawMaterialCode="test1", UnitName = "KG", ShouldUseCount = 123, DestoryCost = "5.3%", NeedUseCount = 150, Remark = "test1111" }, new RawMaterialModel { RawMaterialIndex = 2, RawMaterialName="测试物料2", RawMaterialCode="test2", UnitName = "KG", ShouldUseCount = 444, DestoryCost ="-", NeedUseCount = 555, Remark = "test222" }, new RawMaterialModel { RawMaterialIndex = 3, RawMaterialName="测试物料3", RawMaterialCode="test3", UnitName = "KG", ShouldUseCount = 654, DestoryCost = "-", NeedUseCount = 800, Remark = "test333" }, }; var packageMaterialList = new List<RawMaterialModel> { new RawMaterialModel { RawMaterialIndex = 1, RawMaterialName="包材1", RawMaterialCode="test1", UnitName = "KG", ShouldUseCount = 123, DestoryCost = "5.3", NeedUseCount = 150, Remark = "test1111" }, new RawMaterialModel { RawMaterialIndex = 2, RawMaterialName="包材2", RawMaterialCode="test2", UnitName = "KG", ShouldUseCount = 444, DestoryCost = "9", NeedUseCount = 555, Remark = "test222" } }; var dt = CommonHelper.ListToTable(rawMaterialList); dt.TableName = "RawMaterialList"; var dt2 = CommonHelper.ListToTable(packageMaterialList); dt2.TableName = "PackageMaterialList"; var ds = new DataSet(); ds.Tables.Add(dt); ds.Tables.Add(dt2); doc.MailMerge.ExecuteWithRegions(ds);
2. 导入Word:
导入一个模板如下的word,导入word相对比较麻烦,因为我这里主要是一个表格,所以找到第一个table对象就可以,这里表格格式是固定的,所以部分代码采用硬编码的形式。
代码操作如下:
Document doc = new Document(filePathAndName); Section section = (Section)doc.ChildNodes[0]; Body body = section.Body; var importDocModel = new ImportDocModel(); Aspose.Words.Tables.Table table = null; //找到第一个tabel foreach (var node in body.ChildNodes) { if (node is Aspose.Words.Tables.Table) { table = (Aspose.Words.Tables.Table)node; break; } } //原辅料起始索引 var OldRawMaterialStartIndex = 5; //原辅料结束索引 var OldRawMaterialEndIndex = 5; //包材列表起始索引 var baoCaiStartIndex = table.Rows.Count - 1 - 7; //包材列表结束索引 var baoCaiEndIndex = table.Rows.Count - 1 - 7; //计算原辅料和包材的起始、结束索引 for (var i = 0; i < table.Rows.Count; i++) { if (table.Rows[i].Cells[0].Paragraphs[0] != null && table.Rows[i].Cells[0].Paragraphs[0].Runs[0].Text == "包材") { OldRawMaterialEndIndex = i - 1; baoCaiStartIndex = i + 2; break; } } //循环表的每一行 for (var i = 0; i < table.Rows.Count; i++) { var row = table.Rows[i]; //1-3行数据处理 if (i <= 2) { #region 循环每行的每一列, 截取“:”:后面的内容 for (var j = 0; j < row.Cells.Count; j++) { var cell = row.Cells[j]; if (cell.Paragraphs[0] != null && cell.Paragraphs[0].Runs.Count > 0) { var cellText = string.Empty; for (int x = 0; x < cell.Paragraphs[0].Runs.Count; x++) { cellText += cell.Paragraphs[0].Runs[x].Text; } if (!string.IsNullOrEmpty(cellText)) { var index = cellText.IndexOf(":"); var useText = cellText; if (index >= 0) { useText = cellText.Substring(index + 1, cellText.Length - index - 1); } if (i == 0 && j == 0) { importDocModel.Headr.MedicinalName = useText; } else if (i == 0 && j == 1) { importDocModel.Headr.Size = useText; } else if (i == 1 && j == 0) { importDocModel.Headr.MaterialCode = useText; } else if (i == 1 && j == 1) { importDocModel.Headr.ShoulUseCount = useText; } else if (i == 2 && j == 0) { importDocModel.Headr.ProductNumber = useText; } else if (i == 2 && j == 1) { importDocModel.Headr.DoDate = useText; } } } } #endregion } //原辅料列表处理 else if (i >= OldRawMaterialStartIndex && i <= OldRawMaterialEndIndex) { if (row.Cells[0].Paragraphs[0] != null && row.Cells[0].Paragraphs[0].Runs.Count > 0) { var model1 = GetRawMaterialByRow(row); importDocModel.RawMaterialModelList1.Add(model1); } } //包材列表处理 else if (i >= baoCaiStartIndex && i <= baoCaiEndIndex) { if (row.Cells[0].Paragraphs[0] != null && row.Cells[0].Paragraphs[0].Runs.Count > 0) { var model2 = GetRawMaterialByRow(row); importDocModel.RawMaterialModelList2.Add(model2); } } }