使用Spire.Doc组件利用模板导出Word文档

     以前一直是用Office的组件实现Word文档导出,但是让客户在服务器安装Office,涉及到版权;而且Office安装,包括权限配置也是比较麻烦。

     现在流行使用第三方组件来实现对Office的操作,有NPOI,Spire等第三方组件。开始考虑的是NPOI,毕竟它在操作Excel方面还是很强大的;但是不知道是它本身没有,还是我没找到,无法实现利用Word模板的标签插入内容,纯靠代码去生成Word文档,排版是个大问题。最终找到了Spire.Doc组件,轻松实现!

  Spire的官网地址:https://www.e-iceblue.com/

1、项目中引用 Free Spire.Doc 组件,我是直接用NuGet下载包的.

安装完后,会引用其三个组件:

2、Word 模板制作

打开Word,点击 文件->选项->自定义功能区,勾选上“开发工具”:

主要使用文本域控件,插入作为标签:

如果有需要,可以添加“下划线”,或者“字符边框”等效果:

底下三个,前2个我用的是开发工具中的复选框(窗体控件)效果不是勾选的,是×号,效果不是客户想要的,所以使用了第二种解决方案“字符边框”,最后看导出的效果:

3、代码

可重用代码:

 1 using Spire.Doc;
 2 using Spire.Doc.Documents;
 3 using Spire.Doc.Fields;
 4 using System;
 5 using System.Collections.Generic;
 6 using System.ComponentModel;
 7 using System.IO;
 8 using System.Linq;
 9 using System.Text;
10 using System.Threading.Tasks;
11 
12 namespace We.Framework.Spire
13 {
14     /// <summary>
15     /// Sprie.Doc
16     /// Designed by XIAO
17     /// 2017-05-09
18     /// </summary>
19     public class WordHandler
20     {
21         public static bool ExportWordByFields<T>(T mod, string TempleteFilePath, string ExpFilePath)
22         {
23             if (mod == null)
24             {
25                 throw new Exception("模型为空!");
26             }
27 
28             System.Reflection.PropertyInfo[] properties = mod.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
29             if (properties.Length <= 0)
30             {
31                 throw new Exception("模型属性为空!");
32             }
33 
34             if (!File.Exists(TempleteFilePath))
35             {
36                 throw new Exception("指定路径的模板文件不存在!");
37             }
38 
39             try
40             {
41                 Document doc = new Document();
42                 doc.LoadFromFile(TempleteFilePath);
43 
44                 #region 替换文字
45                 //doc.Replace("海关", "海关口岸", true, true);
46                 //doc.Replace("报验", "报检", true, true);
47                 #endregion
48 
49                 //清除表单域阴影
50                 doc.Properties.FormFieldShading = false;
51 
52                 //遍历Word模板中的文本域(field.name为文本域名称)
53                 foreach (FormField field in doc.Sections[0].Body.FormFields)
54                 {
55                     foreach (System.Reflection.PropertyInfo prop in properties)
56                     {
57                         string name = prop.Name; //属性名称  
58                         object value = prop.GetValue(mod, null);  //属性值  
59                         string des = ((DescriptionAttribute)Attribute.GetCustomAttribute(prop, typeof(DescriptionAttribute))).Description;// 属性描述值
60 
61                         //注意:文本域名称 == 模型中属性的 Description 值 !!!!!!
62                         //也可以: 文本域名称 == 模型中属性的 Name 值 !!!!!!
63                         if (field.Name == des)
64                         {
65                             if (field.DocumentObjectType == DocumentObjectType.TextFormField)   //文本域
66                             {
67                                 if (prop.PropertyType.Name == "Boolean")
68                                 {
69                                     field.Text = "";   //插入勾选符号
70                                     break;
71                                 }
72                                 else
73                                 {
74                                     field.Text = value.ToString();   //向Word模板中插入值
75                                     break;
76                                 }
77                             }
78                             else if (field.DocumentObjectType == DocumentObjectType.CheckBox)   //复选框
79                             {
80                                 (field as CheckBoxFormField).Checked = (value as bool?).HasValue ? (value as bool?).Value : false;
81                             }
82                         }
83                     }
84                 }
85 
86                 doc.SaveToFile(ExpFilePath, FileFormat.Docx);
87                 doc.Close();
88 
89                 return true;
90             }
91             catch (Exception ex)
92             {
93                 string msg = ex.Message;
94 
95                 return false;
96             }
97         }
98     }
99 }

测试代码部分:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace WordHelper.TestModel
 9 {
10     /// <summary>
11     /// 抽样记录单
12     /// </summary>
13     public class SamplingRcd
14     {
15         [Description("记录单编号")]
16         public string No { get; set; }
17 
18         [Description("")]
19         public int Year { get; set; }
20 
21         [Description("")]
22         public int Month { get; set; }
23 
24         [Description("")]
25         public int Day { get; set; }
26 
27         [Description("药品名称")]
28         public string DrugName { get; set; }
29 
30         [Description("商品名")]
31         public string GoodsName { get; set; }
32 
33         [Description("注册证号")]
34         public string RegistNo { get; set; }
35 
36         [Description("检验通知号")]
37         public string NoticeNo { get; set; }
38 
39         [Description("外包装是否完整")]
40         public bool IsIntact { get; set; }
41 
42         [Description("是否封固")]
43         public bool IsFixed { get; set; }
44 
45         [Description("铅封")]
46         public bool IsPb { get; set; }
47     }
48 }
数据模型
 1         private void button1_Click(object sender, EventArgs e)
 2         {
 3             SamplingRcd mod = new SamplingRcd();
 4             mod.No = "No158922144";
 5             mod.Year = 2017;
 6             mod.Month = 5;
 7             mod.Day = 8;
 8             mod.DrugName = "门冬胰岛素50注射液";
 9             mod.GoodsName = "康胰素";
10             mod.RegistNo = "R12324552";
11             mod.NoticeNo = "N12324552";
12             mod.IsIntact = true;
13             mod.IsFixed = true;
14             mod.IsPb = true;
15 
16             System.IO.Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
17             string templeteFileName = @"..\..\WordTemplete\进口药品抽样记录单.docx";
18             string newFileName = string.Format("H:\\Exp_进口药品抽样记录单_{0}.docx", DateTime.Now.ToString("yyyyMMddHHmmss"));
19 
20             bool result = WordHandler.ExportWordByFields<SamplingRcd>(mod, templeteFileName, newFileName);
21             if (result)
22             {
23                 MessageBox.Show("成功");
24             }
25             else
26             {
27                 MessageBox.Show("失败");
28             }
29         }

基本功能已经实现,还有待改进,希望各位提出宝贵意见!

(PS:如果有朋友知道NPOI如何实现类似功能的,望告知下!先谢谢了!^_^)

 

posted on 2017-05-09 23:46  風云  阅读(2578)  评论(0编辑  收藏  举报

导航