Files
SzmediTools/Szmedi.RvKits/ModelManager/ReportGenerator.cs

239 lines
9.6 KiB
C#
Raw Normal View History

2025-12-23 21:37:02 +08:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EPPlus.Core.Extensions;
using OfficeOpenXml;
using OfficeOpenXml.Style;
namespace Szmedi.RvKits.ModelManager
{
public static class ReportGenerator
{
public static string Generate(List<ElementDiffInfo> results)
{
if (results == null || results.Count == 0) return "未发现构件差异。";
StringBuilder sb = new StringBuilder();
sb.AppendLine("=== Revit 版本对比报告 ===");
// 1. 新增
var added = results.Where(r => r.Status == DiffType.Added).ToList();
if (added.Any())
{
sb.AppendLine($"\n【新增构件】: {added.Count}");
foreach (var item in added)
{
sb.Append($" [+] ID:{item.ElementId} | {item.CategoryName}: {item.Name}");
// 如果 LocationChange 不为空,说明计算出了坐标
if (item.LocationChange != null && !string.IsNullOrEmpty(item.LocationChange.NewValue))
{
sb.Append($" @ {item.LocationChange.NewValue}");
}
sb.AppendLine();
}
}
// 2. 修改
var modified = results.Where(r => r.Status == DiffType.Modified).ToList();
if (modified.Any())
{
sb.AppendLine($"\n【修改构件】: {modified.Count}");
foreach (var item in modified)
{
sb.AppendLine($" [*] ID:{item.ElementId} | {item.CategoryName}: {item.Name}");
// 显示位置移动
if (item.LocationChange != null)
{
sb.AppendLine($" [位置移动]");
sb.AppendLine($" 原: {item.LocationChange.OldValue}");
sb.AppendLine($" 新: {item.LocationChange.NewValue}");
}
// 显示参数变化
foreach (var p in item.ParamChanges)
{
sb.AppendLine($" > {p.ParamName}: \"{p.OldValue}\" -> \"{p.NewValue}\"");
}
sb.AppendLine();
}
}
// 3. 删除
var deleted = results.Where(r => r.Status == DiffType.Deleted).ToList();
if (deleted.Any())
{
sb.AppendLine($"\n【删除构件】: {deleted.Count}");
foreach (var item in deleted)
{
sb.AppendLine($" [-] ID:{item.ElementId} | {item.CategoryName}: {item.Name}");
}
}
return sb.ToString();
}
public static void ToExcel(string excelPath, List<ElementDiffInfo> infos)
{
FileInfo fi = new(excelPath);
ExcelPackage package = infos.ToWorksheet("构件数量变动对比表")
.WithConfiguration(cfg => cfg.WithColumnConfiguration(c => c.AutoFit()))
.ToExcelPackage();
package.SaveAs(fi);
}
public static void Export(List<ReportRow> data, string filePath)
{
var file = new FileInfo(filePath);
if (file.Exists)
{
try { file.Delete(); }
catch { throw new Exception("无法覆盖文件请确保Excel已关闭。"); }
}
using (var package = new ExcelPackage(file))
{
var ws = package.Workbook.Worksheets.Add("构件对比表");
// --- 1. 设置表头 (模仿图片样式) ---
// 设置列宽
ws.Column(1).Width = 6; // 序号
ws.Column(2).Width = 10; // 变更类型
// 变更后 (3-7)
ws.Column(3).Width = 10; // ID
ws.Column(4).Width = 15; // 类型
ws.Column(5).Width = 25; // 设计属性
ws.Column(6).Width = 12; // 出量
ws.Column(7).Width = 12; // 坐标
// 变更前 (8-12)
ws.Column(8).Width = 10;
ws.Column(9).Width = 15;
ws.Column(10).Width = 25;
ws.Column(11).Width = 12;
ws.Column(12).Width = 12;
// 第一行:合并的大标题
ws.Cells[1, 1].Value = "序号"; ws.Cells[1, 1, 2, 1].Merge = true;
ws.Cells[1, 2].Value = "变更\n类型"; ws.Cells[1, 2, 2, 2].Merge = true;
ws.Cells[1, 3].Value = "变更后构件"; ws.Cells[1, 3, 1, 7].Merge = true;
ws.Cells[1, 8].Value = "变更前构件"; ws.Cells[1, 8, 1, 12].Merge = true;
// 第二行:子标题
string[] headers = { "图元ID", "类型", "设计属性", "出量属性", "坐标" };
for (int i = 0; i < 5; i++)
{
ws.Cells[2, 3 + i].Value = headers[i];
ws.Cells[2, 8 + i].Value = headers[i];
}
// 表头样式
using (var range = ws.Cells[1, 1, 2, 12])
{
range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
range.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
range.Style.Font.Bold = true;
range.Style.Fill.PatternType = ExcelFillStyle.Solid;
range.Style.Fill.BackgroundColor.SetColor(Color.LightGray);
range.Style.Border.Top.Style = ExcelBorderStyle.Thin;
range.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
range.Style.Border.Left.Style = ExcelBorderStyle.Thin;
range.Style.Border.Right.Style = ExcelBorderStyle.Thin;
range.Style.WrapText = true; // 允许表头换行
}
// --- 2. 填充数据 ---
int rowIdx = 3;
foreach (var item in data)
{
// 序号 & 类型
ws.Cells[rowIdx, 1].Value = item.Index;
ws.Cells[rowIdx, 2].Value = item.ChangeType;
// 设置变更类型颜色
var typeCell = ws.Cells[rowIdx, 2];
if (item.ChangeType.Contains("新增")) typeCell.Style.Font.Color.SetColor(Color.Green);
else if (item.ChangeType.Contains("删除")) typeCell.Style.Font.Color.SetColor(Color.Red);
else typeCell.Style.Font.Color.SetColor(Color.Blue);
// --- 变更后数据 (After) ---
if (item.After.IsEmpty)
{
// 如果为空合并5列显示“无”
ws.Cells[rowIdx, 3].Value = "无";
ws.Cells[rowIdx, 3, rowIdx, 7].Merge = true;
}
else
{
FillData(ws, rowIdx, 3, item.After);
}
// --- 变更前数据 (Before) ---
if (item.Before.IsEmpty)
{
// 如果为空合并5列显示“无”
ws.Cells[rowIdx, 8].Value = "无";
ws.Cells[rowIdx, 8, rowIdx, 12].Merge = true;
}
else
{
FillData(ws, rowIdx, 8, item.Before);
}
rowIdx++;
}
// --- 3. 全局样式调整 ---
if (data.Count > 0)
{
var dataRange = ws.Cells[3, 1, rowIdx - 1, 12];
// 边框
dataRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
dataRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
dataRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
dataRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
// 对齐
dataRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
dataRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
// 特殊列左对齐 (属性列)
ws.Cells[3, 5, rowIdx - 1, 5].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; // After Props
ws.Cells[3, 10, rowIdx - 1, 10].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; // Before Props
ws.Cells[3, 7, rowIdx - 1, 7].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; // After Coords
ws.Cells[3, 12, rowIdx - 1, 12].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; // Before Coords
// 开启自动换行 (关键,否则 \n 不生效)
dataRange.Style.WrapText = true;
}
package.Save();
}
}
private static void FillData(ExcelWorksheet ws, int row, int col, ComponentState s)
{
ws.Cells[row, col].Value = s.ElementId;
ws.Cells[row, col + 1].Value = s.TypeName;
ws.Cells[row, col + 2].Value = s.DesignProps;
ws.Cells[row, col + 3].Value = s.QuantityProps;
ws.Cells[row, col + 4].Value = s.Coordinates;
}
}
}