NPOI导出Word文档(读取数据渲染原有模板)

因为使用到了NPOI导出,所以在网上找了个方法,收藏在这里,以作记录(侵权联系删除)

原博客园地址:https://www.cnblogs.com/jomzhang/p/9555397.html

工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/// <summary>
   /// 作者:jomz
   /// </summary>
   public class NpoiHeplper
   {
       /// <summary>
       /// 输出模板docx文档(使用字典)
       /// </summary>
       /// <param name="tempFilePath">docx文件路径</param>
       /// <param name="outPath">输出文件路径</param>
       /// <param name="data">字典数据源</param>
       public static void Export(string tempFilePath,string outPath,Dictionary<string,string> data)
       {
           using (FileStream stream = File.OpenRead(tempFilePath))
           {
               XWPFDocument doc = new XWPFDocument(stream);
               //遍历段落                 
               foreach (var para in doc.Paragraphs)
               {
                   ReplaceKey(para, data);
               }
               //遍历表格     
               foreach (var table in doc.Tables)
               {
                   foreach (var row in table.Rows)
                   {
                       foreach (var cell in row.GetTableCells())
                       {
                           foreach (var para in cell.Paragraphs)
                           {
                               ReplaceKey(para, data);
                           }
                       }
                   }
               }
               //写文件
               FileStream outFile = new FileStream(outPath, FileMode.Create);
               doc.Write(outFile);
               outFile.Close();
           }
       }
       private static void ReplaceKey(XWPFParagraph para, Dictionary<string,string> data)
       {
           string text = "";
           foreach (var run in para.Runs)
           {
               text = run.ToString();
               foreach (var key in data.Keys)
               {
                   //$$模板中数据占位符为$KEY$
                   if (text.Contains($"${key}$"))
                   {
                       text = text.Replace($"${key}$", data[key]);
                   }
               }
               run.SetText(text, 0);
           }
       }
 
 
       /// <summary>
       /// 输出模板docx文档(使用反射)
       /// </summary>
       /// <param name="tempFilePath">docx文件路径</param>
       /// <param name="outPath">输出文件路径</param>
       /// <param name="data">对象数据源</param>
       public static void ExportObjet(string tempFilePath, string outPath, object data)
       {
           using (FileStream stream = File.OpenRead(tempFilePath))
           {
               XWPFDocument doc = new XWPFDocument(stream);
               //遍历段落                 
               foreach (var para in doc.Paragraphs)
               {
                   ReplaceKeyObjet(para, data);
               }
               //遍历表格     
               foreach (var table in doc.Tables)
               {
                   foreach (var row in table.Rows)
                   {
                       foreach (var cell in row.GetTableCells())
                       {
                           foreach (var para in cell.Paragraphs)
                           {
                               ReplaceKeyObjet(para, data);
                           }
                       }
                   }
               }
               //写文件
               FileStream outFile = new FileStream(outPath, FileMode.Create);
               doc.Write(outFile);
               outFile.Close();
           }
       }
       private static void ReplaceKeyObjet(XWPFParagraph para, object model)
       {
           string text = "";
           Type t = model.GetType();
           PropertyInfo[] pi = t.GetProperties();
           foreach (var run in para.Runs)
           {
               text = run.ToString();
               foreach (PropertyInfo p in pi)
               {
                   //$$模板中数据占位符为$KEY$
                   string key = $"${p.Name}$";
                   if (text.Contains(key))
                   {
                       try
                       {
                           text = text.Replace(key, p.GetValue(model, null).ToString());
                       }
                       catch (Exception ex)
                       {
                           //可能有空指针异常
                           text = text.Replace(key, "");
                       }
                   }
               }
               run.SetText(text, 0);
           }
       }
 
   }

  

使用介绍,本工具类可根据字典数据源或者对象数据源导出标准的docx格式word,不考虑word排版问题,只考虑数据填充,排版由word模板使用office自行制作。

ExportObjet方法传入word模板对象地址tempFilePath,导出到地址outPath,以及类数据源data,通过反射获取字段匹配word模板中对应的$key$,我在项目中使用的是{{替换名称}}名称去替换其值达到最后效果,但是因为文字样式等问题有的会无法替换,这个时候多调整几次即可。同理
Export则使用字典作为数据源。

实际使用案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public Dictionary<string, object> Export(Guid Id)
 {
     //获取路径
     var result = _dAL.Get(Id);
     var mubanFile = "纠正和预防措施报告.docx";
     string FilePath = Directory.GetCurrentDirectory();
     FilePath += $"\\{_AppConfig.TemplateFile}\\";
     var templatePath = Path.Combine(FilePath, mubanFile);
      //数据源,字段类型 
     var textDic = new Dictionary<string, object>()
     {
         ["名称"] = 结果 ?? "",   
         ["一般"] = "口",//选择框处理  
     };
//特殊情况特殊处理
     if (result.CauseAnalysisList.Count > 0)
     {
         textDic.Add("名称", 结果 ?? "");
 
     }
  string exportFileName = result.ReportCode + " 纠正和预防措施报告.docx";
  string targetPath = $@"{_AppConfig.TempExportDir}\{exportFileName}";
//调用工具类
  CommonTool.Export(targetPath, templatePath, textDic);
 
  var returnInfo = new Dictionary<string, object>()
  {
      ["targetPath"] = targetPath,
      ["exportFileName"] = exportFileName
  };
  return returnInfo;
}

  在处理数据源的时候,可以使用字典直接进行数据传输,但是有一些特殊的情况,也是需要进行特殊处理的

posted @   喜东东三三  阅读(454)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示