Lesson 7 of 46 ~25 min
Course progress
0%

Microsoft 365 Integration

Automate enterprise knowledge work with Opus 4.6 — Excel data analysis, PowerPoint generation, and Word document automation with practical examples.

Opus 4.6 integrates natively with Microsoft 365 through Microsoft Foundry. This is not “paste data into a prompt” — it is structured access to Excel workbooks, PowerPoint presentations, and Word documents with full read/write capabilities.

Architecture Overview

┌─────────────┐    ┌──────────────────┐    ┌──────────────────┐
│  Your App   │───▶│  Opus 4.6 API    │───▶│  Microsoft Graph │
│             │◀───│  (with M365      │◀───│  API             │
│             │    │   tool access)   │    │                  │
└─────────────┘    └──────────────────┘    └──────────────────┘

                                           ┌────────┴────────┐
                                           │  Excel  PPT  Word│
                                           └─────────────────┘

Excel Data Analysis

Reading and Analyzing Spreadsheets

from anthropic import Anthropic

client = Anthropic()

# Provide Excel data as structured input
excel_data = """
| Quarter | Revenue ($M) | Costs ($M) | Headcount | NPS |
|---------|-------------|-----------|-----------|-----|
| Q1 2025 | 12.3        | 8.1       | 145       | 72  |
| Q2 2025 | 14.7        | 9.2       | 162       | 68  |
| Q3 2025 | 13.1        | 10.8      | 178       | 65  |
| Q4 2025 | 16.9        | 11.3      | 185       | 71  |
| Q1 2026 | 18.2        | 12.1      | 192       | 74  |
"""

response = client.messages.create(
    model="claude-opus-4-6-20260205",
    max_tokens=8192,
    thinking={"type": "adaptive", "effort": "deep"},
    messages=[{
        "role": "user",
        "content": f"""Analyze this quarterly business data and provide:
1. Revenue growth trend and projection for Q2-Q4 2026
2. Cost efficiency analysis (cost per employee, cost-to-revenue ratio)
3. NPS correlation with business metrics
4. Three actionable recommendations for the executive team

Data:
{excel_data}"""
    }]
)

print(next(b.text for b in response.content if b.type == "text"))

Building an Excel Analysis Pipeline

import csv
import io

class ExcelAnalyzer:
    """Analyze CSV/Excel data with Opus 4.6."""

    def __init__(self):
        self.client = Anthropic()

    def analyze_csv(self, csv_content: str, analysis_type: str) -> dict:
        """Run a structured analysis on CSV data."""
        reader = csv.DictReader(io.StringIO(csv_content))
        rows = list(reader)

        # Build a concise data summary for the prompt
        headers = list(rows[0].keys()) if rows else []
        sample = rows[:5]  # First 5 rows as sample
        total_rows = len(rows)

        prompt = f"""Analyze this dataset ({total_rows} rows, columns: {headers}).

Sample data (first 5 rows):
{self._format_rows(sample)}

Full statistical summary:
{self._compute_stats(rows, headers)}

Analysis type: {analysis_type}

Respond with JSON containing:
- "summary": one-paragraph executive summary
- "findings": list of key findings with supporting data
- "anomalies": any data quality issues or outliers detected
- "recommendations": actionable next steps"""

        response = self.client.messages.create(
            model="claude-opus-4-6-20260205",
            max_tokens=4096,
            thinking={"type": "adaptive"},
            messages=[{"role": "user", "content": prompt}]
        )

        text = next(b.text for b in response.content if b.type == "text")
        return {"analysis": text, "rows_analyzed": total_rows}

    def _format_rows(self, rows: list[dict]) -> str:
        if not rows:
            return "No data"
        headers = list(rows[0].keys())
        lines = [" | ".join(headers)]
        lines.append(" | ".join("---" for _ in headers))
        for row in rows:
            lines.append(" | ".join(str(row.get(h, "")) for h in headers))
        return "\n".join(lines)

    def _compute_stats(self, rows: list[dict], headers: list[str]) -> str:
        stats = []
        for h in headers:
            values = [row.get(h, "") for row in rows]
            try:
                nums = [float(v) for v in values if v]
                stats.append(f"{h}: min={min(nums)}, max={max(nums)}, "
                           f"avg={sum(nums)/len(nums):.2f}")
            except (ValueError, ZeroDivisionError):
                unique = len(set(values))
                stats.append(f"{h}: {unique} unique values (categorical)")
        return "\n".join(stats)

