0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonでExcelをHTMLに変換する:Webページでデータを簡単に公開

0
Posted at

日々の業務において、Excelレポートは欠かせない存在です。売上データ、社員のパフォーマンス、プロジェクトの進捗状況など、ほぼすべてのチームが表計算ソフトで業務データを管理しています。しかし、こうしたレポートをチームメンバーや顧客、上司にオンラインで共有する際、Excelファイルはしばしば不十分です。相手がOfficeをインストールしていなかったり、デバイスによってレイアウトが崩れたり、社内システムやWebページに埋め込むのが面倒だったりします。表を手動でコピー&ペーストしてWebページにする作業は、時間がかかるだけでなく、元のフォント、色、罫線、画像などの書式が失われがちです。

この問題は、Pythonコードによってうまく解決できます。プログラムによる変換を使えば、ワークシート全体やワークブック全体をワンクリックでHTMLページに変換でき、データの構造とスタイルを自動的に保持できます。変換処理は完全に自動化・バッチ実行できるため、レポートのオンライン公開、データダッシュボードの表示、定期的なWebレポート生成などのシーンに最適です。

本記事では、実際の売上データワークブックを例に、Pythonを使用してExcelをHTMLに変換する完全なフローを紹介します。本記事で使用する方法には Free Spire.XLS for Python が必要です。pipでインストールできます:

pip install spire.xls.free

1. デモ用Excelワークブックの準備

デモを分かりやすくするため、まずコードで2つのワークシートと埋め込みLogo画像を含むサンプルワークブックを作成します。最初のワークシート「Quarterly Sales」は各地域の四半期売上、2番目のワークシート「Employee Performance」は社員のパフォーマンス、3番目のワークシート「Dashboard」は主要指標の集計と会社Logoの挿入を担います。サンプル内容はすべて英語にして、実際の国際的な業務レポートに近づけています:

from spire.xls import *
from spire.xls.common import *

outputFile = "DemoSalesReport.xlsx"

# 新しいワークブックを作成
workbook = Workbook()
workbook.Version = ExcelVersion.Version2010

# ============================================================
# ワークシート 1:Quarterly Sales
# ============================================================
sheet1 = workbook.Worksheets[0]
sheet1.Name = "Quarterly Sales"

# タイトルを書き込む(セル結合、白太字、濃紺背景)
titleCell = sheet1.Range["A1"]
titleCell.Text = "Quarterly Sales Report — FY2025"
titleCell.Style.Font.FontName = "Calibri"
titleCell.Style.Font.Size = 16
titleCell.Style.Font.IsBold = True
titleCell.Style.Font.Color = Color.get_White()
titleCell.Style.Color = Color.FromRgb(0, 70, 127)
titleCell.Style.HorizontalAlignment = HorizontalAlignType.Center
sheet1.Range["A1:E1"].Merge()
sheet1.Rows[0].RowHeight = 36

# サブタイトルを書き込む
subCell = sheet1.Range["A2"]
subCell.Text = "Prepared by: Finance Department  |  Date: July 2025"
subCell.Style.Font.IsItalic = True
subCell.Style.Font.Color = Color.FromRgb(100, 100, 100)
subCell.Style.HorizontalAlignment = HorizontalAlignType.Center
sheet1.Range["A2:E2"].Merge()

# ヘッダーを書き込む
headers = ["Region", "Product Category", "Q1 Revenue (USD)", "Q2 Revenue (USD)", "Growth Rate"]
headerRange = sheet1.Range["A4:E4"]
for col, h in enumerate(headers):
    headerRange.Columns[col].Text = h
headerRange.Style.Font.IsBold = True
headerRange.Style.Font.Color = Color.get_White()
headerRange.Style.Color = Color.FromRgb(0, 112, 192)
headerRange.Style.HorizontalAlignment = HorizontalAlignType.Center
headerRange.Borders.LineStyle = LineStyleType.Thin

