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;
}
在处理数据源的时候,可以使用字典直接进行数据传输,但是有一些特殊的情况,也是需要进行特殊处理的

浙公网安备 33010602011771号