KellyReport_D/Utils/WorkBookUtils.cs

288 lines
12 KiB
C#

using KellyReport_D.Properties;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using KellyReport_D.Model;
namespace KellyReport_D.Utils
{
internal static class WorkBookUtils
{
public static async void GenForecast(System.Windows.Forms.Button button)
{
String originLabel = button.Text;
if (button != null)
{
button.Text = Resources.GENERATING;
}
var app = Globals.ThisAddIn.Application;
var context = new GenForecaseContext
{
Application = app
};
try
{
// 获取「銷售年度預估」工作表
readSalesForecastData(context);
// 获取「產品年度預估」工作表
readProductForecastData(context);
// 获取「客户资料」工作表
readClientContact(context);
GenBussenessSheet(context);
}
catch (Exception ex)
{
Console.WriteLine("Error generating forecast:" + ex.Message);
MessageBox.Show("分析预估表失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
button.Text = originLabel;
}
public static void GenBussenessSheet(GenForecaseContext context)
{
var app = context.Application;
// 假设 app 是 Excel.Application
Worksheet sheet = null;
string sheetName = "業務月達成率";
try
{
// 新增工作表
sheet = app.Worksheets.Add();
sheet.Name = sheetName;
}
catch
{
// 已存在则获取
sheet = app.Worksheets[sheetName] as Worksheet;
try
{
Range usedRange = sheet.UsedRange;
if (usedRange != null && usedRange.Cells.Count > 1)
{
usedRange.Clear();
}
}
catch
{
// 无 UsedRange 可忽略
}
}
// 合并A1:A2并填入年份
try
{
var monthData = context.MonthData;
var yearValue = monthData[0];
Range yearRange = sheet.Range["A1", "A2"];
yearRange.Merge();
yearRange.Value2 = yearValue.ToString();
yearRange.NumberFormat = "@"; // 文本格式
// 填入月份
for (int i = 1; i < monthData.Length; i++)
{
sheet.Cells[i + 2, 1] = monthData[i];
}
// B列开始填 salesName 及相关数据
int col = 2; // B列
foreach (var salesForcastData in context.SalesForecastList)
{
int rowIndex = 1; // Excel 行号从1开始
int startCol = col;
int endCol = col + 4;
// 合并并填入 salesName
Range salesNameRange = sheet.Range[
sheet.Cells[rowIndex, startCol],
sheet.Cells[rowIndex, startCol + 1]
];
salesNameRange.Merge();
salesNameRange.Value2 = salesForcastData.Name;
// 合并并填入“完成%”
Range finishRange = sheet.Range[
sheet.Cells[rowIndex, startCol + 2],
sheet.Cells[rowIndex, startCol + 2]
];
finishRange.Merge();
finishRange.Value2 = "完成%";
// 合并并填入“累積達成率”
Range accRange = sheet.Range[
sheet.Cells[rowIndex, startCol + 3],
sheet.Cells[rowIndex, startCol + 3]
];
accRange.Merge();
accRange.Value2 = "累積達成率";
// 第二行填入 Y-forecast 和 turnover
rowIndex++;
sheet.Cells[rowIndex, startCol] = "Y-forecast";
sheet.Cells[rowIndex, startCol + 1] = "turnover";
// 填入每月数据
rowIndex++;
foreach (var forcastMonth in salesForcastData.MonthlyForecast)
{
var cell = sheet.Cells[rowIndex, startCol];
cell.Value2 = forcastMonth;
cell.NumberFormat = "#,##0";
rowIndex++;
}
col = endCol;
}
// 自适应所有已用列宽
Range usedRange2 = sheet.UsedRange;
if (usedRange2 != null)
{
usedRange2.Columns.AutoFit();
}
}
catch (Exception ex)
{
MessageBox.Show("写入业绩月达成率时发生错误:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private static void readClientContact(GenForecaseContext context)
{
var app = context.Application;
var clientContactSheet = app.Worksheets["客戶資料"] as Worksheet;
var clientContactRange = clientContactSheet.UsedRange;
IList<ClientContact> clientContactList = new List<ClientContact>();
if (clientContactRange.Value2 is object[,] rawContactData)
{
int rowCount = rawContactData.GetLength(0);
int colCount = rawContactData.GetLength(1);
// 模板第二行开始是数据
for (int i = 2; i <= rowCount; i++)
{
var input = new ClientContact
{
Region = rawContactData[i, 1]?.ToString() ?? "",
Industry = rawContactData[i, 2]?.ToString() ?? "",
AnnualCapacity = rawContactData[i, 3]?.ToString() ?? "",
Name = rawContactData[i, 4]?.ToString() ?? "",
PurchasingManager = rawContactData[i, 5]?.ToString() ?? "",
PurchasingManagerPhone = rawContactData[i, 6]?.ToString() ?? "",
Purchaser = rawContactData[i, 7]?.ToString() ?? "",
PurchaserPhone = rawContactData[i, 8]?.ToString() ?? "",
Address = rawContactData[i, 9]?.ToString() ?? ""
};
clientContactList.Add(input);
}
}
context.ClientContactList = clientContactList;
}
private static void readProductForecastData(GenForecaseContext context)
{
var app = context.Application;
var productForecastSheet = app.Worksheets["產品年度預估"] as Worksheet;
var productRange = productForecastSheet.UsedRange;
IList<ProductForecastInput> productForecastList = new List<ProductForecastInput>();
if (productRange.Value2 is object[,] rawProductData)
{
int rowCount = rawProductData.GetLength(0);
int colCount = rawProductData.GetLength(1);
if (rawProductData[1, 2] == null)
{
throw new MissingMemberException("「產品年度預估」工作表的(年份)不能为空,请检查数据格式。");
}
var year = Convert.ToInt32(rawProductData[1, 2]);
// 模板第三行开始是数据
for (int i = 3; i <= rowCount; i++)
{
var input = new ProductForecastInput
{
Year = year,
Name = rawProductData[i, 1]?.ToString() ?? "",
Quantity = rawProductData[i, 2] != null ? Convert.ToDecimal(rawProductData[i, 2]) : 0,
AmountTax = rawProductData[i, 3] != null ? Convert.ToDecimal(rawProductData[i, 3]) : 0,
Amount = rawProductData[i, 4] != null ? Convert.ToDecimal(rawProductData[i, 4]) : 0,
PriceAvg = rawProductData[i, 5] != null ? Convert.ToDecimal(rawProductData[i, 5]) : 0,
};
productForecastList.Add(input);
}
}
context.ProductForecastList = productForecastList;
}
private static void readSalesForecastData(GenForecaseContext context)
{
var app = context.Application;
var salesForecastSheet = app.Worksheets["銷售年度預估"] as Worksheet;
var salesRange = salesForecastSheet.UsedRange;
IList<SalesForecastInput> salesForecastInputList = new List<SalesForecastInput>();
string[] monthData = new string[13];
if (salesRange.Value2 is object[,] rawSalesData)
{
int rowCount = rawSalesData.GetLength(0);
int colCount = rawSalesData.GetLength(1);
if (rawSalesData[1, 2] == null)
{
throw new MissingMemberException("「銷售年度預估」工作表的(年份)不能为空,请检查数据格式。");
}
var year = Convert.ToInt32(rawSalesData[1, 2]);
monthData[0] = year.ToString();
for (int i = 1; i <= 12; i++)
{
monthData[i] = rawSalesData[2, i + 1].ToString();
}
// 模板第三行开始是数据
for (int i = 3; i <= rowCount; i++)
{
var input = new SalesForecastInput
{
Year = year,
Name = rawSalesData[i, 1]?.ToString() ?? "",
January = rawSalesData[i, 2] != null ? Convert.ToDecimal(rawSalesData[i, 2]) : 0,
February = rawSalesData[i, 3] != null ? Convert.ToDecimal(rawSalesData[i, 3]) : 0,
March = rawSalesData[i, 4] != null ? Convert.ToDecimal(rawSalesData[i, 4]) : 0,
April = rawSalesData[i, 5] != null ? Convert.ToDecimal(rawSalesData[i, 5]) : 0,
May = rawSalesData[i, 6] != null ? Convert.ToDecimal(rawSalesData[i, 6]) : 0,
June = rawSalesData[i, 7] != null ? Convert.ToDecimal(rawSalesData[i, 7]) : 0,
July = rawSalesData[i, 8] != null ? Convert.ToDecimal(rawSalesData[i, 8]) : 0,
August = rawSalesData[i, 9] != null ? Convert.ToDecimal(rawSalesData[i, 9]) : 0,
September = rawSalesData[i, 10] != null ? Convert.ToDecimal(rawSalesData[i, 10]) : 0,
October = rawSalesData[i, 11] != null ? Convert.ToDecimal(rawSalesData[i, 11]) : 0,
November = rawSalesData[i, 12] != null ? Convert.ToDecimal(rawSalesData[i, 12]) : 0,
December = rawSalesData[i, 13] != null ? Convert.ToDecimal(rawSalesData[i, 13]) : 0,
Total = rawSalesData[i, 14] != null ? Convert.ToDecimal(rawSalesData[i, 14]) : 0,
};
salesForecastInputList.Add(input);
}
}
context.SalesForecastList = salesForecastInputList;
context.MonthData = monthData;
}
}
}