よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【Flask】Excelの売上台帳にWebアプリからプルダウン入力する其の1

Excelシートの売上台帳への入力を、Webアプリで作ったフォームで行いたい。
そのとき同じExcelシートの顧客台帳から顧客一覧を抽出し、Webアプリでプルダウンのメニュを出して選択できるようにする。
PythonとFlaskとExcelを使う。

今回は、Webアプリで入力フォームを作る段階で、プルダウンメニューが表示されるかどうかだけの確認を行う。ショボい( ^∀^)



【実行環境】

目次




用意したもの


  1. Excelファイル(sample.xlsx)
    1. Sheet1 : 売上台帳(適当に作成)
    2. Sheet2 : 顧客台帳(上に〃)
  2. Flaskの実行ファイル(app.py)
  3. テンプレートファイル(index.html)



それぞれの内容は下記の通り。

1.1 Excelファイル/Sheet1/売上台帳用


Excelで適当に作った売上台帳的なシート

sample.xlsxSheet1

f:id:chayarokurokuro:20210115161631j:plain
これは今回は使わない。これへの入力の手助けとなるWebアプリを作ろうとしている。

1.2 Excelファイル/Sheet2/顧客台帳用


こちらも適当に作った顧客台帳
sample.xlsxSheet2

f:id:chayarokurokuro:20210115161848j:plain
この一覧が入力フォームのプルダウンになる予定。
追記
書き忘れていた。上の顧客名の「大内氏」はわざと2つ入れている。ダブって登録することはよくあるだろう。なので、↓のファイルでは顧客一覧を取り出す際にunique()を使ってダブりを無くしている。

2. Flaskの実行ファイル(app.py)


Webアプリ起動用のPythonスクリプト
外部ライブラリを使用するので未だなら下記など環境に合わせて先に行っておく。

$ pip install Flask Pandas


コードは以下。

import pandas as pd
from flask import Flask, render_template

# Excelの読み込みと顧客一覧抽出
def read_excel(filename="sample.xlsx"):
    df = pd.read_excel(filename, sheet_name=None)

    return df["Sheet2"].loc[:,"顧客名"].unique()

data_list = read_excel()

# Webアプリ
app = Flask(__name__)
app.config['DEBUG'] = True


@app.route("/")
def index():
    return render_template("index.html", data_list=data_list)

if __name__ == "__main__":
    app.run()

Excelファイルの全シートを(sheet_name=Noneで)読み込んだあと、2枚目の「Sheet2」の「顧客名」列を抜き出し、unique()で重複しないように要素を抽出。変数名をdata_listとしているが、型はnumpy配列です(これで上手く動く)。
それをrender_template()にテンプレートファイルと一緒に渡している。



3. テンプレートファイル(index.html)


ブラウザ表示用のhtmlファイル。

<!DOCTYPE html>
<html>

  <head>
    <title>flask</title>
    <style type="text/css">
        select { width: 250px;
                height: 5em;
        }
    </style>
  </head>
  <body>
    <select name="sample">
    {% for data in data_list %}
        <option value="{{ data }}">{{ data }}</option>
    {% endfor %}
    </select>
  </body>
</html>

selectタグの中にoptionタグを羅列してプルダウンの要素を増やす代わりにfor文を使って書いている。
forからendforのカタマリはselectの中に入れ込まないと表示がおかしくなりました。最初間違えて書いてしまって。一応注意ということでメモ。



ディレクトリ構成


以上の3つのファイル

  • app.py
  • sample.xlsx (シート2枚)
  • index.html

を作ったら、次のようなディレクトリ構成にする。


作業フォルダ
.
├── app.py
├── sample.xlsx
└── templates  ←フォルダです
    └── index.html

1 directory, 3 files


templates」フォルダはHTMLテンプレートファイルを入れておくフォルダで、Flaskでは標準でこの名前を使わないといけないようです。「template」や「temp」等の名前だとファイルが読まれなくてエラーが出る。


というか、「ディレクトリ」と書いたり「フォルダ」と書いたり、どっちやねん。(  ̄ー ̄)



準備が済んだら実行


Webアプリを起動します。
起動したらサーバーが立ち上がりますので、ブラウザのURL窓にlocalhost:5000、またはhttp://127.0.0.1:5000/と書いてenter。

実行。

$ python app.py
* Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

なんちゃらかんちゃら……



ブラウザでlocalhost:5000、またはhttp://127.0.0.1:5000/にアクセス。

f:id:chayarokurokuro:20210115165506j:plain



↑selectのプルダウンのあれが表示されています。

押してみます。↓

f:id:chayarokurokuro:20210115165631j:plain


上手く行きました。

終える時は、Ctrl+cでサーバーが止まる。

今回の実験はここまで。



おわりに


プルダウンのサイズや文字サイズの変更方法がよく分からないのでindex.htmlの中に適当に書いている。その内わかれば追記する。


次は、プルダウンの選択をPython側に送って、Excelシートの売上台帳に記入することをやります。果たして出来ますでしょうか。



以上です。