feat: add learned document template workflow
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -40,7 +41,7 @@ public sealed class WordDocumentService : IWordDocumentService, IDisposable
|
||||
range = Own(FindInsertionRange(document, insertion.Type, proxies), proxies) ?? throw new WordAutomationException("The insertion point disappeared while opening the template.");
|
||||
token.ThrowIfCancellationRequested(); progress?.Report($"Inserting {Path.GetExtension(request.BodyPath).ToUpperInvariant()} body"); if (request.BodyPath.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)) range.Text = File.ReadAllText(request.BodyPath).Replace("\r\n", "\r").Replace('\n', '\r'); else bodyImport = _bodyImporter.ImportOnSta(application, document, range, new DocxBodyImportRequest { SourcePath = request.BodyPath, DestinationRangeHandle = range }, progress is null ? null : new Progress<WordOperationProgress>(x => progress.Report(x.Message ?? x.Stage)), token, proxies);
|
||||
token.ThrowIfCancellationRequested(); progress?.Report("Updating fields and pagination"); document.Repaginate(); document.Fields.Update(); UpdateHeadersFooters(document, proxies); document.SaveAs2(stagedOutput, 12); document.Close(0); document = null; RemoveUnreferencedHeaderFooterParts(stagedOutput); CommitOutput(stagedOutput, request.OutputDocxPath);
|
||||
var logPath = Path.ChangeExtension(request.OutputDocxPath, ".generation.json"); File.WriteAllText(logPath, JsonSerializer.Serialize(new { operationId = Guid.NewGuid(), template = request.TemplatePath, body = request.BodyPath, output = request.OutputDocxPath, insertionPoint = insertion.Type, wordPid, staThread = Thread.CurrentThread.ManagedThreadId, staApartment = Thread.CurrentThread.GetApartmentState().ToString(), durationMs = started.ElapsedMilliseconds, completedAtUtc = DateTime.UtcNow }, new JsonSerializerOptions { WriteIndented = true }));
|
||||
var logPath = Path.ChangeExtension(request.OutputDocxPath, ".generation.json"); File.WriteAllText(logPath, JsonSerializer.Serialize(new { operationId = Guid.NewGuid(), operationType = "BuildDocument", startedAtUtc = DateTime.UtcNow.Subtract(started.Elapsed), completedAtUtc = DateTime.UtcNow, template = request.TemplatePath, templateSha256 = Hash(request.TemplatePath), templateVersion = "1.0", body = request.BodyPath, sourceSha256 = Hash(request.BodyPath), output = request.OutputDocxPath, resultSha256 = Hash(request.OutputDocxPath), insertionPoint = insertion.Type, wordPid, staThread = Thread.CurrentThread.ManagedThreadId, staApartment = Thread.CurrentThread.GetApartmentState().ToString(), durationMs = started.ElapsedMilliseconds, status = "Succeeded", errorCode = (string?)null }, new JsonSerializerOptions { WriteIndented = true }));
|
||||
return new WordDocumentResult { OutputDocxPath = request.OutputDocxPath, LogPath = logPath, Duration = started.Elapsed, InsertionPoint = insertion.Type, BodyImport = bodyImport };
|
||||
}
|
||||
catch (WordNotInstalledException) { throw; }
|
||||
@@ -81,6 +82,7 @@ public sealed class WordDocumentService : IWordDocumentService, IDisposable
|
||||
private static int? TryGetPid(dynamic application) { try { return Process.GetProcessById((int)application.Hwnd).Id; } catch { return null; } }
|
||||
private static T? Own<T>(T? value, List<object?> proxies) where T : class { if (value is not null) proxies.Add(value); return value; }
|
||||
private static void ReleaseAll(IEnumerable<object?> proxies) { foreach (var proxy in proxies.Reverse()) try { if (proxy is not null && Marshal.IsComObject(proxy)) Marshal.FinalReleaseComObject(proxy); } catch { } }
|
||||
private static string Hash(string path) => Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(path)));
|
||||
private static void CommitOutput(string staged, string output) { var full = Path.GetFullPath(output); if (File.Exists(full)) File.Copy(full, full + ".bak-" + DateTime.UtcNow.ToString("yyyyMMddHHmmss"), true); File.Copy(staged, full, true); }
|
||||
private static void RemoveUnreferencedHeaderFooterParts(string path)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user