添加历史年度的报表导入
This commit is contained in:
parent
c3f2d905cf
commit
aedbd788be
@ -74,7 +74,7 @@ namespace KellyReport_D
|
||||
|
||||
try
|
||||
{
|
||||
WorkBookUtils.importSalesDetailFromWorkBook(workBook);
|
||||
WorkBookUtils.ImportSalesDetailFromWorkBook(workBook);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -14,6 +14,13 @@ namespace KellyReport_D.Model
|
||||
public Microsoft.Office.Interop.Excel.Application Application { get; set; }
|
||||
public IList<ClientContact> ClientContactList { get; set; }
|
||||
public IList<SalesDetail> SalesDetails { get; set; }
|
||||
|
||||
public List<int> YearList => SalesDetails
|
||||
.Where(x => x.InvoiceDate.HasValue)
|
||||
.Select(x => x.InvoiceDate.Value.Year)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
public class GroupedSalesDetailModel
|
||||
{
|
||||
public string SalesName { get; set; }
|
||||
|
||||
@ -12,7 +12,7 @@ namespace KellyReport_D.Utils
|
||||
{
|
||||
internal static class WorkBookUtils
|
||||
{
|
||||
public static void importSalesDetailFromWorkBook(Workbook workbook)
|
||||
public static void ImportSalesDetailFromWorkBook(Workbook workbook)
|
||||
{
|
||||
var importContext = new ImportContext()
|
||||
{
|
||||
@ -28,8 +28,8 @@ namespace KellyReport_D.Utils
|
||||
foreach (var userGroupedSalesDetail in importContext.GroupedSalesDetailBySalesName)
|
||||
{
|
||||
var userSheet = GenUserSalesDetailSheet(importContext, userGroupedSalesDetail);
|
||||
PrepareTotalHeader(userSheet);
|
||||
WriteSalesDetailsData(importContext, userGroupedSalesDetail, userSheet);
|
||||
var yearColIndex = PrepareTotalHeader(userSheet, importContext);
|
||||
WriteSalesDetailsData(importContext, userGroupedSalesDetail, userSheet, yearColIndex);
|
||||
|
||||
importContext.SalesWorksheets.Add(userSheet);
|
||||
}
|
||||
@ -55,7 +55,7 @@ namespace KellyReport_D.Utils
|
||||
bussenessWorksheet = item;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (bussenessWorksheet == null)
|
||||
{
|
||||
@ -116,25 +116,120 @@ namespace KellyReport_D.Utils
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void UpdateSalesDetailSummary(Worksheet userWorkSheet, int summaryRowStartIndex)
|
||||
{
|
||||
int lastColumnIndex = userWorkSheet.UsedRange.Columns.Count;
|
||||
|
||||
int summaryRowIndex = summaryRowStartIndex;
|
||||
int sumColStart = 13; // L列是第12列
|
||||
do
|
||||
{
|
||||
userWorkSheet.Cells[summaryRowIndex, 11].Value2 = "總銷量及金額(未稅)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
userWorkSheet.Cells[summaryRowIndex, quantityColIndex].formula = $"=(SUM({quantityColLetter}4:{quantityColLetter}{summaryRowIndex - 1})/2)";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
userWorkSheet.Cells[summaryRowIndex, amountColIndex].formula = $"=((SUM({amountColLetter}4:{amountColLetter}{summaryRowIndex - 1})/2) - {amountColLetter}{summaryRowIndex + 2})/1.13";
|
||||
}
|
||||
string totalQuantityColLetter = GetColumnLetter(sumColStart + 36);
|
||||
string totalAmountColLetter = GetColumnLetter(sumColStart + 37);
|
||||
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 36].formula = $"=(SUM({totalQuantityColLetter}4:{totalAmountColLetter}{summaryRowIndex - 1})/2)";
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 37].formula = $"=((SUM({totalAmountColLetter}4:{totalAmountColLetter}{summaryRowIndex - 1})/2) - {totalAmountColLetter}{summaryRowIndex + 2})/1.13";
|
||||
|
||||
summaryRowIndex++;
|
||||
userWorkSheet.Cells[summaryRowIndex, 11].Value2 = "總銷量及金額(含稅)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
userWorkSheet.Cells[summaryRowIndex, quantityColIndex].formula = $"=(SUM({quantityColLetter}4:{quantityColLetter}{summaryRowIndex - 1})/2)";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
userWorkSheet.Cells[summaryRowIndex, amountColIndex].formula = $"=(SUM({amountColLetter}4:{amountColLetter}{summaryRowIndex - 1})/2)";
|
||||
}
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 36].formula = $"=(SUM({totalQuantityColLetter}4:{totalQuantityColLetter}{summaryRowIndex - 1})/2)";
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 37].formula = $"=(SUM({totalAmountColLetter}4:{totalAmountColLetter}{summaryRowIndex - 1})/2)";
|
||||
|
||||
summaryRowIndex++;
|
||||
userWorkSheet.Cells[summaryRowIndex, 11].Value2 = "總銷量及金額(外銷)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
userWorkSheet.Cells[summaryRowIndex, quantityColIndex].Value2 = 0;
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
userWorkSheet.Cells[summaryRowIndex, amountColIndex].Value2 = 0;
|
||||
}
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 36].Value2 = 0;
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 37].Value2 = 0;
|
||||
|
||||
summaryRowIndex++;
|
||||
userWorkSheet.Cells[summaryRowIndex, 11].Value2 = "總銷量及金額(內外銷)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
userWorkSheet.Cells[summaryRowIndex, quantityColIndex].formula = $"={quantityColLetter}{summaryRowIndex - 3}+{quantityColLetter}{summaryRowIndex - 1}";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
userWorkSheet.Cells[summaryRowIndex, amountColIndex].formula = $"={amountColLetter}{summaryRowIndex - 3}+{amountColLetter}{summaryRowIndex - 1}";
|
||||
}
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 36].formula = $"={totalQuantityColLetter}{summaryRowIndex - 3}+{totalQuantityColLetter}{summaryRowIndex - 1}";
|
||||
userWorkSheet.Cells[summaryRowIndex, sumColStart + 37].formula = $"={totalAmountColLetter}{summaryRowIndex - 3}+{totalAmountColLetter}{summaryRowIndex - 1}";
|
||||
|
||||
// 下一年的index
|
||||
sumColStart += 38;
|
||||
summaryRowIndex = summaryRowStartIndex;
|
||||
} while (sumColStart < lastColumnIndex);
|
||||
}
|
||||
|
||||
private static void GenSalesTotal(ImportContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
var totalWorksheet = CreateSheetIfNotExisted(app, "JQ Total(Total)");
|
||||
|
||||
PrepareTotalHeader(totalWorksheet);
|
||||
PrepareTotalHeader(totalWorksheet, context);
|
||||
// 删除现有数据
|
||||
int totalRowIndex = 4;
|
||||
int lastRowIndex = totalWorksheet.UsedRange.Rows.Count;
|
||||
if (lastRowIndex > totalRowIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
totalWorksheet.Application.DisplayAlerts = false;
|
||||
var deleteRows = totalWorksheet.Rows[$"{totalRowIndex}:{lastRowIndex}"];
|
||||
deleteRows.UnMerge();
|
||||
deleteRows.EntireRow.Delete(XlDeleteShiftDirection.xlShiftUp);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine("delete error %s", ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
totalWorksheet.Application.DisplayAlerts = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var userSheet in context.SalesWorksheets)
|
||||
{
|
||||
Range usedRange = userSheet.UsedRange;
|
||||
int rowIndexStart = 4;
|
||||
int rowIndexEnd = usedRange.Rows.Count;
|
||||
int rowIndexEnd = usedRange.Rows.Count - 5;
|
||||
|
||||
int rowCount = rowIndexEnd - rowIndexStart + 1;
|
||||
int rowCount = rowIndexEnd - rowIndexStart;
|
||||
if (rowCount > 1)
|
||||
{
|
||||
Range sourceRange = userSheet.Range[
|
||||
@ -148,78 +243,17 @@ namespace KellyReport_D.Utils
|
||||
totalWorksheet.Cells[totalRowIndexEnd, usedRange.Columns.Count]
|
||||
];
|
||||
sourceRange.Copy(targetRange);
|
||||
totalRowIndex = totalRowIndexEnd;
|
||||
totalRowIndex = totalRowIndexEnd + 1;
|
||||
}
|
||||
}
|
||||
|
||||
totalWorksheet.Cells[totalRowIndex, 1].Value = "總結";
|
||||
var sumRange = totalWorksheet.Range[
|
||||
totalWorksheet.Cells[totalRowIndex, 1],
|
||||
totalWorksheet.Cells[totalRowIndex + 4, 5]
|
||||
totalWorksheet.Cells[totalRowIndex + 3, 5]
|
||||
];
|
||||
sumRange.Merge();
|
||||
|
||||
int sumColStart = 13; // L列是第12列
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(未稅)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].formula = $"=(SUM({quantityColLetter}4:{quantityColLetter}{totalRowIndex - 1})/2)";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].formula = $"=((SUM({amountColLetter}4:{amountColLetter}{totalRowIndex - 1})/2) - {amountColLetter}{totalRowIndex + 2})/1.13";
|
||||
}
|
||||
string totalQuantityColLetter = GetColumnLetter(49);
|
||||
string totalAmountColLetter = GetColumnLetter(50);
|
||||
|
||||
totalWorksheet.Cells[totalRowIndex, 49].formula = $"=(SUM({totalQuantityColLetter}4:{totalAmountColLetter}{totalRowIndex - 1})/2)";
|
||||
totalWorksheet.Cells[totalRowIndex, 50].formula = $"=((SUM({totalAmountColLetter}4:{totalAmountColLetter}{totalRowIndex - 1})/2) - {totalAmountColLetter}{totalRowIndex + 2})/1.13";
|
||||
|
||||
|
||||
totalRowIndex++;
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(含稅)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].formula = $"=(SUM({quantityColLetter}4:{quantityColLetter}{totalRowIndex - 1})/2)";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].formula = $"=(SUM({amountColLetter}4:{amountColLetter}{totalRowIndex - 1})/2)";
|
||||
}
|
||||
totalWorksheet.Cells[totalRowIndex, 49].formula = $"=(SUM({totalQuantityColLetter}4:{totalQuantityColLetter}{totalRowIndex - 1})/2)";
|
||||
totalWorksheet.Cells[totalRowIndex, 50].formula = $"=(SUM({totalAmountColLetter}4:{totalAmountColLetter}{totalRowIndex - 1})/2)";
|
||||
|
||||
totalRowIndex++;
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(外銷)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].Value2 = 0;
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].Value2 = 0;
|
||||
}
|
||||
totalWorksheet.Cells[totalRowIndex, 49].Value2 = 0;
|
||||
totalWorksheet.Cells[totalRowIndex, 50].Value2 = 0;
|
||||
|
||||
totalRowIndex++;
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(內外銷)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].formula = $"={quantityColLetter}{totalRowIndex - 3}+{quantityColLetter}{totalRowIndex - 1}";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].formula = $"={amountColLetter}{totalRowIndex - 3}+{amountColLetter}{totalRowIndex - 1}";
|
||||
}
|
||||
totalWorksheet.Cells[totalRowIndex, 49].formula = $"={totalQuantityColLetter}{totalRowIndex - 3}+{totalQuantityColLetter}{totalRowIndex - 1}";
|
||||
totalWorksheet.Cells[totalRowIndex, 50].formula = $"={totalAmountColLetter}{totalRowIndex - 3}+{totalAmountColLetter}{totalRowIndex - 1}";
|
||||
UpdateSalesDetailSummary(totalWorksheet, totalRowIndex);
|
||||
|
||||
// 自适应所有已用列宽
|
||||
FormatSheetStyle(totalWorksheet);
|
||||
@ -256,16 +290,67 @@ namespace KellyReport_D.Utils
|
||||
return colLetter;
|
||||
}
|
||||
|
||||
public static int FindRowBySalesAndClient(Worksheet userSheet, string salesName, string clientName)
|
||||
{
|
||||
Range salesRows = userSheet.Columns[1];
|
||||
Range found = salesRows.Find(What: salesName, LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
if (found == null)
|
||||
return 0;
|
||||
|
||||
string firstAddress = found?.Address;
|
||||
Range cur = found;
|
||||
int result = 0;
|
||||
do
|
||||
{
|
||||
var rIndex = cur.Row;
|
||||
Range eCell = userSheet.Cells[rIndex, 5];
|
||||
var rawValue = eCell.Value2;
|
||||
if (rawValue != null && string.Equals(rawValue.ToString().Trim(), clientName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result = cur.Row;
|
||||
break;
|
||||
}
|
||||
|
||||
cur = salesRows.FindNext(cur);
|
||||
} while (cur != null && cur.Address != firstAddress);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void WriteSalesDetailsData(
|
||||
ImportContext context,
|
||||
ImportContext.GroupedSalesDetailModel userGroupedSalesDetail,
|
||||
Worksheet userSheet
|
||||
)
|
||||
Worksheet userSheet,
|
||||
int yearColIndex)
|
||||
{
|
||||
int rowIndex = 4; // 从第四行开始写入数据
|
||||
var detailSummaryRow = userSheet.UsedRange.Find(What: "總結", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
int summaryRowIndex = userSheet.UsedRange.Rows.Count; // 从第四行开始写入数据
|
||||
bool hasSummary = detailSummaryRow != null;
|
||||
if (hasSummary)
|
||||
{
|
||||
summaryRowIndex = detailSummaryRow.Row;
|
||||
}
|
||||
|
||||
var clientSalesList = context.GetGroupedSalesDetailByClientName(userGroupedSalesDetail.Details);
|
||||
|
||||
foreach (var clientSalesDetail in clientSalesList)
|
||||
{
|
||||
var clientSalesRowIndex = FindRowBySalesAndClient(userSheet, clientSalesDetail.SalesName, clientSalesDetail.ClientName);
|
||||
if (clientSalesRowIndex == 0)
|
||||
{
|
||||
clientSalesRowIndex = summaryRowIndex;
|
||||
if (hasSummary)
|
||||
{
|
||||
userSheet.Rows[clientSalesRowIndex].Insert(XlInsertShiftDirection.xlShiftDown);
|
||||
summaryRowIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
clientSalesRowIndex++;
|
||||
summaryRowIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
ClientContact clientContact = context.ClientContactList.FirstOrDefault(x => x.Name == clientSalesDetail.ClientName) ?? new ClientContact
|
||||
{
|
||||
Name = clientSalesDetail.ClientName,
|
||||
@ -281,9 +366,30 @@ namespace KellyReport_D.Utils
|
||||
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
|
||||
Quantity = grouped.Sum(x => x.Quantity ?? 0),
|
||||
Details = grouped.ToList()
|
||||
});
|
||||
rowIndex = WriteSalesDetailToSheet(userSheet, rowIndex, clientContact, productSalesList);
|
||||
}).ToList();
|
||||
|
||||
Range salesNameCell = userSheet.Cells[clientSalesRowIndex, 1];
|
||||
int curRowCount = 1;
|
||||
int clientSalesRowCount = productSalesList.Count + 1;
|
||||
if (salesNameCell.MergeCells)
|
||||
{
|
||||
Range mergedCell = salesNameCell.MergeArea;
|
||||
curRowCount = mergedCell.Rows.Count;
|
||||
}
|
||||
// 添加行数
|
||||
if (curRowCount < clientSalesRowCount)
|
||||
{
|
||||
for (var i = 0; i < clientSalesRowCount - curRowCount; i++)
|
||||
{
|
||||
userSheet.Rows[clientSalesRowIndex + curRowCount].Insert(XlInsertShiftDirection.xlShiftDown);
|
||||
summaryRowIndex++;
|
||||
}
|
||||
}
|
||||
salesNameCell.Value2 = clientSalesDetail.SalesName;
|
||||
int totalRowIndex = clientSalesRowIndex + clientSalesRowCount - 1;
|
||||
userSheet.Range[userSheet.Cells[clientSalesRowIndex, 1], userSheet.Cells[totalRowIndex, 1]].Merge();
|
||||
|
||||
WriteSalesDetailToSheet(userSheet, clientSalesRowIndex, yearColIndex, clientContact, productSalesList);
|
||||
// 客户销量汇总
|
||||
var totalSales = new List<ImportContext.GroupedSalesDetailModel>()
|
||||
{
|
||||
@ -325,20 +431,33 @@ namespace KellyReport_D.Utils
|
||||
}
|
||||
};
|
||||
|
||||
rowIndex = WriteSalesDetailToSheet(userSheet, rowIndex, clientContact, totalSales);
|
||||
WriteSalesDetailToSheet(userSheet, totalRowIndex, yearColIndex, clientContact, totalSales);
|
||||
}
|
||||
|
||||
// 计算总结
|
||||
if (!hasSummary)
|
||||
{
|
||||
summaryRowIndex++;
|
||||
}
|
||||
userSheet.Cells[summaryRowIndex, 1].Value = "總結";
|
||||
var sumRange = userSheet.Range[
|
||||
userSheet.Cells[summaryRowIndex, 1],
|
||||
userSheet.Cells[summaryRowIndex + 3, 5]
|
||||
];
|
||||
sumRange.Merge();
|
||||
UpdateSalesDetailSummary(userSheet, summaryRowIndex);
|
||||
|
||||
FormatSheetStyle(userSheet);
|
||||
|
||||
userSheet.Cells[4, 12].Select();
|
||||
userSheet.Application.ActiveWindow.FreezePanes = true;
|
||||
}
|
||||
|
||||
private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList)
|
||||
private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, int yearColIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList)
|
||||
{
|
||||
foreach (var productSalesDetail in salesDetailList)
|
||||
{
|
||||
userSheet.Cells[rowIndex, 1].Value2 = productSalesDetail.SalesName;
|
||||
//userSheet.Cells[rowIndex, 1].Value2 = productSalesDetail.SalesName;
|
||||
userSheet.Cells[rowIndex, 2].Value2 = clientContact.Region;
|
||||
userSheet.Cells[rowIndex, 3].Value2 = clientContact.Industry;
|
||||
userSheet.Cells[rowIndex, 4].Value2 = clientContact.AnnualCapacity;
|
||||
@ -351,7 +470,7 @@ namespace KellyReport_D.Utils
|
||||
userSheet.Cells[rowIndex, 11].Value2 = productSalesDetail.ProductNameEN;
|
||||
|
||||
// 计算每月的数量和金额
|
||||
int monthCol = 13; // L列是第12列
|
||||
int monthCol = yearColIndex;
|
||||
for (int i = 1; i < 13; i++)
|
||||
{
|
||||
int monthCounter = 0;
|
||||
@ -373,6 +492,7 @@ namespace KellyReport_D.Utils
|
||||
|
||||
return accSalesModel;
|
||||
});
|
||||
|
||||
if (monthCounter > 1)
|
||||
{
|
||||
monthDetail.PriceWithTax = monthDetail.PriceWithTax / monthCounter;
|
||||
@ -394,14 +514,13 @@ namespace KellyReport_D.Utils
|
||||
userSheet.Cells[rowIndex, 49].Value = productSalesDetail.Quantity;
|
||||
userSheet.Cells[rowIndex, 50].Value = productSalesDetail.TotalAmount;
|
||||
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
public static void PrepareTotalHeader(Worksheet userSheet)
|
||||
public static int PrepareTotalHeader(Worksheet userSheet, ImportContext importContext)
|
||||
{
|
||||
// 合并A1:L1并设置标题
|
||||
userSheet.Range["A1", "L1"].Merge();
|
||||
@ -434,11 +553,26 @@ namespace KellyReport_D.Utils
|
||||
userSheet.Range["L2"].Value2 = "需求/月";
|
||||
|
||||
// 计算起始列(L列后面,列号13)
|
||||
int year = importContext.YearList[0];
|
||||
string yearTitle = $"{year}销售表";
|
||||
int startCol = 13;
|
||||
|
||||
Range yearCol = userSheet.Rows[1].Find(What: yearTitle, LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
if (yearCol != null)
|
||||
{
|
||||
// 已经存在年度销售数据,不需处理
|
||||
return yearCol.Column;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 38; i++)
|
||||
{
|
||||
userSheet.Columns[13].EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
|
||||
}
|
||||
|
||||
// 合并年度销售表标题
|
||||
userSheet.Range[userSheet.Cells[1, startCol], userSheet.Cells[1, startCol + 37]].Merge();
|
||||
userSheet.Cells[1, startCol].Value2 = "年度销售表";
|
||||
userSheet.Cells[1, startCol].Value2 = yearTitle;
|
||||
|
||||
// 设置月份表头
|
||||
for (int i = 0; i < 12; i++)
|
||||
@ -460,6 +594,8 @@ namespace KellyReport_D.Utils
|
||||
// 设置所有已用单元格居中
|
||||
Range usedRange = userSheet.UsedRange;
|
||||
usedRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
|
||||
|
||||
return startCol;
|
||||
}
|
||||
|
||||
|
||||
@ -472,11 +608,6 @@ namespace KellyReport_D.Utils
|
||||
var salesName = groupedSalesDetail.SalesName ?? "UNKONW";
|
||||
string sheetName = $"JQ Total({salesName.ToUpper()})";
|
||||
Worksheet userSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
Range usedRange = userSheet.UsedRange;
|
||||
if (usedRange != null && usedRange.Cells.Count > 1)
|
||||
{
|
||||
usedRange.Clear();
|
||||
}
|
||||
|
||||
return userSheet;
|
||||
}
|
||||
@ -491,7 +622,8 @@ namespace KellyReport_D.Utils
|
||||
userSheet = item;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
if (userSheet == null)
|
||||
{
|
||||
@ -509,6 +641,28 @@ namespace KellyReport_D.Utils
|
||||
|
||||
return userSheet;
|
||||
}
|
||||
public static DateTime? ResolveExcelDate(object rawValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rawValue is double dateValue)
|
||||
{
|
||||
return DateTime.FromOADate(dateValue);
|
||||
}
|
||||
else if (rawValue != null)
|
||||
{
|
||||
return DateTime.Parse(rawValue.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine("parse date error:" + ex.Message);
|
||||
//throw new FormatException($"日期格式错误 '{rawValue}'");
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private static void ReadSalesDetails(ImportContext context)
|
||||
{
|
||||
@ -526,9 +680,9 @@ namespace KellyReport_D.Utils
|
||||
{
|
||||
SalesName = rawSalesDetailData[i, 1]?.ToString() ?? "UNKNOWN",
|
||||
Month = rawSalesDetailData[i, 2]?.ToString() ?? "",
|
||||
DeliveryDate = rawSalesDetailData[i, 3] is double invoiceDate ? DateTime.FromOADate(invoiceDate) : (DateTime?)null,
|
||||
DeliveryDate = ResolveExcelDate(rawSalesDetailData[i, 3]),
|
||||
OrderNumber = rawSalesDetailData[i, 4]?.ToString() ?? "",
|
||||
InvoiceDate = rawSalesDetailData[i, 5] != null ? DateTime.Parse(rawSalesDetailData[i, 5]?.ToString()) : (DateTime?)null,
|
||||
InvoiceDate = ResolveExcelDate(rawSalesDetailData[i, 5]),
|
||||
InvoiceNumber = rawSalesDetailData[i, 6]?.ToString() ?? "",
|
||||
ClientName = rawSalesDetailData[i, 7]?.ToString() ?? "",
|
||||
ProductNameEN = rawSalesDetailData[i, 8]?.ToString() ?? "",
|
||||
@ -543,6 +697,10 @@ namespace KellyReport_D.Utils
|
||||
}
|
||||
}
|
||||
context.SalesDetails = salesDatailList;
|
||||
if (context.YearList.Count > 1)
|
||||
{
|
||||
throw new Exception("抱歉,匯入的銷售資料格式有誤,每次只能處理同一個自然年的資料。");
|
||||
}
|
||||
}
|
||||
|
||||
public static Workbook SelectAndOpenExcelFile()
|
||||
@ -600,33 +758,57 @@ namespace KellyReport_D.Utils
|
||||
public static void GenBussenessSheet(GenForecaseContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
Worksheet sheet = CreateSheetIfNotExisted(app, "業務月達成率");
|
||||
|
||||
// 假设 app 是 Excel.Application
|
||||
Worksheet sheet = null;
|
||||
string sheetName = "業務月達成率";
|
||||
Range usedRange = sheet.UsedRange;
|
||||
int totalRows = usedRange?.Rows?.Count ?? 0;
|
||||
int yearRowIndex = 1;
|
||||
Boolean updateCurrentBook = false;
|
||||
while (yearRowIndex < totalRows - 1)
|
||||
{
|
||||
object rawYearValue = sheet.Cells[yearRowIndex, 1]?.Value2;
|
||||
if (rawYearValue == null)
|
||||
{
|
||||
throw new Exception($"更新業務月達成率年份异常");
|
||||
}
|
||||
string yearValue = "";
|
||||
if (rawYearValue is double d)
|
||||
{
|
||||
yearValue = (rawYearValue).ToString();
|
||||
}
|
||||
|
||||
if (yearValue == context.MonthData[0])
|
||||
{
|
||||
updateCurrentBook = true;
|
||||
break;
|
||||
}
|
||||
|
||||
yearRowIndex += 15;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 新增工作表
|
||||
sheet = app.Worksheets.Add();
|
||||
sheet.Name = sheetName;
|
||||
string rowRanges = "";
|
||||
if (updateCurrentBook)
|
||||
{
|
||||
rowRanges = $"{yearRowIndex}:{yearRowIndex + 14}";
|
||||
Range updateRows = sheet.Rows[rowRanges];
|
||||
updateRows.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
yearRowIndex = 1;
|
||||
rowRanges = "1:15";
|
||||
Range newRows = sheet.Rows[rowRanges];
|
||||
newRows.Insert(XlInsertShiftDirection.xlShiftDown);
|
||||
}
|
||||
// 插入后重新获取引用并清除新行格式
|
||||
Range targetRows = sheet.Rows[rowRanges];
|
||||
targetRows.ClearFormats();
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 已存在则获取
|
||||
sheet = app.Worksheets[sheetName] as Worksheet;
|
||||
try
|
||||
{
|
||||
Range usedRange = sheet.UsedRange;
|
||||
if (usedRange != null && usedRange.Cells.Count > 1)
|
||||
{
|
||||
usedRange.Clear();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 无 UsedRange 可忽略
|
||||
}
|
||||
throw new Exception($"更新{context.MonthData[0]}年業務月達成率失败", ex);
|
||||
}
|
||||
|
||||
// 合并A1:A2并填入年份
|
||||
@ -634,12 +816,12 @@ namespace KellyReport_D.Utils
|
||||
{
|
||||
var monthData = context.MonthData;
|
||||
var yearValue = monthData[0];
|
||||
Range yearRange = sheet.Range["A1", "A2"];
|
||||
Range yearRange = sheet.Range[$"A{yearRowIndex}", $"A{yearRowIndex + 1}"];
|
||||
yearRange.Merge();
|
||||
yearRange.Value2 = yearValue.ToString();
|
||||
yearRange.NumberFormat = "@"; // 文本格式
|
||||
|
||||
int startRowIndex = 1;
|
||||
int startRowIndex = yearRowIndex;
|
||||
// 填入月份
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
@ -717,7 +899,6 @@ namespace KellyReport_D.Utils
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void ReadClientContact(ImportContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
@ -837,6 +1018,10 @@ namespace KellyReport_D.Utils
|
||||
Total = rawSalesData[i, 14] != null ? Convert.ToDecimal(rawSalesData[i, 14]) : 0,
|
||||
};
|
||||
salesForecastInputList.Add(input);
|
||||
|
||||
// 只读取第一段的数据
|
||||
if (input.Name == "total")
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -852,13 +1037,7 @@ namespace KellyReport_D.Utils
|
||||
Worksheet productSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
productSheet.Activate();
|
||||
|
||||
var yearList = context.SalesDetails
|
||||
.Where(x => x.InvoiceDate.HasValue)
|
||||
.Select(x => x.InvoiceDate.Value.Year)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
yearList.ForEach(yearNumber =>
|
||||
context.YearList.ForEach(yearNumber =>
|
||||
{
|
||||
Range usedRange = productSheet.UsedRange;
|
||||
|
||||
@ -1020,6 +1199,13 @@ namespace KellyReport_D.Utils
|
||||
var startColLetter = GetColumnLetter(startCol);
|
||||
var endColLetter = GetColumnLetter(startCol + 3);
|
||||
|
||||
if (curYearRange == null)
|
||||
{
|
||||
deptSheet.Range[$"{startColLetter}:{endColLetter}"]
|
||||
.EntireColumn
|
||||
.Insert(XlInsertShiftDirection.xlShiftToRight);
|
||||
}
|
||||
|
||||
Range prevYearRange = deptSheet.UsedRange.Find(What: $"{yearNumber - 1}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
int prevStartCol = 0;
|
||||
string prevForecastColLetter = "";
|
||||
@ -1031,11 +1217,7 @@ namespace KellyReport_D.Utils
|
||||
prevTurnoverColLetter = GetColumnLetter(prevStartCol + 1);
|
||||
}
|
||||
|
||||
deptSheet.Range[$"{startColLetter}:{endColLetter}"]
|
||||
.EntireColumn
|
||||
.Insert(XlInsertShiftDirection.xlShiftToRight);
|
||||
|
||||
deptSheet.Cells[1, 2].Value2 = $"{yearNumber}";
|
||||
deptSheet.Cells[1, startCol].Value2 = $"{yearNumber}";
|
||||
deptSheet.Range[deptSheet.Cells[1, startCol], deptSheet.Cells[1, startCol + 3]].Merge();
|
||||
|
||||
deptSheet.Cells[2, startCol].Value2 = "Forecast";
|
||||
@ -1095,9 +1277,7 @@ namespace KellyReport_D.Utils
|
||||
Worksheet deptSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
deptSheet.Activate();
|
||||
|
||||
var yearList = context.SalesDetails.Where(x => x.InvoiceDate.HasValue).Select(x => x.InvoiceDate.Value.Year).Distinct().ToList();
|
||||
|
||||
yearList.ForEach(yearoNumber =>
|
||||
context.YearList.ForEach(yearoNumber =>
|
||||
{
|
||||
Range yearRange = deptSheet.UsedRange.Find(What: $"{yearoNumber}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user