# データ行を書き込む(行ごとに交互の背景色)
data = [
    ["North America", "Enterprise Software",  485000, 562000, 0.158],
    ["North America", "Cloud Services",        320000, 398000, 0.243],
    ["Europe",        "Enterprise Software",   372000, 401000, 0.078],
    ["Europe",        "Cloud Services",        215000, 276000, 0.283],
    ["Asia Pacific",  "Enterprise Software",   298000, 387000, 0.298],
    ["Asia Pacific",  "Cloud Services",        186000, 254000, 0.365],
    ["Latin America", "Enterprise Software",   142000, 168000, 0.183],
    ["Latin America", "Cloud Services",         97000, 131000, 0.350],
]
for row_idx, row_data in enumerate(data, start=5):
    for col_idx, value in enumerate(row_data, start=1):
        cell = sheet1.Range[row_idx, col_idx]
        if col_idx <= 2:
            cell.Text = str(value)
        elif col_idx <= 4:
            cell.NumberValue = float(value)
            cell.Style.NumberFormat = "$#,##0"
        else:
            cell.NumberValue = float(value)
            cell.Style.NumberFormat = "0.0%"
        cell.Style.Font.FontName = "Calibri"
        cell.Style.Font.Size = 10
    # 行ごとに交互の背景色
    range_row = sheet1.Range[f"A{row_idx}:E{row_idx}"]
    if row_idx % 2 == 1:
        range_row.Style.Color = Color.FromRgb(234, 243, 253)
    else:
        range_row.Style.Color = Color.get_White()

# 合計行を書き込む(SUM式を使用)
totalRow = 13
sheet1.Range[totalRow, 1].Text = "Total"
sheet1.Range[totalRow, 1].Style.Font.IsBold = True
sheet1.Range[totalRow, 3].Formula = "=SUM(C5:C12)"
sheet1.Range[totalRow, 3].Style.NumberFormat = "$#,##0"
sheet1.Range[totalRow, 3].Style.Font.IsBold = True
sheet1.Range[totalRow, 4].Formula = "=SUM(D5:D12)"
sheet1.Range[totalRow, 4].Style.NumberFormat = "$#,##0"
sheet1.Range[totalRow, 4].Style.Font.IsBold = True
sheet1.Range[totalRow, 5].Formula = "=D13/C13-1"
sheet1.Range[totalRow, 5].Style.NumberFormat = "0.0%"
sheet1.Range[totalRow, 5].Style.Font.IsBold = True

# 列幅を設定
sheet1.Columns[0].ColumnWidth = 20
sheet1.Columns[1].ColumnWidth = 22
sheet1.Columns[2].ColumnWidth = 20
sheet1.Columns[3].ColumnWidth = 20
sheet1.Columns[4].ColumnWidth = 15

# ============================================================
# ワークシート 2:Employee Performance
# ============================================================
sheet2 = workbook.Worksheets.Add("Employee Performance")
t2 = sheet2.Range["A1"]
t2.Text = "Employee Performance Review — Q2 2025"
t2.Style.Font.Size = 16
t2.Style.Font.IsBold = True
t2.Style.Font.Color = Color.get_White()
t2.Style.Color = Color.FromRgb(31, 86, 53)
t2.Style.HorizontalAlignment = HorizontalAlignType.Center
sheet2.Range["A1:F1"].Merge()

emp_headers = ["Employee ID", "Full Name", "Department", "Performance Score", "Projects Completed", "Status"]
empHeaderRange = sheet2.Range["A4:F4"]
for col, h in enumerate(emp_headers):
    empHeaderRange.Columns[col].Text = h
empHeaderRange.Style.Font.IsBold = True
empHeaderRange.Style.Font.Color = Color.get_White()
empHeaderRange.Style.Color = Color.FromRgb(46, 125, 75)
empHeaderRange.Style.HorizontalAlignment = HorizontalAlignType.Center

