using System; using System.Collections.Generic; using System.Reflection; namespace bdf { public class Row //Generic Type 2 { public Int32 Row_Number { get; set; } = 1; public Int32 Record_Type { get; set; } = 2; public Int32 Contractor_Billing_Account_Number { get; set; } = 0; // This will change for each service type public String Invoice_Number { get; set; } = "INV X"; public Int32 Invoice_Period { get; set; } = 0; public String Canada_Contract_Identifier { get; set; } = "X"; public String Contractor { get; set; } = "ROGERS"; public Int32 SSC_Order_Number { get; set; } = 0; public Int32 SSC_Version { get; set; } = 0; public Int32 SSC_Seq_No { get; set; } = 1; public String SDPID { get; set; } = "X"; public String Department { get; set; } = "X"; public String Prov { get; set; } = "X"; public String Service_Project_ID { get; set; } = ""; public Int32 Billing_Effective_Date { get; set; } = 0; public Int32 Billing_End_Date { get; set; } = 0; public Int32 Billing_Cancel_Date { get; set; } = 0; public Int32 Period_of_Service { get; set; } = 0; public String SCID { get; set; } = "X"; public Int32 Quantity { get; set; } = 1; public Double Recurring_Charges_for_the_Month { get; set; } = 0; public Double Total_Recurring_Charges_for_the_Month { get; set; } = 0; public Double Non_recurring_Charges_for_the_Month { get; set; } = 0; public Double Total_Non_recurring_Charges_for_the_Month { get; set; } = 0; public Double Total_Service_Credits { get; set; } = 0; public Double Total_Other_Charges_and_Credits { get; set; } = 0; public Double Total_GST_Amount { get; set; } = 0; //public Double Total_PST_Amount { get; set; } = 0; public Double Total_HST_Amount { get; set; } = 0; public Double Total_QST_Amount { get; set; } = 0; // to be used for both PST and QST per call with Diana Aboud Feb 9, 2026 public Double Total_Taxes { get; set; } = 0; public Double Total_Amount_including_taxes { get; set; } = 0; public String CI_Name { get; set; } = "X"; public String CI_Name_2 { get; set; } = ""; public String TCID { get; set; } = "X"; public String PO_Number { get; set; } = ""; public String TA_Number { get; set; } = "X"; //var copy = original.Clone(); public T Clone() where T : class { return (T)this.MemberwiseClone(); } } public class Row2 // Generic Type 1 { public Int32 Record_Type { get; set; } = 1; public Int32 Invoice_Date { get; set; } = 0; public Int32 Invoice_Period { get; set; } = 0; public String Canada_Contract_Identifier { get; set; } = "X"; public String Contractor_Name { get; set; } = "X"; public Int32 Total_Recurring_Charges_for_the_Month { get; set; } = 0; public Int32 Total_Non_Recurring_Charges_for_the_Month { get; set; } = 0; public Int32 Total_Charges_Excluding_Taxes { get; set; } = 0; public Int32 Total_Other_Charges_and_Credits { get; set; } = 0; public Int32 Total_Service_Credits { get; set; } = 0; public Int32 Total_Late_Payment_Amount { get; set; } = 0; public Int32 Total_GST_Amount { get; set; } = 0; //public Int32 Total_PST_Amount { get; set; } = 0; public Int32 Total_HST_Amount { get; set; } = 0; public Int32 Total_QST_Amount { get; set; } = 0; public Int32 Total_Taxes { get; set; } = 0; public Int32 Total_Amount_Including_Taxes { get; set; } = 0; public Int32 Total_Usage_Charges { get; set; } = 0; // Added because of SIP } public class Row3 // SIP Type 3 { public Int32 Line_Number { get; set; } = 1; public Int32 Record_Type { get; set; } = 0; public Int32 Contractor_Billling_Account_Number { get; set; } = 0; public Int32 Invoice_Number { get; set; } = 0; public Int32 Invoice_Period { get; set; } = 0; public String Canada_Contract_Identifier { get; set; } = "X"; public String Contractor { get; set; } = "X"; public String Period_of_Service { get; set; } = "X"; public String Department { get; set; } = "X"; public String SCID { get; set; } = "X"; public Int32 Total_Usage_Charges_for_the_Month { get; set; } = 0; public Int32 Total_Other_Charges_and_Credits { get; set; } = 0; public Int32 Total_GST_Amount { get; set; } = 0; //public Int32 Total_PST_Amount { get; set; } = 0; public Int32 Total_HST_Amount { get; set; } = 0; public Int32 Total_QST_Amount { get; set; } = 0; public Int32 Total_Taxes { get; set; } = 0; public Int32 Total_Amount_Including_Taxes { get; set; } = 0; public String PO_Number { get; set; } = "X"; } public class BDF { public static Spire.Xls.Workbook CreateBDF(string type) { if (type == "LDF" || type == "WAV") return S_CreateBDF(); else if (type == "SIP") return S_CreateBDFSIP(); else return null; } public static Spire.Xls.Workbook S_CreateBDFSIP() { var workbook = new Spire.Xls.Workbook(); var worksheet1 = workbook.Worksheets.Add("BDF Type 1"); cleanSheets(ref workbook); { //Headers "SIP BDF Type 1" worksheet1.Range[1, 1].Value = "Record Type"; worksheet1.Range[1, 2].Value = "Invoice Date"; worksheet1.Range[1, 3].Value = "Invoice Period"; worksheet1.Range[1, 4].Value = "Canada Contract Identifier"; worksheet1.Range[1, 5].Value = "Contractor"; worksheet1.Range[1, 6].Value = "Total Recurring Charges for the Month"; worksheet1.Range[1, 7].Value = "Total Non-Recurring Charges for the Month"; worksheet1.Range[1, 8].Value = "Total Charges Excluding Taxes"; worksheet1.Range[1, 9].Value = "Total Other Charges and Credits"; worksheet1.Range[1, 10].Value = "Total Service Credits"; worksheet1.Range[1, 11].Value = "Total Late Payment Amount"; worksheet1.Range[1, 12].Value = "Total GST Amount"; worksheet1.Range[1, 13].Value = "Total HST Amount"; worksheet1.Range[1, 14].Value = "Total QST Amount"; worksheet1.Range[1, 15].Value = "Total Taxes"; worksheet1.Range[1, 16].Value = "Total Amount Including Taxes"; worksheet1.Range[1, 17].Value = "Total Usage Charges"; // this line was the only delta var worksheet2 = workbook.Worksheets.Add("BDF Type 2"); //Headers "BDF Type 2" worksheet2.Range[1, 1].Value = "Line Number"; //slight change worksheet2.Range[1, 2].Value = "Record Type"; worksheet2.Range[1, 3].Value = "Contractor Billing Account Number"; worksheet2.Range[1, 4].Value = "Invoice Number"; worksheet2.Range[1, 5].Value = "Invoice Period"; worksheet2.Range[1, 6].Value = "Canada Contract Identifier"; worksheet2.Range[1, 7].Value = "Contractor"; worksheet2.Range[1, 8].Value = "SSC Reference Number"; //slight change worksheet2.Range[1, 9].Value = "SSC Version"; worksheet2.Range[1, 10].Value = "SSC Seq No"; worksheet2.Range[1, 11].Value = "SDPID"; worksheet2.Range[1, 12].Value = "Department"; worksheet2.Range[1, 13].Value = "Prov"; worksheet2.Range[1, 14].Value = "Service Project ID"; worksheet2.Range[1, 15].Value = "Billing Effective Date"; worksheet2.Range[1, 16].Value = "Billing End Date"; worksheet2.Range[1, 17].Value = "Billing Cancel Date"; worksheet2.Range[1, 18].Value = "Period of Service"; worksheet2.Range[1, 19].Value = "SCID"; worksheet2.Range[1, 20].Value = "Qty"; //slight change worksheet2.Range[1, 21].Value = "Recurring Charges for the Month"; worksheet2.Range[1, 22].Value = "Total Recurring Charges for the Month"; worksheet2.Range[1, 23].Value = "Non-recurring Charges for the Month"; worksheet2.Range[1, 24].Value = "Total Non-recurring Charges for the Month"; worksheet2.Range[1, 25].Value = "Total Service Credits"; worksheet2.Range[1, 26].Value = "Total Other Charges and Credits"; worksheet2.Range[1, 27].Value = "Total GST Amount"; worksheet2.Range[1, 28].Value = "Total HST Amount"; worksheet2.Range[1, 29].Value = "Total QST Amount"; worksheet2.Range[1, 30].Value = "Total Taxes"; worksheet2.Range[1, 31].Value = "Total Amount including taxes"; worksheet2.Range[1, 32].Value = "CI Name"; worksheet2.Range[1, 33].Value = "CI Name 2"; worksheet2.Range[1, 34].Value = "TCID"; worksheet2.Range[1, 35].Value = "PO #"; //slight change // worksheet2.Range[1, 36].Value = "TA Number"; //this line removed for SIP-2 var worksheet3 = workbook.Worksheets.Add("BDF Type 3"); //Headers "SIP BDF Type 3" worksheet3.Range[1, 1].Value = "Line Number"; worksheet3.Range[1, 2].Value = "Record Type"; worksheet3.Range[1, 3].Value = "Contractor Billing Account Number"; worksheet3.Range[1, 4].Value = "Invoice Number"; worksheet3.Range[1, 5].Value = "Invoice Period"; worksheet3.Range[1, 6].Value = "Canada Contract Identifier"; worksheet3.Range[1, 7].Value = "Contractor"; worksheet3.Range[1, 8].Value = "Period of Service"; worksheet3.Range[1, 9].Value = "Department"; worksheet3.Range[1, 10].Value = "SCID"; worksheet3.Range[1, 11].Value = "Total Usage Charges for the Month"; worksheet3.Range[1, 12].Value = "Total Other Charges and Credits"; worksheet3.Range[1, 13].Value = "Total GST Amount"; worksheet3.Range[1, 14].Value = "Total HST Amount"; worksheet3.Range[1, 15].Value = "Total QST Amount"; worksheet3.Range[1, 16].Value = "Total Taxes"; worksheet3.Range[1, 17].Value = "Total Amount including taxes"; worksheet3.Range[1, 18].Value = "PO Number"; } Logger.Log(0, "Excel BDF template file created! {0}", bdf.output_path + bdf.filename); return workbook; } public static Spire.Xls.Workbook S_CreateBDF() { var workbook = new Spire.Xls.Workbook(); var worksheet1 = workbook.Worksheets.Add("BDF Type 1"); cleanSheets(ref workbook); { //Headers "BDF Type 1" worksheet1.Range[1, 1].Value = "Record Type"; worksheet1.Range[1, 2].Value = "Invoice Date"; worksheet1.Range[1, 3].Value = "Invoice Period"; worksheet1.Range[1, 4].Value = "Canada Contract Identifier"; worksheet1.Range[1, 5].Value = "Contractor Name"; worksheet1.Range[1, 6].Value = "Total Recurring Charges for the Month"; worksheet1.Range[1, 7].Value = "Total Non-Recurring Charges for the Month"; worksheet1.Range[1, 8].Value = "Total Charges Excluding Taxes"; worksheet1.Range[1, 9].Value = "Total Other Charges and Credits"; worksheet1.Range[1, 10].Value = "Total Service Credits"; worksheet1.Range[1, 11].Value = "Total Late Payment Amount"; worksheet1.Range[1, 12].Value = "Total GST Amount"; worksheet1.Range[1, 13].Value = "Total HST Amount"; worksheet1.Range[1, 14].Value = "Total QST Amount"; worksheet1.Range[1, 15].Value = "Total Taxes"; worksheet1.Range[1, 16].Value = "Total Amount Including Taxes"; var worksheet2 = workbook.Worksheets.Add("BDF Type 2"); //Headers "BDF Type 2" worksheet2.Range[1, 1].Value = "Row Number"; worksheet2.Range[1, 2].Value = "Record Type"; worksheet2.Range[1, 3].Value = "Contractor Billing Account Number"; worksheet2.Range[1, 4].Value = "Invoice Number"; worksheet2.Range[1, 5].Value = "Invoice Period"; worksheet2.Range[1, 6].Value = "Canada Contract Identifier"; worksheet2.Range[1, 7].Value = "Contractor"; worksheet2.Range[1, 8].Value = "SSC Order Number"; worksheet2.Range[1, 9].Value = "SSC Version"; worksheet2.Range[1, 10].Value = "SSC Seq No"; worksheet2.Range[1, 11].Value = "SDPID"; worksheet2.Range[1, 12].Value = "Department"; worksheet2.Range[1, 13].Value = "Prov"; worksheet2.Range[1, 14].Value = "Service Project ID"; worksheet2.Range[1, 15].Value = "Billing Effective Date"; worksheet2.Range[1, 16].Value = "Billing End Date"; worksheet2.Range[1, 17].Value = "Billing Cancel Date"; worksheet2.Range[1, 18].Value = "Period of Service"; worksheet2.Range[1, 19].Value = "SCID"; worksheet2.Range[1, 20].Value = "Quantity"; worksheet2.Range[1, 21].Value = "Recurring Charges for the Month"; worksheet2.Range[1, 22].Value = "Total Recurring Charges for the Month"; worksheet2.Range[1, 23].Value = "Non-recurring Charges for the Month"; worksheet2.Range[1, 24].Value = "Total Non-recurring Charges for the Month"; worksheet2.Range[1, 25].Value = "Total Service Credits"; worksheet2.Range[1, 26].Value = "Total Other Charges and Credits"; worksheet2.Range[1, 27].Value = "Total GST Amount"; worksheet2.Range[1, 28].Value = "Total HST Amount"; worksheet2.Range[1, 29].Value = "Total QST Amount"; worksheet2.Range[1, 30].Value = "Total Taxes"; worksheet2.Range[1, 31].Value = "Total Amount including taxes"; worksheet2.Range[1, 32].Value = "CI Name"; worksheet2.Range[1, 33].Value = "CI Name 2"; worksheet2.Range[1, 34].Value = "TCID"; worksheet2.Range[1, 35].Value = "PO Number"; worksheet2.Range[1, 36].Value = "TA Number"; } Logger.Log(0, "Excel BDF template file created! {0}", bdf.output_path + bdf.filename); return workbook; } public static void S_InsertData(Spire.Xls.Worksheet worksheet, List items) { /// /// Inserts a list of objects (T) into a worksheet with headers. /// Each property becomes a column, each object becomes a row. /// if (worksheet == null) throw new ArgumentNullException(nameof(worksheet)); if (items == null) throw new ArgumentNullException(nameof(items)); if (items.Count == 0) return; // Get properties of T PropertyInfo[] props = typeof(T).GetProperties( BindingFlags.Public | BindingFlags.Instance); // No properties → nothing to insert if (props.Length == 0) return; int startRow = 1; // Header row int startCol = 1; // ----------------------------------------- // Write header row // ----------------------------------------- /* for (int col = 0; col < props.Length; col++) { Spire.Xls.CellRange cell = worksheet.Range[startRow, startCol + col]; cell.Text = props[col].Name; cell.Style.Font.IsBold = true; } */ // ----------------------------------------- // Write data rows // ----------------------------------------- for (int row = 0; row < items.Count; row++) { T item = items[row]; int excelRow = startRow + 1 + row; for (int col = 0; col < props.Length; col++) { Spire.Xls.CellRange cell = worksheet.Range[excelRow, startCol + col]; object value = props[col].GetValue(item); if (value == null) { cell.Text = string.Empty; continue; } // Write numeric values as numbers. either Int32 or Double if ( value is byte || value is short || value is int // || //value is long || value is float || value is double || value is decimal ) { cell.NumberValue = Convert.ToInt32(value); } else if ( //value is byte || value is short || value is int || value is long || value is float || value is double || value is decimal ) { cell.NumberValue = Convert.ToDouble(value); } else { cell.Text = value.ToString(); } } } // Total number of rows written (header + items) int totalRows = 1 + items.Count; int totalCols = props.Length; // ------------------------------------------------------ // Create a table format // ------------------------------------------------------ Spire.Xls.CellRange tableRange = worksheet.Range[startRow, startCol, totalRows, totalCols]; ApplyTableFormat(tableRange); // ------------------------------------------ // Autofit column widths to contents // ------------------------------------------ //worksheet.AllocatedRange.AutoFitColumns(); } /* /// Applies "table-style" formatting to a specified range: /// - Bold gray header row /// - Bordered cells /// - Alternating (banded) row background colors /// Fully compatible with FreeSpire.XLS. /// /// Spire.Xls.CellRange to format /// // Spire.Xls.Worksheet sheet = wb.Worksheets[0]; // Define a range with header + rows // Spire.Xls.CellRange tableRange = sheet.Range["A1:D10"]; // Apply table styling // TableFormatter.ApplyTableFormat(tableRange); */ public static void ApplyTableFormat(Spire.Xls.CellRange range) { if (range == null) throw new System.ArgumentNullException("range"); int rowCount = range.RowCount; int colCount = range.ColumnCount; if (rowCount == 0 || colCount == 0) return; // --------------------------- // 1. Format Header Row // --------------------------- for (int col = 0; col < colCount; col++) { Spire.Xls.CellRange headerCell = range[1, col + 1]; // 1-based indexing inside CellRange segment headerCell.Style.Font.IsBold = true; headerCell.Style.Color = System.Drawing.Color.LightGray; headerCell.Style.Borders.LineStyle = Spire.Xls.LineStyleType.Thin; headerCell.Borders[Spire.Xls.BordersLineType.DiagonalDown].LineStyle = Spire.Xls.LineStyleType.None; headerCell.Borders[Spire.Xls.BordersLineType.DiagonalUp].LineStyle = Spire.Xls.LineStyleType.None; } // --------------------------- // 2. Format Data Rows (banded) // --------------------------- for (int row = 2; row <= rowCount; row++) { bool isEven = (row % 2 == 0); System.Drawing.Color rowColor = isEven ? System.Drawing.Color.FromArgb(245, 245, 245) // light gray band : System.Drawing.Color.White; for (int col = 1; col <= colCount; col++) { Spire.Xls.CellRange cell = range[row, col]; cell.Style.Color = rowColor; cell.Style.Borders.LineStyle = Spire.Xls.LineStyleType.Thin; cell.Borders[Spire.Xls.BordersLineType.DiagonalDown].LineStyle = Spire.Xls.LineStyleType.None; cell.Borders[Spire.Xls.BordersLineType.DiagonalUp].LineStyle = Spire.Xls.LineStyleType.None; } } // --------------------------- // 3. Auto-fit column widths // --------------------------- range.AutoFitColumns(); } public static void cleanSheets(ref Spire.Xls.Workbook workbook) { // Spire worksheets come with 3 default sheets, Sheet1, Sheet2 and Sheet3 // So we pop them off the stack, one at a time, the first time we add our own sheet to the Workbook workbook.Worksheets.RemoveAt(0); workbook.Worksheets.RemoveAt(0); workbook.Worksheets.RemoveAt(0); } } }