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

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

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

工具类

 /// <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则使用字典作为数据源。

实际使用案例:
 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 @ 2024-03-29 11:27  喜东东三三  阅读(591)  评论(0)    收藏  举报