using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
using Furion.DependencyInjection;
namespace YD_Event.Core.Certificate
{
///
/// DOCX模板处理器
///
public class DocxTemplateProcessor : ITransient
{
private const string PlaceholderPattern = @"\{\{([^}]+)\}\}";
///
/// 处理DOCX模板,替换占位符
///
/// 模板文件流
/// 数据字典
/// 二维码数据字典
/// 处理后的文件流
public Stream ProcessTemplate(Stream templateStream, Dictionary data, Dictionary qrCodeData = null)
{
var outputStream = new MemoryStream();
// 复制模板到输出流
templateStream.Position = 0;
templateStream.CopyTo(outputStream);
outputStream.Position = 0;
using (var document = WordprocessingDocument.Open(outputStream, true))
{
var body = document.MainDocumentPart?.Document?.Body;
if (body == null) return outputStream;
// 处理段落中的占位符
ProcessParagraphs(body, data, qrCodeData);
// 处理表格中的占位符
ProcessTables(body, data, qrCodeData);
// 处理页眉页脚中的占位符
ProcessHeaderFooter(document, data, qrCodeData);
document.Save();
}
outputStream.Position = 0;
return outputStream;
}
///
/// 处理段落中的占位符
///
private void ProcessParagraphs(Body body, Dictionary data, Dictionary qrCodeData)
{
foreach (var paragraph in body.Elements())
{
ProcessParagraph(paragraph, data, qrCodeData);
}
}
///
/// 处理单个段落
///
private void ProcessParagraph(Paragraph paragraph, Dictionary data, Dictionary qrCodeData)
{
var runs = paragraph.Elements().ToList();
foreach (var run in runs)
{
var texts = run.Elements().ToList();
foreach (var text in texts)
{
var processedText = ReplacePlaceholders(text.Text, data, qrCodeData);
// 检查是否是二维码占位符
if (IsQRCodePlaceholder(text.Text))
{
var placeholder = ExtractPlaceholderKey(text.Text);
if (qrCodeData != null && qrCodeData.ContainsKey(placeholder))
{
// 替换为二维码图片
ReplaceTextWithQRCode(run, qrCodeData[placeholder]);
}
else
{
text.Text = processedText;
}
}
else
{
text.Text = processedText;
}
}
}
}
///
/// 处理表格中的占位符
///
private void ProcessTables(Body body, Dictionary data, Dictionary qrCodeData)
{
foreach (var table in body.Elements())
{
foreach (var row in table.Elements())
{
foreach (var cell in row.Elements())
{
foreach (var paragraph in cell.Elements())
{
ProcessParagraph(paragraph, data, qrCodeData);
}
}
}
}
}
///
/// 处理页眉页脚中的占位符
///
private void ProcessHeaderFooter(WordprocessingDocument document,
Dictionary data, Dictionary qrCodeData)
{
// 暂时跳过页眉页脚处理,因为API兼容性问题
// 实际项目中需要根据具体的DocumentFormat.OpenXml版本调整
}
///
/// 替换文本中的占位符
///
private string ReplacePlaceholders(string text, Dictionary data, Dictionary qrCodeData)
{
if (string.IsNullOrWhiteSpace(text)) return text;
return Regex.Replace(text, PlaceholderPattern, match =>
{
var key = match.Groups[1].Value.Trim();
// 优先使用二维码数据
if (qrCodeData != null && qrCodeData.ContainsKey(key))
{
return qrCodeData[key];
}
// 使用普通数据
if (data != null && data.ContainsKey(key))
{
return data[key] ?? string.Empty;
}
// 返回原始占位符(未找到数据)
return match.Value;
});
}
///
/// 检查是否是二维码占位符
///
private bool IsQRCodePlaceholder(string text)
{
if (string.IsNullOrWhiteSpace(text)) return false;
var match = Regex.Match(text, PlaceholderPattern);
if (!match.Success) return false;
var key = match.Groups[1].Value.Trim().ToLowerInvariant();
return key.Contains("qr") || key.Contains("qrcode");
}
///
/// 提取占位符键名
///
private string ExtractPlaceholderKey(string text)
{
var match = Regex.Match(text, PlaceholderPattern);
return match.Success ? match.Groups[1].Value.Trim() : string.Empty;
}
///
/// 将文本替换为二维码图片
///
private void ReplaceTextWithQRCode(Run run, string qrCodeContent)
{
// 注意:这里需要实现二维码图片生成和插入逻辑
// 由于DocumentFormat.OpenXml处理图片比较复杂,这里先简化处理
// 实际实现需要使用QRCodeService生成图片,然后插入到文档中
// 临时实现:用文本替代
var texts = run.Elements().ToList();
foreach (var text in texts)
{
text.Text = $"[QR: {qrCodeContent}]";
}
}
///
/// 验证数据完整性
///
/// 必填占位符列表
/// 数据字典
/// 验证结果
public TemplateValidationResult ValidateTemplateData(List requiredPlaceholders, Dictionary data)
{
var result = new TemplateValidationResult { IsValid = true };
foreach (var placeholder in requiredPlaceholders)
{
if (!data.ContainsKey(placeholder) || string.IsNullOrWhiteSpace(data[placeholder]))
{
result.IsValid = false;
result.MissingPlaceholders.Add(placeholder);
}
}
return result;
}
}
///
/// 模板验证结果
///
public class TemplateValidationResult
{
public bool IsValid { get; set; }
public List MissingPlaceholders { get; set; } = new List();
public List Warnings { get; set; } = new List();
}
}