169 lines
5.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 Furion.DependencyInjection;
namespace YD_Event.Core.Domain.Certificate
{
/// <summary>
/// DOCX模板解析器
/// </summary>
public class DocxTemplateParser : ITransient
{
private const string PlaceholderPattern = @"\{\{([^}]+)\}\}";
/// <summary>
/// 从DOCX文件中提取占位符
/// </summary>
/// <param name="docxStream">DOCX文件流</param>
/// <returns>占位符列表</returns>
public List<string> ExtractPlaceholders(Stream docxStream)
{
var placeholders = new HashSet<string>();
using (var document = WordprocessingDocument.Open(docxStream, false))
{
var body = document.MainDocumentPart?.Document?.Body;
if (body == null) return new List<string>();
// 解析段落中的占位符
foreach (var paragraph in body.Elements<Paragraph>())
{
var text = ExtractTextFromParagraph(paragraph);
var foundPlaceholders = ExtractPlaceholdersFromText(text);
foreach (var placeholder in foundPlaceholders)
{
placeholders.Add(placeholder);
}
}
// 解析表格中的占位符
foreach (var table in body.Elements<Table>())
{
var tablePlaceholders = ExtractPlaceholdersFromTable(table);
foreach (var placeholder in tablePlaceholders)
{
placeholders.Add(placeholder);
}
}
// 解析页眉页脚中的占位符
ExtractPlaceholdersFromHeaderFooter(document, placeholders);
}
return placeholders.OrderBy(x => x).ToList();
}
/// <summary>
/// 从文本中提取占位符
/// </summary>
/// <param name="text">文本内容</param>
/// <returns>占位符列表</returns>
private List<string> ExtractPlaceholdersFromText(string text)
{
var placeholders = new List<string>();
var matches = Regex.Matches(text, PlaceholderPattern);
foreach (Match match in matches)
{
var placeholder = match.Groups[1].Value.Trim();
if (!string.IsNullOrWhiteSpace(placeholder))
{
placeholders.Add(placeholder);
}
}
return placeholders;
}
/// <summary>
/// 从段落中提取文本
/// </summary>
/// <param name="paragraph">段落元素</param>
/// <returns>文本内容</returns>
private string ExtractTextFromParagraph(Paragraph paragraph)
{
return string.Join("", paragraph.Elements<Run>().Select(run =>
string.Join("", run.Elements<Text>().Select(text => text.Text))));
}
/// <summary>
/// 从表格中提取占位符
/// </summary>
/// <param name="table">表格元素</param>
/// <returns>占位符列表</returns>
private List<string> ExtractPlaceholdersFromTable(Table table)
{
var placeholders = new HashSet<string>();
foreach (var row in table.Elements<TableRow>())
{
foreach (var cell in row.Elements<TableCell>())
{
foreach (var paragraph in cell.Elements<Paragraph>())
{
var text = ExtractTextFromParagraph(paragraph);
var cellPlaceholders = ExtractPlaceholdersFromText(text);
foreach (var placeholder in cellPlaceholders)
{
placeholders.Add(placeholder);
}
}
}
}
return placeholders.ToList();
}
/// <summary>
/// 从页眉页脚中提取占位符
/// </summary>
/// <param name="document">Word文档对象</param>
/// <param name="placeholders">占位符集合</param>
private void ExtractPlaceholdersFromHeaderFooter(WordprocessingDocument document, HashSet<string> placeholders)
{
// 暂时跳过页眉页脚处理,因为API兼容性问题
// 实际项目中需要根据具体的DocumentFormat.OpenXml版本调整
}
/// <summary>
/// 验证占位符格式
/// </summary>
/// <param name="placeholder">占位符</param>
/// <returns>是否有效</returns>
public bool IsValidPlaceholder(string placeholder)
{
return !string.IsNullOrWhiteSpace(placeholder) &&
Regex.IsMatch(placeholder, @"^[a-zA-Z_][a-zA-Z0-9_]*$");
}
/// <summary>
/// 获取占位符类型
/// </summary>
/// <param name="placeholder">占位符</param>
/// <returns>占位符类型</returns>
public string GetPlaceholderType(string placeholder)
{
if (string.IsNullOrWhiteSpace(placeholder))
return "Text";
var lowerPlaceholder = placeholder.ToLowerInvariant();
if (lowerPlaceholder.Contains("date") || lowerPlaceholder.Contains("time"))
return "Date";
if (lowerPlaceholder.Contains("qr") || lowerPlaceholder.Contains("qrcode"))
return "QRCode";
if (lowerPlaceholder.Contains("image") || lowerPlaceholder.Contains("img") || lowerPlaceholder.Contains("photo"))
return "Image";
return "Text";
}
}
}