using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NPOI.XWPF.UserModel;
using System.IO;
using System.Reflection;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using NPOI.OpenXmlFormats.Wordprocessing;
using Newtonsoft.Json.Linq;
using System.Threading;
namespace OnLineServiceMS_Common
{
public static class WordHelper
{
/// <summary>
/// 生成新的word文档
/// </summary>
/// <param name="srcPath">文件原始路径</param>
/// <param name="dstPath">输出目录路径</param>
/// <param name="info">段落数据对象</param>
/// <param name="jar">表格信息</param>
/// <param name="errMsg"></param>
/// <returns></returns>
public static bool GenerateWord_ZFZM(string srcPath, string dstPath,
JObject info, JArray jar, ref string errMsg)
{
//模板转换默认成功
bool changeFlag = true;
try
{
if (File.Exists(srcPath))
{
File.Copy(srcPath, dstPath, true);
XWPFDocument document = null;
using (FileStream stream = File.OpenRead(dstPath))
{
//获取docx解析对象
document = new XWPFDocument(stream);
}
info.Add(new JProperty("Count", jar == null ? "0" : jar.Count.ToString()));
//解析替换文本段落对象
WordHelper.ChangeText(document, info);
//解析替换表格对象
// JArray jar = JArray.Parse(info["CertList"].ToString());
WordHelper.ChangeTable(document, info, jar);
int trys=3;
while (trys > 0)
{
try
{
using (FileStream stream = new FileStream(dstPath,FileMode.Create))
{
//生成新的word
document.Write(stream);
break;
}
}
catch (Exception ex)
{
if (ex is IOException)
{
Gd.Common.SysErrorLog.Write(ex.ToString());
Thread.Sleep(3000);
trys--;
}
}
}
if (trys==0)
{
changeFlag = false;
errMsg = "文件保存失败!";
}
}
else
{
errMsg = "指定目标文件不存在!";
}
}
catch (Exception e)
{
changeFlag = false;
errMsg = e.ToString();
}
return changeFlag;
}
/// <summary>
/// 实体类转换为字典
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
[Obsolete("已过时", true)]
public static Dictionary<string, string> GetProperties<T>(T t)
{
Dictionary<string, string> ret = new Dictionary<string, string>();
if (t == null)
{
return null;
}
PropertyInfo[] properties = t.GetType().GetProperties(System.Reflection.BindingFlags.Instance | BindingFlags.Public);
if (properties.Length <= 0)
{
return null;
}
foreach (PropertyInfo item in properties)
{
string name = item.Name; //实体类字段名称
string value = item.GetValue(t, null).ToString(); //该字段的值
if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
{
if (t.GetType().Name == "CertList")
{
ret.Add("<CertList." + name + ">", value);
}
else
{
ret.Add("<" + name + ">", value);
}
}
}
return ret;
}
/// <summary>
/// 替换段落文本
/// </summary>
/// <param name="document">word对象</param>
/// <param name="textMap">字典数据</param>
private static void ChangeText(XWPFDocument document, JObject textMap)
{
//获取段落集合
List<XWPFParagraph> paragraphs = document.Paragraphs.ToList();
foreach (XWPFParagraph paragraph in paragraphs)
{
//判断此段落时候需要进行替换
string text = paragraph.Text;
if (CheckText(text))
{
ReplaceRuns(paragraph, textMap);
}
}
}
/// <summary>
/// 指定字符替换
/// </summary>
/// <param name="paragraph">段落</param>
/// <param name="textMap">替换数据</param>
private static void ReplaceRuns(XWPFParagraph paragraph, JObject textMap)
{
string text = paragraph.ParagraphText;
var newString = new Regex(@"<([^>]+?)>").Matches(text);
foreach (var item in newString)
{
string newText = "";
if (textMap != null)
{
newText = ChangeValue(item.ToString().Trim(), textMap);
if (newText != "")
{
DateTime newDa;
if (DateTime.TryParse(newText, out newDa))
{
var dataString = new Regex(@"\[.*?\]").Match(item.ToString()).ToString();
if (!string.IsNullOrEmpty(dataString))
{
newText = newDa.ToString(dataString.Replace("[", "").Replace("]", ""));
}
}
text = text.Replace(item.ToString().Replace("{", "").Replace("}", ""), newText);
}
}
}
if (paragraph.ParagraphText != "")
{
paragraph.ReplaceText(paragraph.ParagraphText, text.ToString());
}
}
/// <summary>
/// 替换表格对象
/// </summary>
/// <param name="document"></param>
/// <param name="textMap"></param>
/// <param name="tableList"></param>
public static void ChangeTable(XWPFDocument document, JObject info,
JArray tableList)
{
//获取表格对象集合
List<XWPFTable> tables = document.Tables.ToList();
for (int i = 0; i < tables.Count(); i++)
{
XWPFTable table = tables[i];
if (table.Rows.Count() > 1)
{
List<XWPFTableRow> rows = table.Rows;
//遍历表格,并替换模板
//EachTable(rows, tableList);
//数据填充
InsertTable(table, info, tableList);
}
}
}
/// <summary>
/// 添加新行
/// </summary>
/// <param name="table"></param>
/// <param name="tableList"></param>
public static void InsertTable(XWPFTable table, JObject info, JArray tableList)
{
//创建行,根据需要插入的数据添加新行,不处理表头
if (tableList != null && tableList.Count > 3)
{
for (int i = 0; i < tableList.Count - 3; i++)
{
XWPFTableRow x = table.InsertNewTableRow(i + 3);
x.GetCTRow().AddNewTrPr().AddNewTrHeight().val = (ulong)table.GetRow(0).Height;//指定行高
for (int j = 0; j < 9; j++)
{
x.AddNewTableCell();
}
}
}
//遍历表格插入数据
List<XWPFTableRow> rows = table.Rows.ToList();
List<string> keys = EachTable(rows, info, tableList == null ? null : JObject.Parse(tableList[0].ToString()));
if (tableList != null)
{
for (int i = 1; i < tableList.Count; i++)//不计算表头与第一行
{
List<XWPFTableCell> cells = table.GetRow(i + 1).GetTableCells();
for (int j = 0; j < cells.Count; j++)
{
//插入数据并设置样式
XWPFTableCell xph = table.GetRow(0).GetTableCells()[j];
JObject jb = JObject.Parse(tableList[i].ToString());
table.GetRow(i).GetCell(j).SetVerticalAlignment(xph.GetVerticalAlignment());
XWPFParagraph pIO = cells[j].Paragraphs[0];
pIO.Alignment = xph.Paragraphs[0].Alignment;
XWPFRun rIO = cells[j].Paragraphs[0].CreateRun();
rIO.FontFamily = xph.Paragraphs[0].Runs[0].FontFamily;
rIO.FontSize = xph.Paragraphs[0].Runs[0].FontSize;
rIO.SetColor(xph.Paragraphs[0].Runs[0].GetColor());
string key = keys[j].Split('.')[1].Replace(">", "").Trim();
if (jb.Property(key) != null)
{
rIO.SetText(jb[key].ToString());
}
else
{
rIO.SetText("");
}
}
}
}
}
/// <summary>
/// 表格遍历
/// </summary>
/// <param name="rows"></param>
/// <param name="textMap"></param>
public static List<string> EachTable(List<XWPFTableRow> rows, JObject tableLine, JObject textMap)
{
var newString = new Regex(@"<([^>]+?)>");
List<string> keyName = new List<string>();
foreach (XWPFTableRow row in rows)
{
List<XWPFTableCell> cells = row.GetTableCells();
foreach (XWPFTableCell cell in cells)
{
List<XWPFParagraph> paragraphs = cell.Paragraphs.ToList();
for (int i = 0; i < paragraphs.Count; i++)
{
string text = paragraphs[i].ParagraphText;
if (text.IndexOf(".") > -1)//匹配是否存在指定关键字
{
if (textMap != null)
{
keyName.Add(text);
string s = ChangeValue(text.Split('.')[1].Trim(), textMap);
paragraphs[i].ReplaceText(text, s);
}
else
{
paragraphs[i].ReplaceText(text, "");
}
}
else
{
if (newString.IsMatch(text))
{
string msgString = newString.Match(text).ToString();
// paragraphs[i].ReplaceText(text, ChangeValue(msgString, tableLine));
ReplaceRuns(paragraphs[i], tableLine);
}
}
}
}
}
return keyName;
}
/// <summary>
/// 匹配传入信息集合与模板
/// </summary>
/// <param name="value">模板需要替换的区域</param>
/// <param name="textMap">传入信息集合</param>
/// <returns>模板需要替换区域信息集合对应值</returns>
private static string ChangeValue(string key, JObject textMap)
{
if (key.IndexOf("[") > -1)
{
key = key.Split('[')[0].Replace("<", "").Trim();
}
else
{
key = key.Replace("<", "").Replace(">", "").Trim();
}
if (textMap.Property(key) != null)
{
return textMap[key].ToString();
}
else
{
return key;
}
}
/// <summary>
/// 匹配是否存在指定关键字符
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private static bool CheckText(string text)
{
bool check = false;
var reg = new Regex(@"<([^>]+?)>");
if (reg.IsMatch(text))
{
check = true;
}
return check;
}
}
}