239 lines
9.6 KiB
C#
239 lines
9.6 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|