emp_data = [
    ["EMP-001", "Alice Johnson",  "Engineering", 4.7, 12, "Exceeds Expectations"],
    ["EMP-002", "Michael Chen",   "Engineering", 4.2, 10, "Exceeds Expectations"],
    ["EMP-003", "Sarah Williams", "Marketing",   3.9,  8, "Meets Expectations"],
    ["EMP-004", "David Martinez", "Sales",       4.5, 15, "Exceeds Expectations"],
    ["EMP-005", "Emily Thompson", "Product",     3.6,  7, "Meets Expectations"],
    ["EMP-006", "James Anderson", "Finance",     4.1,  9, "Meets Expectations"],
    ["EMP-007", "Olivia Brown",   "HR",          3.4,  6, "Meets Expectations"],
    ["EMP-008", "Robert Taylor",  "Engineering", 4.8, 14, "Exceeds Expectations"],
    ["EMP-009", "Sophia Lee",     "Marketing",   2.9,  5, "Needs Improvement"],
    ["EMP-010", "Daniel Garcia",  "Sales",       4.3, 11, "Exceeds Expectations"],
]
for row_idx, row_data in enumerate(emp_data, start=5):
    for col_idx, value in enumerate(row_data, start=1):
        cell = sheet2.Range[row_idx, col_idx]
        if col_idx == 4:
            cell.NumberValue = float(value)
            cell.Style.NumberFormat = "0.0"
        elif col_idx == 5:
            cell.NumberValue = float(value)
        else:
            cell.Text = str(value)
        cell.Style.Font.FontName = "Calibri"
        cell.Style.Font.Size = 10

# ============================================================
# ワークシート 3:Dashboard(Logo画像付き)
# ============================================================
sheet3 = workbook.Worksheets.Add("Dashboard")
dashTitle = sheet3.Range["A1"]
dashTitle.Text = "Sales Dashboard — FY2025"
dashTitle.Style.Font.Size = 16
dashTitle.Style.Font.IsBold = True
dashTitle.Style.Font.Color = Color.get_White()
dashTitle.Style.Color = Color.FromRgb(0, 70, 127)
dashTitle.Style.HorizontalAlignment = HorizontalAlignType.Center
sheet3.Range["A1:D1"].Merge()

metrics = [
    ["Region", "Total Revenue (USD)", "Market Share", "Target Met"],
    ["North America", 960000, 0.34, "Yes"],
    ["Europe", 773000, 0.28, "Yes"],
    ["Asia Pacific", 685000, 0.25, "Yes"],
    ["Latin America", 309000, 0.13, "No"],
]
for r, row_data in enumerate(metrics, start=3):
    for c, value in enumerate(row_data, start=1):
        cell = sheet3.Range[r, c]
        cell.Text = str(value)
        cell.Style.Font.Size = 11 if r == 3 else 10
        cell.Style.Font.IsBold = (r == 3)
        if r == 3:
            cell.Style.Font.Color = Color.get_White()
            cell.Style.Color = Color.FromRgb(0, 112, 192)
        elif c == 2:
            cell.Style.NumberFormat = "$#,##0"

# ワークシート 3 に会社Logo画像を挿入
sheet3.Pictures.Add(2, 6, "DemoLogo.png")

# デフォルトの空ワークシートを削除
for i in range(workbook.Worksheets.Count - 1, -1, -1):
    if workbook.Worksheets[i].Name.startswith("Sheet"):
        workbook.Worksheets.Remove(workbook.Worksheets[i])

# すべての式の値を計算し、HTML変換時に合計行にデータが入るようにする
workbook.CalculateAllValue()

# ワークブックを保存
workbook.SaveToFile(outputFile, ExcelVersion.Version2010)
workbook.Dispose()
print(f"Sample Excel file created: {outputFile}")