PowerPoint Generation

Generate structured presentation content that maps directly to slides:

class PresentationGenerator:
    """Generate structured PowerPoint content with Opus 4.6."""

    SYSTEM_PROMPT = """You generate structured presentation content.
Output JSON with this exact schema for each slide:
{
  "slides": [
    {
      "title": "Slide title",
      "layout": "title|content|two_column|chart|summary",
      "content": "Main content (markdown)",
      "speaker_notes": "What the presenter should say",
      "chart_data": null or {"type": "bar|line|pie", "data": {...}}
    }
  ]
}

Rules:
- Maximum 6 bullet points per slide
- Each bullet under 15 words
- Speaker notes should be conversational, 2-3 sentences
- Use chart_data when numerical comparisons are involved"""

    def __init__(self):
        self.client = Anthropic()

    def generate(self, topic: str, audience: str,
                 duration_minutes: int) -> dict:
        slides_count = max(5, duration_minutes // 2)

        response = self.client.messages.create(
            model="claude-opus-4-6-20260205",
            max_tokens=8192,
            thinking={"type": "adaptive", "effort": "deep"},
            system=self.SYSTEM_PROMPT,
            messages=[{
                "role": "user",
                "content": f"""Create a {slides_count}-slide presentation.

Topic: {topic}
Audience: {audience}
Duration: {duration_minutes} minutes

Include an executive summary slide, data-driven content slides,
and a clear call-to-action closing slide."""
            }]
        )

        text = next(b.text for b in response.content if b.type == "text")
        return {"content": text, "target_slides": slides_count}

Word Document Automation

Contract Review Pipeline

class ContractReviewer:
    """Review contracts and legal documents with Opus 4.6."""

    SYSTEM_PROMPT = """You are a contract review assistant working alongside
legal counsel. You identify potential issues but do not provide legal advice.

For each clause, assess:
- Risk level: LOW / MEDIUM / HIGH / CRITICAL
- Standard market position: Is this term standard or unusual?
- Recommended action: Accept / Negotiate / Reject / Flag for counsel

Output structured JSON for each finding."""

    def __init__(self):
        self.client = Anthropic()

    def review(self, contract_text: str,
               contract_type: str = "SaaS agreement") -> str:
        response = self.client.messages.create(
            model="claude-opus-4-6-20260205",
            max_tokens=16384,
            thinking={"type": "adaptive", "effort": "maximum"},
            system=self.SYSTEM_PROMPT,
            messages=[{
                "role": "user",
                "content": f"""Review this {contract_type}. Identify all
clauses that present risk, are non-standard, or require negotiation.

Contract text:
{contract_text}"""
            }]
        )

        return next(b.text for b in response.content if b.type == "text")

Report Generation

class ReportGenerator:
    """Generate structured business reports from raw data."""

    def generate_quarterly_report(self, data: dict) -> str:
        prompt = f"""Generate a quarterly business report from this data.

Financial Data: {data.get('financials', {})}
Operational Metrics: {data.get('operations', {})}
Customer Metrics: {data.get('customers', {})}
Team Updates: {data.get('team', {})}

Output format:
1. Executive Summary (3-4 sentences)
2. Financial Performance (with YoY and QoQ comparisons)
3. Operational Highlights
4. Customer Health
5. Risks and Mitigation
6. Next Quarter Outlook

Write for a board-level audience. Be specific with numbers.
Flag any metric that deviates more than 10% from the previous quarter."""

        response = Anthropic().messages.create(
            model="claude-opus-4-6-20260205",
            max_tokens=8192,
            thinking={"type": "adaptive", "effort": "deep"},
            messages=[{"role": "user", "content": prompt}]
        )

        return next(b.text for b in response.content if b.type == "text")

Integration Best Practices

PracticeRationale
Batch document processingProcess multiple documents in a single session to amortize context setup costs
Use deep thinking for analysisFinancial and legal analysis benefits from exhaustive reasoning
Structure output as JSONMakes it easy to feed results into downstream tools (PPTX generators, Excel writers)
Validate numerical outputsAlways cross-check AI-generated calculations against source data
Keep source data accessibleInclude raw data references so outputs can be audited

In the next lesson, you will build research pipelines that combine web search, document analysis, and synthesis.