.Net NPOI Word模板关键内容替换
一、问题需求在开发的一个项目中,需要根据给定的文档模板,将数据库中的数据形成模板样式的pdf文件,刚开始使用的是itext创建table的方式创建生成pdf,后来在调试中发现使用itext创建的pdf的样式与模板差别很大,比如封面固定为一页,第二页的数据会显示在封面中,而且使用SetLeading也无法把控间距,后来想到了,使用Word模板,将需要替换的内容设置成固定的标签,然后将新的word..
一、问题需求
在开发的一个项目中,需要根据给定的文档模板,将数据库中的数据形成模板样式的pdf文件,刚开始使用的是itext创建table的方式创建生成pdf,后来在调试中发现使用itext创建的pdf的样式与模板差别很大,比如封面固定为一页,第二页的数据会显示在封面中,而且使用SetLeading也无法把控间距,后来想到了,使用Word模板,将需要替换的内容设置成固定的标签,然后将新的word转成pdf的样式
开发使用的是VS2017,.NetCore的项目框架
二、功能实现
1、准备工作
1)将Word模板中需要替换的内容,使用设定的标签代替,我这里使用的是{$UserName} 样式的标签,其中UserName是实体类中的字段名称
2)Nuget包中搜索并安装DotNetCore.NPOI
3)在相关的操作类中,添加引用
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
2、实现的代码
1)读取并解析word模板文档段落和table表格内容,以下代码是示例,可根据实际情况修改
/// <summary>
/// 生成word文档
/// </summary>
/// <param name="userInfo">用户信息</param>
/// <param name="docTemplatePath">doc模板存放路径</param>
public static void CreateDoc(UserInfo userInfo,string docTemplatePath)
{
if (File.Exists(docTemplatePath))
{
string newTempletePath ="D:\\UploadFiles\\PdfFiles\\";
string newTempleteFileName = Guid.NewGuid().ToString() + ".docx";
if (!Directory.Exists(newTempletePath))
{
Directory.CreateDirectory(newTempletePath);
}
string newTempleteFullPath = newTempletePath + newTempleteFileName;
File.Copy(templetePath, newTempleteFullPath);//拷贝doc模板
//读取Word模板
FileStream fileStream = new FileStream(newTempleteFullPath, FileMode.Open, FileAccess.Read);
XWPFDocument myDoc = new XWPFDocument(fileStream);
//遍历段落,替换内容
foreach (var para in myDoc.Paragraphs)
{
ReplaceKey(userInfo, para);
}
//遍历table,替换单元格内容
foreach(var table in myDoc.Tables)
{
foreach (var row in table.Rows)
{
foreach (var cell in row.GetTableCells())
{
foreach (var para in cell.Paragraphs)
{
ReplaceKey(userInfo, para);
}
}
}
}
MemoryStream ms = new MemoryStream();
myDoc.Write(ms);
//保存修改后的文档
// 把 byte[] 写入文件
FileStream fs = new FileStream("D:\\newDoctest.docx", FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(ms.GetBuffer());
bw.Close();
fs.Close();
}
}
2)模板内容替换实现方法代码
/// <summary>
/// word模板内容替换
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="etity">实体数据</param>
/// <param name="para">段落</param>
private static void ReplaceKey<T>(T etity, XWPFParagraph para)
{
Type entityType = typeof(T);
PropertyInfo[] properties = entityType.GetProperties();
string entityName = entityType.Name;//实体类名称
string paratext = para.ParagraphText;
var runs = para.Runs;
string styleid = para.Style;
string text = "";
foreach(var run in runs)
{
text = run.ToString();
foreach (var p in properties)
{
string propteryName = "{$" + p.Name + "}";//Word模板中设定的需要替换的标签
object value = p.GetValue(etity);
if (value == null)
{
value = "";
}
if (text.Contains(propteryName))
{
text = text.Replace(propteryName, value.ToString());
}
run.SetText(text);//替换标签文本(重要)
}
}
}
3、注意事项
NPOI操作word文档只可操作2003版的word,或者2007版的docx文档,如果是其他版本的word文档,在读取word模板文档时会出现Exception: Wrong Local header signature: 0xE011CFD0的错误,解决这个错误,只要将word文档另存为docx格式的就可以了

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)