🎆

備忘録; 取り込んだExcelファイルのシートを表示するアプリケーション

2024/10/06に公開

Flaskをバックエンド、フロントエンドをhtmlにして、読み込んだExcelファイルのsheetを表示,
sheetにデータを記入するwebアプリケーションを作成しました。その備忘録です。

Flask Backend

from flask import Flask, render_template, request, send_file
import pandas as pd
from openpyxl import load_workbook
import selenium.webdriver as webdriver
from selenium.webdriver.common.by import By
from io import BytesIO

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return 'No file uploaded', 400
    
    file = request.files['file']
    
    # xlsxファイルの読み込み
    wb = load_workbook(file)
    sheet_names = wb.sheetnames
    
    # シート名をクライアント側に送信
    return {"sheetNames": sheet_names}

@app.route('/process', methods=['POST'])
def process_file():
    file = request.files['file']
    sheet_name = request.form['sheet_name']
    selected_day = request.form['day']
    
    # xlsxファイルの読み込み
    wb = load_workbook(file)
    sheet = wb[sheet_name]

    # Seleniumを使ってgoogle.comからデータ取得
    driver = webdriver.Chrome()  # ここで適切なWebDriverを使用する
    driver.get("https://www.google.com")
    elements = driver.find_element(By.CLASS_NAME,'gb_K')  # 適切なclass名に置き換え
    text_data = elements.text
    driver.quit()

    # 取得したテキストデータをxlsxに書き込み
    for i, text in enumerate(text_data):
        sheet[f"A{i+1}"] = text

    # xlsxファイルをメモリに保存
    output = BytesIO()
    wb.save(output)
    output.seek(0)
    
    # ファイルをクライアントに送信
    return send_file(output, as_attachment=True, download_name='processed_file.xlsx')

if __name__ == '__main__':
    app.run(port=8000)


フロントエンド

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Excel Processor</title>
</head>
<body>
    <h1>Excel Processor</h1>

    <!-- ファイルアップロード -->
    <form id="uploadForm" enctype="multipart/form-data">
        <input type="file" id="fileInput" accept=".xlsx" required>
        <button type="submit">Upload File</button>
    </form>

    <!-- シート選択 -->
    <div id="sheetSelection" style="display:none;">
        <label for="sheetSelect">Select a sheet:</label>
        <select id="sheetSelect"></select>
    </div>

    <!-- 日付選択 -->
    <div id="daySelection" style="display:none;">
        <label for="daySelect">Select a day:</label>
        <select id="daySelect">
            <!-- 1〜31日を自動生成 -->
            <script>
                for (let i = 1; i <= 31; i++) {
                    document.write(`<option value="${i}">${i}</option>`);
                }
            </script>
        </select>
    </div>

    <!-- 処理実行ボタン -->
    <div id="processButton" style="display:none;">
        <button id="processFileButton">Process File</button>
    </div>

    <script>
        document.getElementById('uploadForm').onsubmit = function(event) {
            event.preventDefault();

            const fileInput = document.getElementById('fileInput');
            const formData = new FormData();
            formData.append('file', fileInput.files[0]);

            fetch('/upload', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                const sheetSelect = document.getElementById('sheetSelect');
                sheetSelect.innerHTML = '';

                data.sheetNames.forEach(sheet => {
                    const option = document.createElement('option');
                    option.value = sheet;
                    option.text = sheet;
                    sheetSelect.appendChild(option);
                });

                document.getElementById('sheetSelection').style.display = 'block';
                document.getElementById('daySelection').style.display = 'block';
                document.getElementById('processButton').style.display = 'block';
            });
        };

        document.getElementById('processFileButton').onclick = function() {
            const fileInput = document.getElementById('fileInput');
            const sheetSelect = document.getElementById('sheetSelect');
            const daySelect = document.getElementById('daySelect');

            const formData = new FormData();
            formData.append('file', fileInput.files[0]);
            formData.append('sheet_name', sheetSelect.value);
            formData.append('day', daySelect.value);

            fetch('/process', {
                method: 'POST',
                body: formData
            })
            .then(response => response.blob())
            .then(blob => {
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'processed_file.xlsx';
                document.body.appendChild(a);
                a.click();
                a.remove();
            });
        };
    </script>
</body>
</html>


Discussion