Financial model
Build a simple investment analysis with NPV, IRR, and PMT. All financial functions follow Excel semantics exactly.
// typescript
import { createWorkbook, save } from "@mog-sdk/node";
const wb = await createWorkbook();
const ws = wb.getActiveSheet();
// Assumptions
ws.setCell("A1", "Discount Rate"); ws.setCell("B1", 0.08);
ws.setCell("A2", "Initial Outlay"); ws.setCell("B2", -500000);
ws.setCell("A3", "Year 1 CF"); ws.setCell("B3", 120000);
ws.setCell("A4", "Year 2 CF"); ws.setCell("B4", 150000);
ws.setCell("A5", "Year 3 CF"); ws.setCell("B5", 180000);
ws.setCell("A6", "Year 4 CF"); ws.setCell("B6", 200000);
// Analysis
ws.setCell("A8", "NPV");
ws.setCell("B8", "=NPV(B1, B3:B6) + B2");
ws.setCell("A9", "IRR");
ws.setCell("B9", "=IRR(B2:B6)");
ws.setCell("A11", "Equivalent loan payment (5yr, 6%)");
ws.setCell("B11", "=PMT(0.06/12, 60, B2)");
await wb.calculate();
console.log("NPV:", ws.getValue("B8"));
console.log("IRR:", ws.getValue("B9"));
console.log("Monthly PMT:", ws.getValue("B11"));
await save(wb, "financial-model.xlsx");
Data validation
Use COUNTIF, SUMIFS, and conditional logic to validate and summarize data. These patterns are common in data cleaning workflows.
// typescript
import { createWorkbook } from "@mog-sdk/node";
const wb = await createWorkbook();
const ws = wb.getActiveSheet();
// Sample dataset
ws.setCell("A1", "Region"); ws.setCell("B1", "Status"); ws.setCell("C1", "Amount");
ws.setCell("A2", "North"); ws.setCell("B2", "Closed"); ws.setCell("C2", 4500);
ws.setCell("A3", "South"); ws.setCell("B3", "Open"); ws.setCell("C3", 3200);
ws.setCell("A4", "North"); ws.setCell("B4", "Closed"); ws.setCell("C4", 6100);
ws.setCell("A5", "East"); ws.setCell("B5", "Open"); ws.setCell("C5", 2800);
ws.setCell("A6", "North"); ws.setCell("B6", "Closed"); ws.setCell("C6", 5300);
// Validation & summary formulas
ws.setCell("E1", "Closed deals (North)");
ws.setCell("F1", '=COUNTIFS(A2:A6, "North", B2:B6, "Closed")');
ws.setCell("E2", "Revenue (North, Closed)");
ws.setCell("F2", '=SUMIFS(C2:C6, A2:A6, "North", B2:B6, "Closed")');
ws.setCell("E3", "Has open deals?");
ws.setCell("F3", '=IF(COUNTIF(B2:B6, "Open") > 0, "Yes", "No")');
ws.setCell("E4", "Largest deal");
ws.setCell("F4", "=MAX(C2:C6)");
await wb.calculate();
console.log("Closed deals (North):", ws.getValue("F1"));
console.log("Revenue:", ws.getValue("F2"));
console.log("Has open deals?:", ws.getValue("F3"));
console.log("Largest deal:", ws.getValue("F4"));
Lookup tables
Use VLOOKUP and INDEX/MATCH to cross-reference data between tables. INDEX/MATCH is more flexible and handles left-lookups.
// typescript
import { createWorkbook } from "@mog-sdk/node";
const wb = await createWorkbook();
const ws = wb.getActiveSheet();
// Product lookup table
ws.setCell("A1", "SKU"); ws.setCell("B1", "Name"); ws.setCell("C1", "Price");
ws.setCell("A2", "WDG-01"); ws.setCell("B2", "Widget A"); ws.setCell("C2", 29.99);
ws.setCell("A3", "WDG-02"); ws.setCell("B3", "Widget B"); ws.setCell("C3", 49.99);
ws.setCell("A4", "GDG-01"); ws.setCell("B4", "Gadget X"); ws.setCell("C4", 89.99);
ws.setCell("A5", "GDG-02"); ws.setCell("B5", "Gadget Y"); ws.setCell("C5", 119.99);
// VLOOKUP — find price by SKU
ws.setCell("E1", "Lookup SKU");
ws.setCell("F1", "WDG-02");
ws.setCell("E2", "VLOOKUP Price");
ws.setCell("F2", '=VLOOKUP(F1, A2:C5, 3, FALSE)');
// INDEX/MATCH — find SKU by name (left-lookup)
ws.setCell("E4", "Lookup Name");
ws.setCell("F4", "Gadget X");
ws.setCell("E5", "INDEX/MATCH SKU");
ws.setCell("F5", '=INDEX(A2:A5, MATCH(F4, B2:B5, 0))');
// Two-way lookup with INDEX/MATCH
ws.setCell("E7", "Match Result");
ws.setCell("F7", '=INDEX(C2:C5, MATCH("GDG-02", A2:A5, 0))');
await wb.calculate();
console.log("VLOOKUP price:", ws.getValue("F2"));
console.log("INDEX/MATCH SKU:", ws.getValue("F5"));
console.log("Two-way lookup:", ws.getValue("F7"));