From d0ade35042cc95d3d1cd819dbf9fd17245a0fe90 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Mon, 26 Jan 2026 16:12:47 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A2=B0=E6=92=9E=E6=8A=A5?=
=?UTF-8?q?=E5=91=8AHTML=E7=94=9F=E6=88=90=E5=99=A8=EF=BC=8C=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E8=87=AA=E5=8A=A8=E5=AF=BC=E5=87=BAHTML=E6=8A=A5?=
=?UTF-8?q?=E5=91=8A=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
NavisworksTransportPlugin.csproj | 1 +
.../GenerateCollisionReportCommand.cs | 15 +
src/Utils/CollisionReportHtmlGenerator.cs | 296 ++++++++++++++++++
src/Utils/PathHelper.cs | 8 +
4 files changed, 320 insertions(+)
create mode 100644 src/Utils/CollisionReportHtmlGenerator.cs
diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj
index be9c13f..a62c873 100644
--- a/NavisworksTransportPlugin.csproj
+++ b/NavisworksTransportPlugin.csproj
@@ -175,6 +175,7 @@
+
diff --git a/src/Commands/GenerateCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs
index ad17679..a8e23a8 100644
--- a/src/Commands/GenerateCollisionReportCommand.cs
+++ b/src/Commands/GenerateCollisionReportCommand.cs
@@ -269,6 +269,21 @@ namespace NavisworksTransport.Commands
// 显示报告(UI线程)
ShowReport(result);
+
+ // 🔥 自动导出HTML报告
+ try
+ {
+ string htmlPath = Utils.CollisionReportHtmlGenerator.AutoSaveHtmlReport(result);
+ if (!string.IsNullOrEmpty(htmlPath))
+ {
+ LogManager.Info($"HTML报告已自动导出: {htmlPath}");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"自动导出HTML报告失败: {ex.Message}");
+ // HTML导出失败不影响报告生成
+ }
}
catch (OperationCanceledException)
{
diff --git a/src/Utils/CollisionReportHtmlGenerator.cs b/src/Utils/CollisionReportHtmlGenerator.cs
new file mode 100644
index 0000000..f2a310c
--- /dev/null
+++ b/src/Utils/CollisionReportHtmlGenerator.cs
@@ -0,0 +1,296 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using NavisworksTransport.Commands;
+
+namespace NavisworksTransport.Utils
+{
+ ///
+ /// 碰撞报告HTML生成器
+ ///
+ public static class CollisionReportHtmlGenerator
+ {
+ ///
+ /// 生成HTML报告内容
+ ///
+ /// 碰撞报告结果
+ /// HTML文件路径(用于计算截图相对路径)
+ /// HTML内容
+ public static string GenerateHtmlReport(CollisionReportResult report, string htmlFilePath)
+ {
+ if (report == null)
+ {
+ throw new ArgumentNullException(nameof(report));
+ }
+
+ var html = new StringBuilder();
+ var now = DateTime.Now;
+
+ // HTML头部和样式
+ html.AppendLine("");
+ html.AppendLine("
");
+ html.AppendLine("");
+ html.AppendLine("NavisworksTransport 碰撞检测报告");
+ html.AppendLine("");
+ html.AppendLine("");
+
+ // 报告标题
+ html.AppendLine($"NavisworksTransport 碰撞检测报告
");
+ html.AppendLine($"生成时间: {now:yyyy年MM月dd日 HH:mm:ss}
");
+ html.AppendLine($"报告类型: 综合报告
");
+ html.AppendLine($"路径名称: {report.PathName ?? "未知路径"}
");
+
+ // 总体统计
+ html.AppendLine("");
+ html.AppendLine("
总体统计
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
总碰撞数
");
+ html.AppendLine($"
{report.TotalCollisions}
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
碰撞构件
");
+ html.AppendLine($"
{report.UniqueCollidedObjectsCount}个
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
检测点
");
+ html.AppendLine($"
{report.AnimationCollisions}个
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+
+ // 动画参数
+ html.AppendLine("动画参数
");
+ html.AppendLine("");
+ html.AppendLine("
");
+ html.AppendLine("
帧率
");
+ html.AppendLine($"
{report.FrameRate} FPS
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
时长
");
+ html.AppendLine($"
{report.Duration:F1} 秒
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
检测容差
");
+ html.AppendLine($"
{report.DetectionTolerance:F2} 米
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+
+ // 碰撞场景截图
+ if (!string.IsNullOrEmpty(report.ScreenshotPath) && File.Exists(report.ScreenshotPath))
+ {
+ html.AppendLine("碰撞场景截图
");
+ html.AppendLine("");
+
+ // 使用 PathHelper 计算相对路径
+ string relativePath = PathHelper.GetRelativePath(htmlFilePath, report.ScreenshotPath);
+
+ html.AppendLine("
");
+ html.AppendLine($"

");
+ html.AppendLine("
");
+ html.AppendLine($"
分辨率: {report.ScreenshotWidth} x {report.ScreenshotHeight}
");
+ html.AppendLine($"
格式: {report.ScreenshotFormat}
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ html.AppendLine("
");
+ }
+
+ // 运动构件信息
+ if (!string.IsNullOrEmpty(report.MovingObjectInfo))
+ {
+ html.AppendLine("运动构件信息
");
+ html.AppendLine("");
+ html.AppendLine($"🚛 {report.MovingObjectInfo}");
+ html.AppendLine("
");
+ }
+
+ // 碰撞构件清单
+ if (report.CollidedObjectsList?.Count > 0)
+ {
+ html.AppendLine("碰撞构件清单
");
+ html.AppendLine("");
+ int index = 1;
+ foreach (var objName in report.CollidedObjectsList.Take(50)) // 限制显示前50个
+ {
+ html.AppendLine($"
{index}. {objName}
");
+ index++;
+ }
+ if (report.CollidedObjectsList.Count > 50)
+ {
+ html.AppendLine($"
... 还有 {report.CollidedObjectsList.Count - 50} 个构件
");
+ }
+ html.AppendLine("
");
+ }
+
+ // 总结与建议
+ html.AppendLine("总结与建议
");
+ html.AppendLine("");
+
+ // 根据碰撞数量生成总结信息
+ string summaryMessage;
+ if (report.TotalCollisions == 0)
+ {
+ summaryMessage = "✅ 未检测到碰撞,路径规划合理,可以安全通行。";
+ }
+ else if (report.TotalCollisions <= 5)
+ {
+ summaryMessage = $"⚠️ 检测到 {report.TotalCollisions} 个碰撞,建议优化路径或调整构件位置。";
+ }
+ else
+ {
+ summaryMessage = $"🔴 检测到 {report.TotalCollisions} 个碰撞,存在严重安全隐患,必须立即处理。";
+ }
+
+ html.AppendLine($"
{summaryMessage}
");
+
+ // 生成建议措施
+ html.AppendLine("
建议措施:
");
+ html.AppendLine("
");
+
+ if (report.TotalCollisions == 0)
+ {
+ html.AppendLine("- 保持当前路径规划方案
");
+ html.AppendLine("- 定期检查构件位置变化
");
+ html.AppendLine("- 建议进行现场复核确认
");
+ }
+ else
+ {
+ html.AppendLine("- 检查碰撞构件的实际位置和尺寸
");
+ html.AppendLine("- 优化路径规划,避开碰撞区域
");
+ html.AppendLine("- 调整构件位置或尺寸
");
+ html.AppendLine("- 考虑增加安全间隙
");
+ html.AppendLine("- 进行现场勘察确认
");
+ }
+
+ html.AppendLine("
");
+ html.AppendLine("
");
+
+ // 详细碰撞信息(前10个)
+ if (report.AllCollisions?.Count > 0)
+ {
+ html.AppendLine("碰撞详情
");
+ int collisionIndex = 1;
+ foreach (var collision in report.AllCollisions.Take(10))
+ {
+ html.AppendLine("");
+
+ // 生成碰撞标题
+ string item1Name = collision.Item1 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item1) : "未知对象";
+ string item2Name = collision.Item2 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) : "未知对象";
+ html.AppendLine($"
{collisionIndex}. {item1Name} ↔ {item2Name}
");
+
+ // 碰撞距离
+ html.AppendLine($"
碰撞距离: {collision.Distance:F3} 米
");
+
+ // 碰撞位置
+ if (collision.Center != null)
+ {
+ html.AppendLine($"
碰撞位置: ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})
");
+ }
+
+ html.AppendLine("
");
+ collisionIndex++;
+ }
+ if (report.AllCollisions.Count > 10)
+ {
+ html.AppendLine($"... 还有 {report.AllCollisions.Count - 10} 个碰撞未显示
");
+ }
+ }
+
+ // HTML结尾
+ html.AppendLine($"
");
+ html.AppendLine($"报告生成完成 - {now:HH:mm:ss}
");
+ html.AppendLine("");
+
+ return html.ToString();
+ }
+
+ ///
+ /// 保存HTML报告到文件
+ ///
+ /// 碰撞报告结果
+ /// HTML文件保存路径
+ /// 是否保存成功
+ public static bool SaveHtmlReport(CollisionReportResult report, string htmlFilePath)
+ {
+ try
+ {
+ // 确保目录存在
+ string directory = Path.GetDirectoryName(htmlFilePath);
+ if (!string.IsNullOrEmpty(directory))
+ {
+ PathHelper.EnsureDirectoryExists(directory);
+ }
+
+ // 生成HTML内容
+ string htmlContent = GenerateHtmlReport(report, htmlFilePath);
+
+ // 保存到文件
+ File.WriteAllText(htmlFilePath, htmlContent, System.Text.Encoding.UTF8);
+
+ LogManager.Info($"HTML报告已保存: {htmlFilePath}");
+ return true;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"保存HTML报告失败: {ex.Message}", ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 自动生成并保存HTML报告到默认目录
+ ///
+ /// 碰撞报告结果
+ /// HTML文件路径,失败返回null
+ public static string AutoSaveHtmlReport(CollisionReportResult report)
+ {
+ try
+ {
+ // 生成文件名
+ string sanitizedName = PathHelper.SanitizeFileName(report.PathName ?? "未知路径");
+ string fileName = PathHelper.GenerateTimestampedFileName($"collision_{sanitizedName}", "html");
+
+ // 获取报告目录
+ string reportDir = PathHelper.GetReportDirectory();
+ string htmlFilePath = Path.Combine(reportDir, fileName);
+
+ // 保存报告
+ if (SaveHtmlReport(report, htmlFilePath))
+ {
+ return htmlFilePath;
+ }
+
+ return null;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"自动保存HTML报告失败: {ex.Message}", ex);
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Utils/PathHelper.cs b/src/Utils/PathHelper.cs
index f16f3cd..2ea2007 100644
--- a/src/Utils/PathHelper.cs
+++ b/src/Utils/PathHelper.cs
@@ -33,6 +33,14 @@ namespace NavisworksTransport.Utils
return Path.Combine(GetPluginDirectory(), "screenshots");
}
+ ///
+ /// 获取报告目录路径
+ ///
+ public static string GetReportDirectory()
+ {
+ return Path.Combine(GetPluginDirectory(), "reports");
+ }
+
///
/// 确保目录存在,不存在则创建
///