> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doconda.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate an Excel file from an Amazon Bedrock agent

> How to make an Amazon Bedrock agent create an Excel file (.xlsx) and return the download link.

You'll build an Amazon Bedrock agent that, when you ask for a spreadsheet, creates a real Excel file and gives you the
link to download it. The model decides when to call Doconda; you only wire up the tools.

## What you need

* An AWS account with a Bedrock model enabled and its id in `BEDROCK_MODEL_ID`.
* AWS credentials in your environment (`AWS_REGION`, `AWS_ACCESS_KEY_ID`…), like the rest of your code.
* A Doconda API key in `DOCONDA_API_KEY`. Create it in the dashboard, under **API keys**.
* Python 3.9+ or Node 20+.

## 1. Install the dependencies

<CodeGroup>
  ```bash Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  pip install boto3 doconda
  ```

  ```bash TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  npm install ai @ai-sdk/amazon-bedrock @doconda/sdk
  ```
</CodeGroup>

## 2. Connect the tools and ask for the Excel file

`tools()` returns Doconda's tools (create, upload, review, edit, look up…) with their name, description and JSON
Schema. Bedrock takes them as `toolSpec`. The agent calls `create_document` with `format: "xlsx"`, waits until the file is ready and replies with the links.

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import json
  import os

  import boto3
  from doconda import Doconda

  bedrock = boto3.client("bedrock-runtime")
  tools = Doconda().tools()
  tool_config = {"tools": [{"toolSpec": {"name": t.name, "description": t.description, "inputSchema": {"json": t.input_schema}}} for t in tools]}
  messages = [{"role": "user", "content": [{"text": "Make me an Excel file with the event budget: venue, catering, sound and travel"}]}]

  while True:
      res = bedrock.converse(modelId=os.environ["BEDROCK_MODEL_ID"], messages=messages, toolConfig=tool_config)
      message = res["output"]["message"]
      messages.append(message)
      if res["stopReason"] != "tool_use":
          break
      results = []
      for block in message["content"]:
          if "toolUse" in block:
              use = block["toolUse"]
              out = next(t for t in tools if t.name == use["name"]).run(use["input"])
              results.append({"toolResult": {"toolUseId": use["toolUseId"], "content": [{"text": json.dumps(out)}]}})
      messages.append({"role": "user", "content": results})

  print("".join(block.get("text", "") for block in message["content"]))
  ```

  ```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import { bedrock } from "@ai-sdk/amazon-bedrock"
  import { generateText, isStepCount, jsonSchema, tool } from "ai"
  import { Doconda } from "@doconda/sdk"

  const doconda = new Doconda()
  const tools = Object.fromEntries(
    doconda.tools().map((t) => [
      t.name,
      tool({ description: t.description, inputSchema: jsonSchema(t.inputSchema), execute: (input) => t.run(input as Record<string, unknown>) }),
    ]),
  )

  const { text } = await generateText({
    model: bedrock(process.env.BEDROCK_MODEL_ID!),
    tools,
    stopWhen: isStepCount(5),
    prompt: "Make me an Excel file with the event budget: venue, catering, sound and travel",
  })

  console.log(text)
  ```
</CodeGroup>

The Python loop is the Converse API one: while the model asks for a tool (`stopReason == "tool_use"`), you run it and
send the result back. In TypeScript, the AI SDK runs that loop for you.

## Result

The tool returns something like this to the model, and the model passes it on to the user in its reply:

```json theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
{
  "id": "doc_01JAB3…",
  "format": "xlsx",
  "status": "ready",
  "links": { "xlsx": "https://…", "pdf": "https://…" },
  "links_note": "Links expire in 5 minutes: call get_document for fresh ones."
}
```

You get the Excel file (`.xlsx`) and a PDF version. The links expire after 5 minutes; if the user asks for them later,
the agent calls `get_document` and gets new ones.

## Next steps

* [Amazon Bedrock](/en/agents/bedrock): the full guide, also with the Converse API in TypeScript.
* [Python SDK](/en/sdk/python): every method, in case you want to call Doconda without an agent.
* [Complete examples on GitHub](https://github.com/B-C-Software/doconda-examples).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.