説明:

  • Worksheets[0] で最初のワークシートを取得、Worksheets.Add(name) で新しいワークシートを追加
  • Range["A1"] でセル名によるアクセス、Range[row, col] で行・列インデックスによるアクセス
  • NumberFormat で数値書式を設定($#,##0 は桁区切り付きの金額、0.0% はパーセンテージ)
  • Formula で数式を書き込み、合計行は SUM で自動集計
  • Merge() でセルを結合してレポートタイトルを生成
  • Pictures.Add(row, col, path) で指定セル位置に画像を挿入
  • CalculateAllValue() で全数式の値を事前計算し、後続のHTML変換時に合計値を直接表示できるようにする

実行後、DemoSalesReport.xlsx が生成されます。3つのワークシートを含み、以降のHTML変換デモのソースファイルになります。Excelで開いたときの表示は以下の通りです:

Pythonで作成したサンプルExcelワークブック(Quarterly Salesワークシート)

3つのワークシートは、四半期売上レポート(Quarterly Sales)、社員パフォーマンス表(Employee Performance)、Logo画像付きデータダッシュボード(Dashboard)です。


2. 単一ワークシートをHTMLに変換

最も一般的なニーズは、特定のワークシートを独立したHTMLファイルに変換することです。ワークブックを読み込んだ後、ワークシートの SaveToHtml メソッドを呼び出すだけで変換が完了します:

from spire.xls import Workbook, HTMLOptions

inputFile = "DemoSalesReport.xlsx"
outputFile = "QuarterlySales_Sheet.html"

# Excelワークブックを読み込む
workbook = Workbook()
workbook.LoadFromFile(inputFile)

# 最初のワークシートを取得
sheet = workbook.Worksheets[0]

# HTMLオプションを作成し、画像を埋め込む
options = HTMLOptions()
options.ImageEmbedded = True

# ワークシートをHTMLに変換
sheet.SaveToHtml(outputFile, options)
workbook.Dispose()
print("ワークシートをHTMLに変換しました:QuarterlySales_Sheet.html")

説明:

  • LoadFromFile() でディスクから既存のExcelファイルを読み込む
  • HTMLOptions() でHTML変換オプションのオブジェクトを作成し、変換動作を制御
  • SaveToHtml(filePath, options) で現在のワークシートの内容をHTMLファイルとして出力
  • workbook.Dispose() でリソースを解放

変換後のHTMLファイルはブラウザで直接開くことができ、元のフォント、色、罫線、交互背景色などがすべて保持されます。ソースファイルで CalculateAllValue() を呼び出しているため、合計行の数式結果 $2,115,000$2,577,00021.8% もWebページに正しく表示されます。

ブラウザで開いたときの表示は以下の通りです:

PythonでExcelワークシートをHTMLに変換した結果

注意事項:

  • このメソッドは指定した現在のワークシートのみを変換し、他のワークシートの内容は含まれません
  • ワークシートに画像が含まれる場合は、ImageEmbedded = True を維持することを推奨します(Free版では、画像は同名の _files フォルダに出力され、外部リソースとして参照されます)
  • 生成されたHTMLは標準のWebページであり、他のシステムに直接埋め込んで表示できます

3. ワークブック全体をHTMLに変換

Excelファイルに複数のワークシートが含まれる場合、ワークブックレベルの変換メソッドを直接呼び出すことで、すべてのワークシートを一度に、タブナビゲーション付きのHTMLページに変換できます:

from spire.xls import Workbook

inputFile = "DemoSalesReport.xlsx"
outputFile = "DemoSalesReport.html"

# Excelワークブックを読み込む
workbook = Workbook()
workbook.LoadFromFile(inputFile)

# ワークブック全体をHTMLに変換(すべてのワークシートを含む)
workbook.SaveToHtml(outputFile)
workbook.Dispose()
print("ワークブック全体をHTMLに変換しました:DemoSalesReport.html")

説明:

  • workbook.SaveToHtml() でワークブック内のすべてのワークシートを一度にHTMLに変換
  • 変換結果は1つのメインHTMLファイル(framesetフレームページ)となり、各ワークシート間のタブナビゲーションが自動生成され、下部のタブをクリックするとワークシートを切り替えられます
  • 各ワークシートは独立したHTMLファイルとして生成され、メインのファイル名に _files を付けたフォルダに格納されます

ブラウザで開いたときの表示は以下の通りです。ページ下部に自動生成されたワークシートタブがあり、クリックするといずれのワークシートにも切り替えられます:

PythonでExcelワークブックをHTMLに変換した結果(ワークシートタブナビゲーション付き)

Employee Performanceワークシートに対応するHTMLファイルも、元データのスタイル(緑色のヘッダー、交互背景色)を完全に保持しています:

ExcelワークブックをHTMLに変換した各ワークシートの結果

変換後のディレクトリ構造はおおよそ以下の通りです:

DemoSalesReport.html                    ← メインページ(フレームとナビゲーション)
DemoSalesReport_files/
├── Quarterly Sales.html                ← ワークシート 1 の内容
├── Employee Performance.html           ← ワークシート 2 の内容
├── Dashboard.html                      ← ワークシート 3 の内容
└── tabs.html                           ← 下部タブナビゲーション

応用シーン:

  • 月次総合レポート:売上、在庫、財務など複数ディメンションのデータを一度にまとめて公開
  • プロジェクト管理ドキュメント:タスクリスト、進捗追跡、リソース配分など複数のワークシートを統一的に表示
  • データダッシュボード:複数の関連レポートを1つのWebページに統合し、経営層が集中的に確認できるようにする

ワークブック内のDashboardワークシートには埋め込みLogo画像が含まれていますが、HTMLに変換した後も正常に表示されます:

Excelワークブック内の画像をHTMLに変換した表示結果


4. ストリーム出力を使用してHTMLに変換

HTMLを直接ディスクファイルに書き込むのではなく、書き込み前に内容をさらに処理したい場合や、変換結果をカスタムターゲット(サーバーへのアップロード、データベースへの書き込みなど)に直接送りたい場合があります。そのようなシーンではストリーム出力を使用します:

from spire.xls import Workbook, HTMLOptions, Stream

inputFile = "DemoSalesReport.xlsx"
outputFile = "QuarterlySales_Stream.html"

# Excelワークブックを読み込む
workbook = Workbook()
workbook.LoadFromFile(inputFile)

# 最初のワークシートを取得
sheet = workbook.Worksheets[0]

# HTMLオプションを設定
options = HTMLOptions()
options.ImageEmbedded = True

# 出力ストリームを作成して変換
fileStream = Stream(outputFile)
sheet.SaveToHtml(fileStream, options)
fileStream.Close()
workbook.Dispose()
print("ストリーム出力でHTMLに変換しました:QuarterlySales_Stream.html")

説明:

  • Stream(outputFile) でファイルストリームオブジェクトを作成し、出力プロセスを制御
  • SaveToHtml(fileStream, options) でワークシートの内容を指定のストリームに書き込む
  • fileStream.Close() でストリームを閉じてリソースを解放

メリット:

  • 書き込み前にHTMLの内容に対して追加の処理や加工ができる
  • カスタムの出力パスとファイル名をサポート
  • メモリストリームと組み合わせてクラウドに直接アップロードするなど、大規模なデータ処理フローへの統合が容易

5. 主要クラスとメソッドの解説

Workbookクラス

Workbook はExcel操作全体のエントリーポイントであり、完全なExcelファイルを表します。

主なメソッド:

メソッド 説明
LoadFromFile(filePath) 指定パスからExcelファイルを読み込む
SaveToFile(filePath, version) ワークブックをExcelファイルとして保存
SaveToHtml(filePath) ワークブック全体をHTMLファイルに変換
CalculateAllValue() ワークブック内のすべての数式の値を計算
Dispose() ワークブックが使用するリソースを解放

主なプロパティ:

プロパティ 説明
Worksheets ワークブック内のすべてのワークシートコレクションを取得

Worksheetクラス

Worksheet はExcel内の単一ワークシートを表し、データ操作の主要オブジェクトです。

主なメソッド:

メソッド 説明
SaveToHtml(filePath) 現在のワークシートをHTMLファイルに変換
SaveToHtml(stream, options) ワークシートをHTMLに変換してストリームに書き込む
Merge() セル範囲を結合

主なプロパティ:

プロパティ 説明
Name ワークシート名を取得または設定
Range ワークシートのセル範囲オブジェクトを取得
Pictures ワークシート内の画像コレクションを取得。Add() で画像を追加可能

HTMLOptionsクラス

HTMLOptions はHTML変換のさまざまなオプションを設定するために使用します。

主なプロパティ:

プロパティ 説明 デフォルト値
ImageEmbedded 画像をHTMLに埋め込むかどうか(Base64エンコーディング) False
ImageLocationType 画像位置の参照方法(GlobalAbsolute グローバル絶対パス / TableRelative 相対パス) GlobalAbsolute
IsFixedTableColWidth 固定のテーブル列幅を使用するかどうか False
TextMode テキスト取得方法(NumberText 数値書式テキストを保持 / Value 元の数値を取得) NumberText
StyleDefine スタイル定義方法(Head<style> タグに定義 / Inline はインラインスタイル) Head

使用上の推奨:

  • ワークシートに画像が含まれる場合、ImageEmbedded = True を設定すると画像をBase64として単一のHTMLファイルに埋め込めます(商用版でサポート)。Free版では画像が同ディレクトリの _files フォルダに出力されます
  • 単一のHTMLファイルを独立して配布する必要がある場合は画像の埋め込みを、ファイルサイズを抑えたい場合は外部参照を使用することをお勧めします
  • TextModeNumberText(デフォルト)を使用すると $#,##0 などの数値書式が保持され、金額が読みやすくなります

Streamクラス

Stream はストリームI/O操作を提供し、ファイル出力を柔軟に制御します。

主なメソッド:

メソッド 説明
Close() ストリームを閉じてリソースを解放

使用シーン:

  • 書き込み前にデータを処理する必要がある場合
  • 出力をカスタムターゲットにリダイレクトする必要がある場合
  • 非同期処理やバッチ処理フローに統合する場合

6. 実践例:Webレポートの自動生成と公開

以下は完全な実践シーンです。先ほど作成した売上ワークブックからExcelとHTMLの両形式をワンクリックで生成し、アーカイブとオンライン共有の両方に対応します:

from spire.xls import Workbook, ExcelVersion, HTMLOptions

def publish_sales_report(inputFile):
    """売上ワークブックをHTMLレポートに変換"""
    outputHtml = "Published_SalesReport.html"

    # ワークブックを読み込む
    workbook = Workbook()
    workbook.LoadFromFile(inputFile)

    # ワークブック全体をHTMLに変換(すべてのワークシートとナビゲーションを含む)
    workbook.SaveToHtml(outputHtml)

    # 同時に最初のワークシートを独立HTMLファイルに変換
    options = HTMLOptions()
    options.ImageEmbedded = True
    workbook.Worksheets[0].SaveToHtml("Published_QuarterlySales.html", options)

    workbook.Dispose()
    print(f"HTMLレポートを生成しました:{outputHtml}")
    return outputHtml

# 公開処理を実行
publish_sales_report("DemoSalesReport.xlsx")

説明:

  • ワークブックレベルとワークシートレベルの変換を併用し、「全体表示」と「単表共有」の両方のニーズに対応
  • 変換ロジックを関数にカプセル化し、定期タスクへの組み込みでバッチ公開を実現
  • 手動操作が不要で、プロセス全体が完全に自動化されます

拡張の方向性:

  • 定期タスクと組み合わせ、日報・週報・月報の自動生成と公開を実現
  • 生成したHTMLをWebサーバーやオブジェクトストレージにアップロードし、チームでのオンライン共有を実現
  • メール送信と組み合わせ、HTMLレポートを添付ファイルとして関係者に自動配信

まとめ

本記事の例を通じて、Pythonを使用してExcelファイルをHTML形式に変換する方法を理解できました。単一ワークシートの独立した変換から、ワークブック全体のタブ付き一括変換、ストリーム出力の柔軟な応用まで、このプロセスは高度に自動化されており、企業のレポート公開、データダッシュボード表示、オンラインドキュメント共有などのシーンに特に適しています。

手動のコピー&ペーストやオンライン変換ツールと比較して、Pythonベースのコード方式には以下のメリットがあります:

  • 書式の完全保持:元のフォント、色、罫線、セル結合などのスタイルを自動的に保持
  • バッチ処理の高効率:複数のファイルを一度に処理でき、作業効率を大幅に向上
  • カスタマイズ性の高さ:ニーズに応じて変換オプションと出力形式を調整可能
  • 統合の容易さ:自動化ワークフローやWebアプリケーションに簡単に組み込み可能

さらに多くの機能を拡張できます。例えば、定期タスクと組み合わせたレポートの定期公開、社内システムへの統合によるリアルタイムデータ閲覧、データベースとの連携によるデータ抽出からHTML公開までのエンドツーエンド自動化などです。Excelデータのオンライン表示や自動化レポートのニーズに対応する場合、このPythonベースの変換ソリューションはあなたの業務を大きく改善するでしょう。

より高度な機能については、Free Spire.XLS for Python公式ドキュメントを参照してください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?