using System.Collections;
using System.Text.RegularExpressions;
using NetModular.DocX.Core;
namespace Infrastructure.Helpers;
public class WordHelper
{
///
/// 导出word
///
/// 模板路径
/// 保存路径
/// 数据
public static void Export(string tempFilePath, string outPath, Dictionary data)
{
bool isrewrite = true; // true=覆盖已存在的同名文件,false则反之
//if (!System.IO.Directory.Exists(outPath))
//{
// System.IO.Directory.CreateDirectory(outPath);
//}
File.Copy(tempFilePath, outPath, isrewrite);
//新建一个Word文档,加载Load的方法和Create使用一样。
using (DocX document = DocX.Load(outPath))
{
ReplaceDoc(document, data); //普通文本替换
ReplaceTable(document, data); //表格处理
ReplaceList(document, data); //文本列表处理
document.Save(); //保存
}
}
private static void ReplaceDoc(DocX doc, Dictionary data)
{
foreach (var item in doc.Paragraphs)
{
ReplaceParagraph(item, data);
}
}
private static void ReplaceList(DocX doc, Dictionary data)
{
//一定要在 普通文本替换和表格处理之后
foreach (var p in doc.Paragraphs)
{
var li = GetListInfo(p, data);
if (li.IsList)
{
var pc = li.PTemp;
for (int i = 0; i < li.Data.Count; i++)
{
var pt = pc.InsertParagraphAfterSelf(p);
if (li.IsDict)
{
pc = ReplaceParagraph(pt, (Dictionary)li.Data[i]);
}
else
{
pc = ReplaceParagraph(pt, li.Data[i]);
}
}
//删除模板行
li.PTemp.Remove(false);
}
else
{
//do nonthing
}
}
}
private static void ReplaceTable(DocX doc, Dictionary data)
{
var tbs = doc.Tables;
foreach (var table in tbs)
{
//需要先判断表格是列表还是表单
var ti = GetTableInfo(table, data);
if (ti.IsList)
{
for (int i = 0; i < ti.Data.Count; i++)
{
var rt = table.InsertRow(ti.RowTemp);
rt.Height = ti.RowTemp.Height;
rt.MinHeight = ti.RowTemp.MinHeight;
if (ti.IsDict)
{
ReplaceRow(rt, (Dictionary)ti.Data[i]);
}
else
{
ReplaceRow(rt, ti.Data[i]);
}
}
//删除模板行
ti.RowTemp.Remove();
}
else
{
//do nonthing
}
}
}
private static void ReplaceRow(Row row, Dictionary data)
{
foreach (var cell in row.Cells)
{
foreach (var item in cell.Paragraphs)
{
ReplaceParagraph(item, data);
}
}
}
private static void ReplaceRow(Row row, object data)
{
foreach (var cell in row.Cells)
{
foreach (var item in cell.Paragraphs)
{
ReplaceParagraph(item, data);
}
}
}
private static Paragraph ReplaceParagraph(Paragraph p, Dictionary data)
{
Paragraph pr = p;
var ms = GetMatches(p.Text);
var ks = new List();
var rs = new List();
foreach (Match m in ms)
{
if (m.Groups.Count > 1)
{
string text = m.Groups[1].Value;
if (text.Contains("."))
{
var ts = text.Split(".");
text = ts[ts.Length - 1];
}
ks.Add(text);
rs.Add(m.Value);
}
}
bool isCt = data.Any(op => ks.Any(o => o.Contains(op.Key)));
bool isReplace = false;
if (isCt)
{
if (ks.Count > 1)
{
for (int i = 0; i < ks.Count; i++)
{
if (data.ContainsKey(ks[i]))
{
p.ReplaceText(rs[i], data[ks[i]]?.ToString());
}
}
}
else if (ks.Count == 1)
{
string text = ks[0];
if (data.ContainsKey(text))
{
var ct = data[text]?.ToString();
var cts = ResolveText(ct);
var pc = p;
foreach (var item2 in cts)
{
if (string.IsNullOrWhiteSpace(item2)) continue;
var pt = pc.InsertParagraphAfterSelf(p);
pt.ReplaceText(rs[0], item2);
pc = pt;
pr = pc;
}
isReplace = true;
}
}
if (isReplace)
{
//删除原来段落
p.Remove(false);
}
}
return pr;
}
private static Paragraph ReplaceParagraph(Paragraph p, object data)
{
var ms = GetMatches(p.Text);
var isReplace = false;
Paragraph pr = p;
foreach (Match item1 in ms)
{
if (item1.Groups.Count > 1)
{
string text = item1.Groups[1].Value;
var ct = data?.ToString();
var cts = ResolveText(ct);
var pc = p;
foreach (var item2 in cts)
{
var pt = pc.InsertParagraphAfterSelf(p);
pt.ReplaceText(item1.Value, item2);
pc = pt;
pr = pc;
}
isReplace = true;
}
}
if (isReplace)
{
//删除原来段落
p.Remove(false);
}
return pr;
}
private static IList ResolveText(string text)
{
if (string.IsNullOrEmpty(text)) return new List();
text = text.Replace("\r\n", "\n").Replace("\r", "\n");
return text.Split('\n');
}
private static MatchCollection GetMatches(string text)
{
if (string.IsNullOrEmpty(text)) text = "";
Regex regex = new Regex("[#|\\$]([a-zA-Z0-9_.]+?)[#|\\$]",
RegexOptions.IgnoreCase | RegexOptions.Multiline);
return regex.Matches(text);
}
///
/// 只获取列表匹配项
///
///
///
private static MatchCollection GetListMatches(string text)
{
if (string.IsNullOrEmpty(text)) text = "";
Regex regex = new Regex("\\$([a-zA-Z0-9_.]+?)\\$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
return regex.Matches(text);
}
//纯辅助方法
private class TableInfo
{
public bool IsList { get; set; }
public bool IsDict { get; set; }
public Row RowTemp { get; set; }
public IList