Files
autodesk/DocumentAutomation/src/DocxWorkbench.OpenXml/DocumentInspector.cs
T

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
};
}
}