refactor: 更新 README 和代码以支持默认模板导出功能

- README.md: 修改数据源描述,明确默认模板随程序发布,并更新操作流程中的按钮名称。
- ExcelService.cs: 重命名模板生成方法为 CopyTemplate,简化模板导出逻辑。
- MainForm.cs: 更新按钮文本和事件处理,改为导出默认模板。
- Config.cs 和 config.json: 添加 OriginalEstimateRef 字段以支持新功能。
- 删除不再使用的 build_template.ps1 脚本及相关模板部件。
This commit is contained in:
chenshoulin
2026-11-01 12:14:10 +08:00
parent 49d29133cc
commit c2d121d185
14 changed files with 74 additions and 292 deletions
+22 -75
View File
@@ -16,22 +16,23 @@ namespace TfsExcelImporter
public string FinancialProject { get; set; }
public string Completed { get; set; }
public string LogDate { get; set; }
public string CreatedDate { get; set; }
public string ClosedDate { get; set; }
public string PbiId { get; set; }
public string Notes { get; set; }
public string Description { get; set; }
}
/// <summary>
/// Excel 读取与模板生成。
/// 模板列: Title | State | Assigned To | FinancialProject | Completed | LogDate | Created Date | Closed Date | PBI Id | Notes
/// Excel 读取与默认模板。模板内容(列宽、示例行、样式)只在
/// templates\TFS导入模板.xlsx 里维护,随构建复制到 exe 目录后原样导出。
/// 列: Title | State | Assigned To | FinancialProject | Completed | LogDate | PBI Id | Description
/// </summary>
public static class ExcelService
{
public const string TemplateFileName = "TFS导入模板.xlsx";
public static readonly string[] Headers =
{
"Title", "State", "Assigned To", "FinancialProject",
"Completed", "LogDate", "Created Date", "Closed Date", "PBI Id", "Notes"
"Completed", "LogDate", "PBI Id", "Description"
};
private static readonly string[] DateFormats =
@@ -41,68 +42,15 @@ namespace TfsExcelImporter
"yyyy-MM-dd", "yyyy/MM/dd"
};
// --------------------------------------------------------- 生成模板
// --------------------------------------------------------- 默认模板
public static void GenerateTemplate(string path)
/// <summary>把随程序发布的默认模板原样复制到目标路径。</summary>
public static void CopyTemplate(string path)
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("工作项");
for (int i = 0; i < Headers.Length; i++)
{
var cell = ws.Cell(1, i + 1);
cell.Value = Headers[i];
cell.Style.Font.Bold = true;
cell.Style.Fill.BackgroundColor = XLColor.LightGray;
}
// 示例行(To Do / Done 各一,帮助理解格式)
var sample1 = new WorkItemRow
{
Title = "20261012 - 示例:货载报告解析并上传凭证受托报告相关内容",
State = "To Do",
AssignedTo = "李晓柯",
FinancialProject = "信托 - 上海信托",
Completed = "5",
LogDate = "2026-10-12",
CreatedDate = "2026-10-30 11:14:41",
ClosedDate = "",
Notes = "示例行,导入前请删除"
};
var sample2 = new WorkItemRow
{
Title = "20261009 示例:受托报告bug修复",
State = "Done",
AssignedTo = "陈卫宇",
FinancialProject = "信托 - 上海信托",
Completed = "8",
LogDate = "2026-10-09",
CreatedDate = "2026-10-10 18:20:00",
ClosedDate = "2026-10-30 18:00:00",
Notes = "示例行,导入前请删除"
};
WriteRow(ws, 2, sample1);
WriteRow(ws, 3, sample2);
ws.Columns().AdjustToContents();
ws.SheetView.FreezeRows(1);
wb.SaveAs(path);
}
}
private static void WriteRow(IXLWorksheet ws, int r, WorkItemRow row)
{
ws.Cell(r, 1).Value = row.Title ?? "";
ws.Cell(r, 2).Value = row.State ?? "";
ws.Cell(r, 3).Value = row.AssignedTo ?? "";
ws.Cell(r, 4).Value = row.FinancialProject ?? "";
ws.Cell(r, 5).Value = row.Completed ?? "";
ws.Cell(r, 6).Value = row.LogDate ?? "";
ws.Cell(r, 7).Value = row.CreatedDate ?? "";
ws.Cell(r, 8).Value = row.ClosedDate ?? "";
ws.Cell(r, 9).Value = row.PbiId ?? "";
ws.Cell(r, 10).Value = row.Notes ?? "";
var src = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TemplateFileName);
if (!File.Exists(src))
throw new FileNotFoundException("未找到默认模板文件: " + src, src);
File.Copy(src, path, true);
}
// --------------------------------------------------------- 读取数据
@@ -132,10 +80,8 @@ namespace TfsExcelImporter
FinancialProject = CellText(ws, r, headerMap, "FinancialProject"),
Completed = CellText(ws, r, headerMap, "Completed"),
LogDate = CellText(ws, r, headerMap, "LogDate"),
CreatedDate = CellText(ws, r, headerMap, "Created Date"),
ClosedDate = CellText(ws, r, headerMap, "Closed Date"),
PbiId = CellText(ws, r, headerMap, "PBI Id"),
Notes = CellText(ws, r, headerMap, "Notes")
Description = CellText(ws, r, headerMap, "Description")
});
}
}
@@ -151,7 +97,7 @@ namespace TfsExcelImporter
{
var text = ws.Cell(firstRow, c).GetString().Trim();
if (text.Length == 0) continue;
// 归一化:去掉空格/下划线,兼容 "Assigned To" / "AssignedTo" / "Created Date" 等
// 归一化:去掉空格/下划线,兼容 "Assigned To" / "AssignedTo" / "PBI Id" 等
var key = text.Replace(" ", "").Replace("_", "");
if (!map.ContainsKey(key)) map[key] = c;
}
@@ -159,11 +105,12 @@ namespace TfsExcelImporter
foreach (var h in Headers)
{
var key = h.Replace(" ", "");
if (!map.ContainsKey(key))
{
int idx = Array.IndexOf(Headers, h) + 1;
if (idx <= lastCol) map[key] = idx;
}
if (map.ContainsKey(key)) continue;
int idx = Array.IndexOf(Headers, h) + 1;
if (idx > lastCol) continue;
// 该列已有别的表头占用(如旧版模板的 Created Date 列)时不套用位置,避免读错列
bool taken = map.Values.Any(c => c == idx);
if (!taken) map[key] = idx;
}
return map;
}