40 lines
2.7 KiB
C#
40 lines
2.7 KiB
C#
using System.Text.RegularExpressions;
|
|
using DocumentAutomation.Shared;
|
|
using DocumentFormat.OpenXml.Packaging;
|
|
using DocumentFormat.OpenXml.Wordprocessing;
|
|
using DocxWorkbench.Core;
|
|
|
|
namespace DocxWorkbench.OpenXml;
|
|
|
|
public sealed class DocumentInspector : IDocumentInspector
|
|
{
|
|
public DocumentInspectionResult Inspect(string docxPath)
|
|
{
|
|
if (!File.Exists(docxPath)) throw new FileNotFoundException("DOCX не найден.", docxPath);
|
|
var info = new FileInfo(docxPath);
|
|
using var package = WordprocessingDocument.Open(docxPath, false);
|
|
var main = package.MainDocumentPart ?? throw new InvalidDataException("В DOCX отсутствует основной документ.");
|
|
var body = main.Document.Body;
|
|
var text = main.Document.InnerText;
|
|
var headers = main.HeaderParts.Count();
|
|
var footers = main.FooterParts.Count();
|
|
var warnings = new List<string>();
|
|
if (Regex.IsMatch(text, "2019|старый|legacy", RegexOptions.IgnoreCase)) warnings.Add("Обнаружены возможные старые проектные реквизиты; проверьте вручную.");
|
|
if (main.Document.Descendants<SectionProperties>().Any(s => s.GetFirstChild<HeaderReference>() is null)) warnings.Add("Есть секция без явной ссылки на header.");
|
|
return new DocumentInspectionResult
|
|
{
|
|
FilePath = docxPath, FileSize = info.Length, LastWriteTimeUtc = info.LastWriteTimeUtc,
|
|
Sections = Math.Max(1, main.Document.Descendants<SectionProperties>().Count()),
|
|
Paragraphs = main.Document.Descendants<Paragraph>().Count(), Tables = main.Document.Descendants<Table>().Count(),
|
|
Images = main.ImageParts.Count(), Headers = headers, Footers = footers,
|
|
HasPageFields = text.Contains("PAGE", StringComparison.OrdinalIgnoreCase), HasNumPagesFields = text.Contains("NUMPAGES", StringComparison.OrdinalIgnoreCase),
|
|
HasSectionPagesFields = text.Contains("SECTIONPAGES", StringComparison.OrdinalIgnoreCase), Bookmarks = main.Document.Descendants<BookmarkStart>().Count(),
|
|
ContentControls = main.Document.Descendants<SdtElement>().Count(), Comments = package.MainDocumentPart.GetPartsOfType<WordprocessingCommentsPart>().Count(),
|
|
HasTrackedChanges = main.Document.Descendants<Inserted>().Any() || main.Document.Descendants<Deleted>().Any(),
|
|
HasProtectedParts = main.Document.Descendants<DocumentProtection>().Any(),
|
|
Styles = main.StyleDefinitionsPart?.Styles?.Elements<Style>().Select(s => s.StyleId?.Value ?? "").Where(s => s.Length > 0).Distinct().Order().ToArray() ?? [],
|
|
Warnings = warnings
|
|
};
|
|
}
|
|
}
|