Pythonでストリーム内のExcelファイルを操作する方法

Pythonを使用すると、バイトストリームからファイルを直接読み込み、編集し、変更後のドキュメントを再びバイト列として保存できます。これにより、外部ストレージを使用せずに柔軟かつ効率的にデータを処理できるだけでなく、特にネットワーク通信やメモリ上で機密情報を扱う場合に、データの安全性と完全性を確保できます。本記事では、**PythonでExcelファイルを作成してバイトストリームに保存する方法**および**バイトストリーム内のExcelファイルを読み書きする方法**を紹介します。

- **[PythonでExcelファイルを作成し、バイトストリームに保存する](#pythonでexcelファイルを作成しバイトストリームに保存する)**
- **[Pythonでバイトストリーム内のExcelファイルを直接読み込む](#pythonでバイトストリーム内のexcelファイルを直接読み込む)**
- **[Pythonでバイトストリーム内のExcelファイルを編集する](#pythonでバイトストリーム内のexcelファイルを編集する)**

この記事で使用する方法では、Spire.XLS for Pythonライブラリを用います。インストールは以下のコマンドで行います：
```
pip install spire.xls
```

---

## PythonでExcelファイルを作成し、バイトストリームに保存する
まず、`Workbook`インスタンスを作成して新しいExcelブックを生成します。データを追加したりフォーマットを設定したりした後、`Workbook.SaveToStream()`メソッドを使用してこれを`bytes`または`bytearray`に保存できます。以下は具体的な手順の例です：

1. 必要なモジュールをインポートする。
2. `Workbook`オブジェクトを作成し、新しいExcelブックを作成する（初期状態では3つのワークシートが含まれる）。
3. `Workbook.Worksheets.get_Item()`メソッドでワークシートを取得する。
4. データを定義するか、外部からデータをインポートする。
5. `Worksheet.Range.get_Item().Value`または`.NumberValue`プロパティを使用してデータをワークシートに書き込む。
6. `CellRange.Style`プロパティでセルのフォーマットを設定する。
7. `Worksheet.AutoFitColumn()`メソッドで列幅を自動調整する。
8. `Stream`オブジェクトを作成する。
9. `Workbook.SaveToStream()`メソッドでExcelブックを`Stream`オブジェクトに保存する。
10. `Stream`オブジェクトを`bytes`または`bytearray`に変換するか、既存の`bytearray`に書き込む。
11. リソースを解放する。

### コード例
```python
from spire.xls import Workbook, FileFormat, Stream, Color, HorizontalAlignType

# Workbook クラスのインスタンスを作成
workbook = Workbook()

# 最初のワークシートを取得
sheet = workbook.Worksheets.get_Item(0)

# データの2次元リストを作成、または他のソースからデータを読み取る
data = [
    ["タイトル", "著者", "出版年", "ジャンル", "価格 (JPY)"],
    ["吾輩は猫である", "夏目漱石", 1905, "小説", 1200],
    ["人間失格", "太宰治", 1948, "小説", 1000],
    ["羅生門", "芥川龍之介", 1915, "短編", 800],
    ["源氏物語", "紫式部", 1008, "古典文学", 1500],
    ["こころ", "夏目漱石", 1914, "小説", 1100],
    ["雪国", "川端康成", 1947, "小説", 950],
    ["走れメロス", "太宰治", 1940, "短編", 700],
    ["仮面の告白", "三島由紀夫", 1949, "小説", 1200],
    ["細雪", "谷崎潤一郎", 1943, "小説", 1400],
    ["おくのほそ道", "松尾芭蕉", 1702, "俳句", 900]
]

# データをワークシートに挿入
for i, row in enumerate(data):
    for j, value in enumerate(row):
        if isinstance(value, str):
            sheet.Range.get_Item(i + 1, j + 1).Value = value
        else:
            sheet.Range.get_Item(i + 1, j + 1).NumberValue = value

# ヘッダー行をフォーマット
headerRow = sheet.AllocatedRange.Rows.get_Item(0)
headerRow.Style.Color = Color.FromRgb(77, 189, 155)
headerRow.Style.Font.FontName = "MS Gothic"
headerRow.Style.Font.Size = 14
headerRow.Style.Font.IsBold = True
headerRow.Style.HorizontalAlignment = HorizontalAlignType.Center

# データ行をフォーマット
for i in range(1, sheet.AllocatedRange.Rows.Count):
    row = sheet.AllocatedRange.Rows.get_Item(i)
    row.Style.Font.FontName = "MS Gothic"
    row.Style.Font.Size = 12
    row.Style.HorizontalAlignment = HorizontalAlignType.Left
    row.Style.Color = Color.FromRgb(255, 253, 208)
    if i % 2 == 0:
        row.Style.Color = Color.FromRgb(255, 248, 183)

# 列幅を自動調整
for i in range(sheet.AllocatedRange.Columns.Count):
    sheet.AutoFitColumn(i + 1)

# Stream オブジェクトを作成
stream = Stream()

# ワークブックをストリームに保存
workbook.SaveToStream(stream, FileFormat.Version2016)
workbook.Dispose()

# ストリームをバイト配列に変換
bytes_data = stream.ToArray()

# バイト配列をファイルに書き込む
with open("output/CreateExcelByStream.xlsx", "wb") as file:
    file.write(bytes_data)
```

### 実行結果
![Pythonで作成したExcelブックをバイトストリームとして保存](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/5b6fcf20-ce12-1953-c441-0afaf0f232c8.png)

---

## Pythonでバイトストリーム内のExcelファイルを直接読み込む
`Workbook.LoadFromStream(Stream(bytes))`メソッドを使用してバイトストリームからExcelファイルを直接読み込み、使用されているセルの行や列を反復処理してデータを取得します。以下は手順の例です：

1. 必要なモジュールをインポートする。
2. `Workbook`オブジェクトを作成する。
3. `Workbook.LoadFromStream(Stream(bytes))`メソッドでバイトストリームからExcelファイルを読み込む。
4. `Workbook.Worksheets.get_Item()`メソッドで指定のワークシートを取得する。
5. ワークシートの使用中セルを行列単位で反復処理し、`Worksheet.AllocatedRange.get_Item().Value`プロパティでデータを取得する。
6. データを出力または他の操作に使用する。
7. リソースを解放する。

### コード例
```python
from spire.xls import Workbook, Stream

# バイトオブジェクトを作成するか、既存のバイトオブジェクトを使用
with open("output/CreateExcelByStream.xlsx", "rb") as file:
    bytes_data = file.read()

# Workbook クラスのインスタンスを作成
workbook = Workbook()

# バイトストリームからExcelファイルを読み込む
workbook.LoadFromStream(Stream(bytes_data))

# 最初のワークシートを取得
sheet = workbook.Worksheets.get_Item(0)

# ワークシートからデータを読み取る
# データを格納するリストを作成
data = []
for i in range(sheet.AllocatedRange.Rows.Count):
    # 一行分のデータを取得
    row = sheet.AllocatedRange.Rows.get_Item(i)
    # 行のデータを格納するリストを作成
    row_data = []
    for j in range(row.Cells.Count):
        # セルの値を取得
        cellValue = sheet.AllocatedRange.get_Item(i + 1, j + 1).Value
        row_data.append(cellValue)
    data.append(row_data)

# データを表示するか、必要に応じて使用
for row in data:
    print(row)

# リソースを解放
workbook.Dispose()
```

### 実行結果
![バイトストリームからExcelファイルのデータを読み取る](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/b06d197b-d641-2155-d1bd-5d5703053acb.png)

---

## Pythonでバイトストリーム内のExcelファイルを編集する
`Workbook.LoadFromStream(Stream(bytes))`メソッドを使用してバイトストリームからExcelファイルを読み込み、編集後に`Workbook.SaveToStream()`メソッドで再びバイトストリームに保存することができます。以下は手順の例です：

1. 必要なモジュールをインポートする。
2. `Workbook`オブジェクトを作成する。
3. バイトストリームから`Stream`オブジェクトを作成する。
4. `Workbook.LoadFromStream()`メソッドで`Stream`オブジェクトからExcelファイルを読み込む。
5. `Workbook.Worksheets.get_Item()`メソッドで指定のワークシートを取得する。
6. 必要に応じてフォーマットを編集する。
7. `Workbook.SaveToStream()`メソッドで編集済みのExcelブックを`Stream`オブジェクトに保存する。
8. `Stream`オブジェクトを`bytes`または`bytearray`に変換する。
9. バイトストリームをファイルに書き込むか他の用途に使用する。
10. リソースを解放する。

### コード例
```python
from spire.xls import Workbook, Stream, HorizontalAlignType, Color, FileFormat

# バイトオブジェクトを作成するか、既存のバイトオブジェクトを使用
with open("output/CreateExcelByStream.xlsx", "rb") as file:
    bytes_data = file.read()

# Workbook クラスのインスタンスを作成
workbook = Workbook()

# バイトストリームからExcelファイルを読み込む
stream = Stream(bytes_data)
workbook.LoadFromStream(stream)
stream.Close()

# 不要なワークシートを削除
#for i in range(1, workbook.Worksheets.Count):
#    workbook.Worksheets.Remove(workbook.Worksheets.get_Item(i))

# 最初のワークシートを取得
sheet = workbook.Worksheets.get_Item(0)

# ヘッダー行のスタイルを変更
headerRow = sheet.AllocatedRange.Rows.get_Item(0)
headerRow.Style.Font.Bold = False
headerRow.Style.Font.FontName = "MS Mincho"
headerRow.Style.Font.Size = 12
headerRow.Style.HorizontalAlignment = HorizontalAlignType.Left
headerRow.Style.Color = Color.FromRgb(92, 64, 131)

# データ行のスタイルを変更
for i in range(1, sheet.AllocatedRange.Rows.Count):
    row = sheet.AllocatedRange.Rows.get_Item(i)
    row.Style.Font.FontName = "MS Mincho"
    row.Style.Font.Size = 11
    row.Style.Color = Color.FromRgb(255, 237, 206)
    if i % 2 == 0:
        row.Style.Color = Color.FromRgb(255, 228, 181)

# 列幅を自動調整
for i in range(sheet.AllocatedRange.Columns.Count):
    sheet.AutoFitColumn(i + 1)

# 修正したExcelファイルを保存
streamTemp = Stream()
workbook.SaveToStream(streamTemp, FileFormat.Version2016)
workbook.Dispose()

# ストリームをバイトに変換
bytes_data = streamTemp.ToArray()

# バイトをファイルに書き込む、または必要に応じて使用
with open("output/ModifiedExcel.xlsx", "wb") as file:
    file.write(bytes_data)
```

### 実行結果
![バイトストリーム内のExcelブックを編集して保存する](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/98429f27-c69a-fde8-4b30-48aa2dba85e9.png)

---

この記事では、Pythonを使用してExcelブックを作成してバイトストリームに保存する方法、またバイトストリーム内のExcelブックを読み取りおよび編集する方法を解説しました。

[無料ライセンスの申請](https://www.e-iceblue.com/TemLicense.html)