using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace DrillTools
{
///
/// 生成 CAM350 风格的钻孔使用报告。
///
internal static class DrillUsageReportExporter
{
public static string GenerateReport(IReadOnlyList tools, string layerName, DateTime exportTime)
{
if (tools == null)
throw new ArgumentNullException(nameof(tools));
var rows = tools.Select((tool, index) => CreateRow(tool, index + 1)).ToList();
var report = new StringBuilder();
AppendHeader(report, layerName, exportTime);
AppendRows(report, rows);
AppendTotals(report, rows);
return report.ToString();
}
private static ReportRow CreateRow(ToolItem tool, int order)
{
// 当前导出顺序与 Tool Ref 相同;未来如有独立钻孔执行顺序可拆分维护。
return new ReportRow(
order,
tool.ToolNumber,
FormatDiameter(tool.Diameter),
order,
tool.RegularHoles,
tool.SlotHoles,
tool.TotalHoles);
}
private static void AppendHeader(StringBuilder report, string layerName, DateTime exportTime)
{
report.AppendLine("Project file name: ");
report.AppendLine($"Date: {FormatDate(exportTime)}");
report.AppendLine($"Table: DrillTable_1 Layer: {layerName}");
report.AppendLine("Drill Usage:");
report.AppendLine("Table # Tool Ref Tool # Size Exp Ord Plated Hits Unplated Hits Total Hits");
report.AppendLine("======= ======== ====== ==== ======= =========== ============= ==========");
}
private static void AppendRows(StringBuilder report, IReadOnlyList rows)
{
// Column widths and gaps match the header/separator layout exactly.
// Separator sections: [0..6]=7 [9..16]=8 [20..25]=6 [37..40]=4 [52..58]=7 [61..71]=11 [74..86]=13 [89..98]=10
// Gaps between sections: 2sp 3sp 11sp 11sp 2sp 2sp 2sp
foreach (var row in rows)
{
report.AppendLine(string.Format(
CultureInfo.InvariantCulture,
"{0,-7} {1,-8} {2,-6} {3,-4} {4,-7} {5,-11} {6,-13} {7,-10}",
1,
row.ToolRef,
row.ToolNumber,
row.Size,
row.ExportOrder,
row.PlatedHits,
row.UnplatedHits,
row.TotalHits));
}
}
private static void AppendTotals(StringBuilder report, IReadOnlyList rows)
{
report.AppendLine("=========================================================== =========== ============= ==========");
report.AppendLine(string.Format(
CultureInfo.InvariantCulture,
"{0,59} {1,-11} {2,-13} {3,-10}",
"Totals:",
rows.Sum(row => row.PlatedHits),
rows.Sum(row => row.UnplatedHits),
rows.Sum(row => row.TotalHits)));
}
private static string FormatDate(DateTime value)
{
return $"{value:HH:mm:ss} {value.Year}年{value.Month}月{value.Day}日";
}
private static string FormatDiameter(double value)
{
return value.ToString("0.###", CultureInfo.InvariantCulture);
}
private sealed record ReportRow(
int ToolRef,
int ToolNumber,
string Size,
int ExportOrder,
int PlatedHits,
int UnplatedHits,
int TotalHits);
}
}