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

# In-memory output

> Return a workbook as bytes with no file on disk

The `_to_bytes` variants take the same arguments as their file counterparts, minus `filename`, and hand back `bytes`.

```python theme={null}
excel_bytes = jet.write_sheet_arrow_to_bytes(
    df.to_arrow(),
    sheet_name="Employees",
    styled_headers=True,
    auto_width=True,
)
```

This matters wherever the filesystem is awkward: read-only containers, Lambda's ephemeral storage, or any web server where writing a temp file means cleaning it up afterwards.

## Serving from a web framework

<CodeGroup>
  ```python FastAPI theme={null}
  from fastapi import FastAPI
  from fastapi.responses import Response

  XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

  app = FastAPI()

  @app.get("/report")
  async def report():
      data = jet.write_sheet_arrow_to_bytes(df.to_arrow(), styled_headers=True)
      return Response(
          content=data,
          media_type=XLSX,
          headers={"Content-Disposition": "attachment; filename=report.xlsx"},
      )
  ```

  ```python Flask theme={null}
  from flask import Flask, Response

  XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

  app = Flask(__name__)

  @app.route("/download")
  def download():
      data = jet.write_sheet_arrow_to_bytes(df.to_arrow(), styled_headers=True)
      return Response(
          data,
          mimetype=XLSX,
          headers={"Content-Disposition": "attachment;filename=data.xlsx"},
      )
  ```

  ```python AWS Lambda theme={null}
  import base64

  XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

  def lambda_handler(event, context):
      data = jet.write_sheet_arrow_to_bytes(df.to_arrow())
      return {
          "statusCode": 200,
          "body": base64.b64encode(data).decode("utf-8"),
          "isBase64Encoded": True,
          "headers": {"Content-Type": XLSX},
      }
  ```
</CodeGroup>

<Tip>
  That long media type is the correct one for `.xlsx`. Serving `application/vnd.ms-excel` instead, which is the older `.xls` type, makes some browsers mislabel the download.
</Tip>

## Straight to object storage

```python theme={null}
import boto3

s3 = boto3.client("s3")
s3.put_object(
    Bucket="my-bucket",
    Key="reports/monthly.xlsx",
    Body=jet.write_sheets_arrow_to_bytes(sheets, num_threads=2),
    ContentType=(
        "application/vnd.openxmlformats-officedocument."
        "spreadsheetml.sheet"
    ),
)
```

## Multiple sheets to bytes

```python theme={null}
excel_bytes = jet.write_sheets_arrow_to_bytes(
    [
        {"data": df1.to_arrow(), "name": "Sales", "styled_headers": True},
        {"data": df2.to_arrow(), "name": "Costs", "auto_width": True},
    ],
    num_threads=2,
)
```

<Note>
  Here `num_threads` defaults to `1`, unlike the file-writing `write_sheets_arrow` where it's required.
</Note>

## Memory

Jetxl holds the entire workbook in memory before returning it. For a million-row sheet that's on the order of a gigabyte during generation, which is fine on a server and potentially fatal in a small Lambda. Write to a file for very large exports, or split the work.
