#!/bin/bash # Generate a showcase document with beautiful charts # Contains 8 chart types: combo chart, 3D bar, scatter+trendline, 3D pie, bubble, stock OHLC, filled radar, multi-ring doughnut # 4 Sheets: monthly sales, analysis data, stock data, capability assessment # NOTE: intentionally NO `set -e`. Like the SDK twin's doc.batch, this script # tolerates forward-compat 'UNSUPPORTED props' warnings (officecli exit 2) and # keeps building so the full document is produced. XLSX="$(dirname "$0")/charts.xlsx" echo "" echo "==========================================" echo "Generating beautiful charts document: $XLSX" echo "==========================================" rm -f "$XLSX" officecli create "$XLSX" officecli open "$XLSX" ############################################################################### # Sheet1: Monthly sales data ############################################################################### echo " -> Populating Sheet1: Monthly sales data" officecli set "$XLSX" '/Sheet1/A1' --prop value="Month" --prop font.bold=true --prop fill=1F4E79 --prop font.color=FFFFFF --prop font.size=11 --prop alignment.horizontal=center officecli set "$XLSX" '/Sheet1/B1' --prop value="East Sales" --prop font.bold=true --prop fill=2E75B6 --prop font.color=FFFFFF --prop font.size=11 --prop alignment.horizontal=center officecli set "$XLSX" '/Sheet1/C1' --prop value="South Sales" --prop font.bold=true --prop fill=9DC3E6 --prop font.color=1F4E79 --prop font.size=11 --prop alignment.horizontal=center officecli set "$XLSX" '/Sheet1/D1' --prop value="North Sales" --prop font.bold=true --prop fill=BDD7EE --prop font.color=1F4E79 --prop font.size=11 --prop alignment.horizontal=center officecli set "$XLSX" '/Sheet1/E1' --prop value="Total" --prop font.bold=true --prop fill=C55A11 --prop font.color=FFFFFF --prop font.size=11 --prop alignment.horizontal=center officecli set "$XLSX" '/Sheet1/F1' --prop value="YoY Growth %" --prop font.bold=true --prop fill=548235 --prop font.color=FFFFFF --prop font.size=11 --prop alignment.horizontal=center MONTHS=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec") EAST=(120 135 148 162 155 178 195 210 188 172 165 198) SOUTH=(95 108 115 128 142 155 168 175 160 148 135 158) NORTH=(88 92 105 118 125 138 145 152 140 130 122 142) TOTAL=(303 335 368 408 422 471 508 537 488 450 422 498) GROWTH=(5.2 8.1 12.3 15.6 10.2 18.5 22.1 25.3 16.8 11.2 7.5 19.8) for i in $(seq 0 11); do row=$((i + 2)) officecli set "$XLSX" "/Sheet1/A${row}" --prop "value=${MONTHS[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Sheet1/B${row}" --prop "value=${EAST[$i]}" --prop 'numFmt=#,##0' --prop alignment.horizontal=center officecli set "$XLSX" "/Sheet1/C${row}" --prop "value=${SOUTH[$i]}" --prop 'numFmt=#,##0' --prop alignment.horizontal=center officecli set "$XLSX" "/Sheet1/D${row}" --prop "value=${NORTH[$i]}" --prop 'numFmt=#,##0' --prop alignment.horizontal=center officecli set "$XLSX" "/Sheet1/E${row}" --prop "value=${TOTAL[$i]}" --prop 'numFmt=#,##0' --prop font.bold=true --prop alignment.horizontal=center officecli set "$XLSX" "/Sheet1/F${row}" --prop "value=${GROWTH[$i]}" --prop 'numFmt=0.0"%"' --prop alignment.horizontal=center done echo " Done: Sheet1 data" ############################################################################### # Sheet2: Scatter/bubble chart data ############################################################################### echo " -> Populating Sheet2: Analysis data" officecli add "$XLSX" / --type sheet --prop name=Analysis officecli set "$XLSX" '/Analysis/A1' --prop value="Ad Spend (10K)" --prop font.bold=true --prop fill=7030A0 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/Analysis/B1' --prop value="Sales (10K)" --prop font.bold=true --prop fill=7030A0 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/Analysis/C1' --prop value="Margin %" --prop font.bold=true --prop fill=7030A0 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/Analysis/D1' --prop value="Market Share %" --prop font.bold=true --prop fill=7030A0 --prop font.color=FFFFFF --prop alignment.horizontal=center AD_SPEND=(10 15 22 28 35 42 50 58 65 72 80 88 95 105 115) SALES_REV=(45 68 95 120 155 180 220 260 290 335 370 410 445 500 550) PROFIT=(8.5 10.2 12.1 14.5 16.8 15.2 18.3 20.1 19.5 22.3 21.8 24.5 23.1 26.8 28.2) MKT_SHARE=(2.1 3.2 4.5 5.8 7.2 8.5 10.1 11.8 12.5 14.2 15.8 17.5 18.2 20.5 22.1) for i in $(seq 0 14); do row=$((i + 2)) officecli set "$XLSX" "/Analysis/A${row}" --prop "value=${AD_SPEND[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Analysis/B${row}" --prop "value=${SALES_REV[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Analysis/C${row}" --prop "value=${PROFIT[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Analysis/D${row}" --prop "value=${MKT_SHARE[$i]}" --prop alignment.horizontal=center done echo " Done: Sheet2 data" ############################################################################### # Sheet3: Stock data (with red/green coloring) ############################################################################### echo " -> Populating Sheet3: Stock data" officecli add "$XLSX" / --type sheet --prop name=StockData officecli set "$XLSX" '/StockData/A1' --prop value="Date" --prop font.bold=true --prop fill=C00000 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/StockData/B1' --prop value="Open" --prop font.bold=true --prop fill=C00000 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/StockData/C1' --prop value="High" --prop font.bold=true --prop fill=C00000 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/StockData/D1' --prop value="Low" --prop font.bold=true --prop fill=C00000 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/StockData/E1' --prop value="Close" --prop font.bold=true --prop fill=C00000 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/StockData/F1' --prop value="Volume (10K)" --prop font.bold=true --prop fill=C00000 --prop font.color=FFFFFF --prop alignment.horizontal=center DATES=("3/1" "3/2" "3/3" "3/4" "3/5" "3/6" "3/7" "3/8" "3/9" "3/10" "3/11" "3/12" "3/13" "3/14" "3/15" "3/16" "3/17" "3/18" "3/19" "3/20") OPEN=(52.3 53.1 52.8 54.2 55.1 54.5 56.2 57.8 58.5 57.2 56.8 58.3 59.5 60.2 59.8 61.5 62.3 61.8 63.5 64.2) HIGH=(53.8 54.2 54.5 55.8 56.3 56.8 58.1 59.2 59.8 58.5 58.2 59.8 61.2 61.5 61.8 63.2 63.8 63.5 65.2 65.8) LOW=(51.5 52.2 51.8 53.5 54.2 53.8 55.5 56.8 57.2 56.1 55.8 57.5 58.8 59.2 58.5 60.8 61.2 60.5 62.8 63.5) CLOSE=(53.1 52.8 54.2 55.1 54.5 56.2 57.8 58.5 57.2 56.8 58.3 59.5 60.2 59.8 61.5 62.3 61.8 63.5 64.2 65.1) VOLUME=(285 312 268 345 298 378 425 468 395 310 352 415 485 442 368 512 548 478 562 598) for i in $(seq 0 19); do row=$((i + 2)) open=${OPEN[$i]} close=${CLOSE[$i]} if (( $(echo "$close > $open" | bc -l) )); then COLOR="FF0000"; BG="FFF2F2" # Up: red elif (( $(echo "$close < $open" | bc -l) )); then COLOR="008000"; BG="F2FFF2" # Down: green else COLOR="666666"; BG="F5F5F5" # Flat: gray fi officecli set "$XLSX" "/StockData/A${row}" --prop "value=${DATES[$i]}" --prop alignment.horizontal=center --prop "font.color=${COLOR}" --prop "fill=${BG}" officecli set "$XLSX" "/StockData/B${row}" --prop "value=${OPEN[$i]}" --prop 'numFmt=0.00' --prop alignment.horizontal=center --prop "font.color=${COLOR}" --prop "fill=${BG}" officecli set "$XLSX" "/StockData/C${row}" --prop "value=${HIGH[$i]}" --prop 'numFmt=0.00' --prop alignment.horizontal=center --prop "font.color=${COLOR}" --prop "fill=${BG}" officecli set "$XLSX" "/StockData/D${row}" --prop "value=${LOW[$i]}" --prop 'numFmt=0.00' --prop alignment.horizontal=center --prop "font.color=${COLOR}" --prop "fill=${BG}" officecli set "$XLSX" "/StockData/E${row}" --prop "value=${CLOSE[$i]}" --prop 'numFmt=0.00' --prop alignment.horizontal=center --prop "font.color=${COLOR}" --prop "fill=${BG}" officecli set "$XLSX" "/StockData/F${row}" --prop "value=${VOLUME[$i]}" --prop 'numFmt=#,##0' --prop alignment.horizontal=center --prop "font.color=${COLOR}" --prop "fill=${BG}" done echo " Done: Sheet3 stock data (with red/green coloring)" ############################################################################### # Sheet4: Capability radar chart data ############################################################################### echo " -> Populating Sheet4: Capability assessment" officecli add "$XLSX" / --type sheet --prop name=Assessment officecli set "$XLSX" '/Assessment/A1' --prop value="Dimension" --prop font.bold=true --prop fill=002060 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/Assessment/B1' --prop value="Product A" --prop font.bold=true --prop fill=0070C0 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/Assessment/C1' --prop value="Product B" --prop font.bold=true --prop fill=00B050 --prop font.color=FFFFFF --prop alignment.horizontal=center officecli set "$XLSX" '/Assessment/D1' --prop value="Product C" --prop font.bold=true --prop fill=FFC000 --prop font.color=000000 --prop alignment.horizontal=center DIMS=("Performance" "Stability" "Usability" "Security" "Scalability" "Value" "Ecosystem" "Docs") PA=(92 88 75 95 82 70 85 78) PB=(78 92 88 80 90 85 72 82) PC=(85 76 92 72 78 92 88 70) for i in $(seq 0 7); do row=$((i + 2)) officecli set "$XLSX" "/Assessment/A${row}" --prop "value=${DIMS[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Assessment/B${row}" --prop "value=${PA[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Assessment/C${row}" --prop "value=${PB[$i]}" --prop alignment.horizontal=center officecli set "$XLSX" "/Assessment/D${row}" --prop "value=${PC[$i]}" --prop alignment.horizontal=center done echo " Done: Sheet4 data" ############################################################################### # Charts 1-8 — HIGH-LEVEL API (`officecli add --type chart`). # Each chart is one `add` call: chartType + a cell dataRange (or inline data for # the pie/doughnut, whose source cells aren't contiguous) + styling props # (title, colors, legend, 3D view, trendline, secondary axis, radar fill, stock # up/down bars). Positioned with x/y/width/height in cell units. # Exception: Chart 5 (bubble) stays on raw-set — the high-level command can't yet # map a dataRange to a single x/y/size series (see its note below). ############################################################################### # Chart 1: Combo — regional sales columns + YoY-growth line on a secondary axis. echo " -> Chart 1: Combo chart (columns + secondary-axis line)" officecli add "$XLSX" /Sheet1 --type chart \ --prop chartType=combo \ --prop title="Monthly Sales and YoY Growth Trend" \ --prop dataRange=Sheet1!A1:F13 \ --prop combotypes=column,column,column,column,line \ --prop secondaryaxis=5 \ --prop colors=2E75B6,9DC3E6,BDD7EE,C55A11,FF0000 \ --prop legend=b --prop axisTitle="Sales (10K)" \ --prop x=7 --prop y=0 --prop width=11 --prop height=18 # Chart 2: 3D clustered column — regional comparison. echo " -> Chart 2: 3D bar chart" officecli add "$XLSX" /Sheet1 --type chart \ --prop chartType=column3d \ --prop title="3D Regional Sales Comparison" \ --prop dataRange=Sheet1!A1:D13 \ --prop view3d=15,20,30 \ --prop colors=4472C4,ED7D31,70AD47 \ --prop legend=b \ --prop x=7 --prop y=19 --prop width=11 --prop height=18 # Chart 3: Scatter + linear trendline — ad spend vs sales. echo " -> Chart 3: Scatter plot + trendline" officecli add "$XLSX" /Analysis --type chart \ --prop chartType=scatter \ --prop title="Ad Spend vs Sales Correlation" \ --prop dataRange=Analysis!A1:B16 \ --prop trendline=linear \ --prop colors=7030A0 \ --prop catTitle="Ad Spend (10K)" --prop axisTitle="Sales (10K)" \ --prop legend=b \ --prop x=5 --prop y=0 --prop width=11 --prop height=18 # Chart 4: Exploded 3D pie — July regional share. Values live in one row # (B8:D8) with category labels in another (B1:D1), so they're passed inline. echo " -> Chart 4: 3D pie chart (exploded)" officecli add "$XLSX" /Sheet1 --type chart \ --prop chartType=pie3d \ --prop title="July Regional Sales Share (3D)" \ --prop categories="East Sales,South Sales,North Sales" \ --prop series1="Jul:195,168,145" \ --prop explosion=10 --prop view3d=30,70,30 \ --prop dataLabels=percent \ --prop colors=1F4E79,C55A11,548235 \ --prop legend=b \ --prop x=19 --prop y=0 --prop width=9 --prop height=18 # Chart 5: Bubble — ad spend (x) vs sales (y), bubble size = market share. # KEPT ON raw-set: the high-level `add --type chart --prop chartType=bubble` # reads a multi-column dataRange as several y-series sharing column A as x — it # cannot map three columns to a single x / y / size series (multi-point bubble). # Until that mapping exists, the faithful single-series bubble needs raw XML. echo " -> Chart 5: Bubble chart (raw-set — see note)" CHART5_REL=$(officecli add-part "$XLSX" /Analysis --type chart 2>&1 | grep -o 'relId=[^ ]*' | cut -d= -f2) officecli raw-set "$XLSX" '/Analysis/chart[2]' --xpath "/c:chartSpace" --action replace --xml ' Spend-Revenue-Market Share Bubble Analysis!$D$1 Analysis!$A$2:$A$16 Analysis!$B$2:$B$16 Analysis!$D$2:$D$16 Ad Spend (10K) Sales (10K) ' officecli raw-set "$XLSX" '/Analysis/drawing' --xpath "//xdr:wsDr" --action append --xml " 50190 160370 " # Chart 6: Stock OHLC candlestick — hi-low lines + up/down bars (red up, green down). echo " -> Chart 6: Stock OHLC chart" officecli add "$XLSX" /StockData --type chart \ --prop chartType=stock \ --prop title="Stock Candlestick Chart (OHLC)" \ --prop dataRange=StockData!A1:E21 \ --prop hilowlines=true \ --prop updownbars=100:FF0000:00B050 \ --prop legend=b \ --prop x=7 --prop y=0 --prop width=13 --prop height=22 # Chart 7: Filled radar — product capability comparison. echo " -> Chart 7: Filled radar chart" officecli add "$XLSX" /Assessment --type chart \ --prop chartType=radar --prop radarStyle=filled \ --prop title="Product Capability Radar Comparison" \ --prop dataRange=Assessment!A1:D9 \ --prop colors=4472C4,00B050,FFC000 \ --prop legend=b \ --prop x=5 --prop y=0 --prop width=11 --prop height=20 # Chart 8: Multi-ring doughnut — Aug vs Dec regional share (two rings). The two # source rows aren't adjacent, so the ring values are passed inline. echo " -> Chart 8: Multi-ring doughnut chart" officecli add "$XLSX" /Sheet1 --type chart \ --prop chartType=doughnut \ --prop title="Aug vs Dec Regional Sales Multi-Ring" \ --prop categories="East,South,North" \ --prop series1="Aug:210,175,152" \ --prop series2="Dec:198,158,142" \ --prop dataLabels=percent \ --prop colors=1F4E79,C55A11,548235 \ --prop legend=b \ --prop x=19 --prop y=19 --prop width=9 --prop height=18 ############################################################################### # Validation ############################################################################### officecli close "$XLSX" echo "" echo "==========================================" echo "Validating file" echo "==========================================" officecli validate "$XLSX" officecli view "$XLSX" outline echo "" ls -lh "$XLSX" echo "" echo "All done! 8 chart types generated"