Flask

Flask・Ajax・jQueryを利用してCSVファイルを取り込み表形式に変換するWebアプリケーションを作成してみた

Pythonのcsvパッケージやjsonパッケージを利用すると、CSVファイルのデータをJSON形式に簡単に変換することができる。また、AjaxとjQueryを利用すると、JSON形式で受け取ったデータを画面上に表示することができる。

今回は、Flask・Ajax・jQueryを利用して、CSVファイルを取り込み表形式に変換するWebアプリケーション作成してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事のFlaskによる環境構築と実装が完了していること。

Pythonフレームワーク「Flask」を利用したWebアプリケーションを作成してみたFlaskは、Pythonで開発する際のWebフレームワークの1つで、マイクロフレームワーク(軽量で必要最低限の機能が搭載されているフレ...

また、下記記事のchardetパッケージのインストールが完了していること。

Pythonフレームワーク「Flask」を利用したWebアプリケーションでCSVファイルを取り込みJSON形式に変換してみたPythonのcsvパッケージやjsonパッケージを利用すると、CSVファイルのデータをJSON形式に簡単に変換することができる。 ...

サンプルプログラムの作成

作成したサンプルプログラムの構成は、以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。

jquery-3.7.1.jsは、以下のjQuery公式サイトから、赤枠のuncompressed版をダウンロードしている。
https://jquery.com/download/

jQueryのダウンロード

また、index.htmlの内容は以下の通りで、CSVファイルを取り込む部分と、CSV取込結果が表形式で出力する領域を追加している。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <script src="../static/jquery-3.7.1.js"></script>
    <script src="../static/demo.js"></script>
    <title>CSVファイル取込</title>
</head>
<body>
    取り込んだCSVファイルのデータを、JSON形式に変換後、表形式で出力します。
    <br/><br/>
    <form enctype="multipart/form-data">
        <input type="file" id="csv_file" name="csv_file" /> 
        <input type="button" value="CSV取込" onclick="import_csv()" />
        <br/><br/>
        <div id="show_result">~ここにCSV取込結果が表形式で出力されます~</div>
    </form>
</body>
</html>

さらに、demo.jsの内容は以下の通りで、チェック処理と、views.pyのパス(/import-csv)をAjaxで呼び出し、Ajax戻り値(JSON形式で受け取ったCSV取込結果)を画面に表形式で出力する処理を実装している。

'use strict';

// CSV取込ボタン押下処理
function import_csv(){
  const csv_file = $('#csv_file').prop('files')[0];
  if(!csv_file){
    alert("取り込むCSVファイルを選択してください");
    return;
  }
  if(csv_file.name.substring(csv_file.name.length - 4).toLowerCase() !== ".csv"){
    alert("ファイルの拡張子がCSVファイルでありません");
    return;
  }
  if(csv_file.size === 0){
    alert("CSVファイルが空になっています");
    return;
  }
  const form_data = new FormData();
  form_data.append("csv_data", csv_file);
  $.ajax("/import-csv", {
     type: "post"
    , data: form_data
    , processData: false
    , contentType: false
  }).done(function(received_data){
    // 読み込んだCSVファイルのデータをJSONオブジェクトに変換
    const dict = JSON.parse(received_data);

    // 読み込んだCSVファイルのデータを表示するテーブルを作成
    const json_tbl = $("<table><tbody>");

    // 読み込んだCSVファイルのカラム行を追加
    const headers = Object.keys(dict[0]);
    let json_tbl_line = $("<tr></tr>");
    for (let i = 0; i < headers.length; i++){
      json_tbl_line.append($("<th>" + headers[i] + "</th>"));
    }
    json_tbl_line.appendTo(json_tbl);

    // 読み込んだCSVファイルのデータ行を追加
    dict.forEach(item => {
      json_tbl_line = $("<tr></tr>");
      for (let i = 0; i < Object.values(item).length; i++){
        json_tbl_line.append($("<td>" + Object.values(item)[i] + "</td>"));
      }
      json_tbl_line.appendTo(json_tbl);
    });

    // 作成したテーブルを画面に表示
    // その際、「~ここにCSV取込結果が表形式で出力されます~」の文字列を削除する
    $("</tbody></table>").appendTo(json_tbl);
    $("#show_result").empty().append(json_tbl);
    json_tbl.attr('border', '1');
    json_tbl.attr('cellspacing', '0');
    json_tbl.attr('cellpadding', '10');
    json_tbl.find("th").attr('bgcolor', 'skyblue');
  }).fail(function() {
    alert("CSV取込に失敗しました");
  });
}

また、views.pyの内容は以下の通りで、CSV取込ボタン押下処理を追加している。

from demo import app
from flask import render_template, request
from .csv_json import CsvToJson


# 初期表示処理
@app.route("/")
def index():
    return render_template("index.html")


# CSV取込ボタン押下処理
@app.route('/import-csv', methods=['POST'])
def import_csv():
    # CSVファイルのデータをJSONに変換して返す
    csv_json = CsvToJson(request.files["csv_data"].stream)
    return csv_json.upload_csv_to_json()

さらに、csv_json.pyの内容は以下の通りで、views.pyから呼ばれる、取り込んだCSVファイルのデータをJSON形式に変換する処理を実装している。

import io
import json
import csv
from chardet import detect


# CSVファイルのデータをJSONに変換するクラス
class CsvToJson:

  # 引数にCSVファイルを渡してインスタンスを生成
  def __init__(self, req_file_stream):
    self.req_file_stream = req_file_stream

  # CSVファイルのデータをJSONに変換して返す
  def upload_csv_to_json(self):
    # CSVファイルの文字コードを判定
    # 判定した文字コードがSHIFT_JISの場合は、CP932に変換する
    encoding = detect(self.req_file_stream.read())['encoding']
    if "SHIFT_JIS" == encoding:
      encoding = "CP932"

    # アップロードしたCSVファイルを読み込み、json_listに追加する
    self.req_file_stream.seek(0)
    io_stream = io.TextIOWrapper(self.req_file_stream, encoding=encoding)
    json_list = []
    csv_reader = csv.DictReader(io_stream)
    for row in csv_reader:
      json_list.append(row)
    io_stream.close()

    # json_listをJSON形式に変換した値を返す
    # ensure_ascii=Falseを指定することで、日本語のままJSON文字列を出力する
    # indent=2を指定することで、読みやすく改行したJSON文字列になる
    return json.dumps(json_list, ensure_ascii=False, indent=2)

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/python/tree/master/make-flask-csv-to-table/

エンジニアファーストバナー

サンプルプログラムの実行結果

サンプルプログラムの実行結果は、以下の通り。

1) コマンドプロンプトでserver.pyが入っているフォルダに移動し、server.pyを実行する。
サンプルプログラムの実行結果_1

2) Webブラウザで「http://127.0.0.1:5000/」とアクセスすると、以下のように、index.htmlの画面が表示される。
サンプルプログラムの実行結果_2

3) 取込対象となるCSVファイルの内容は以下の通りで、文字コードがUTF-8になっているものとする。
サンプルプログラムの実行結果_3

4) 3)のファイルを指定し、「CSV取込」ボタンを押下する。
サンプルプログラムの実行結果_4

5) 以下のように、取り込んだCSVデータが表形式で画面に表示されることが確認できる。
サンプルプログラムの実行結果_5

6) UTF-8以外の文字コードをもつ場合でも、以下のように、CSVファイルのデータを表形式で表示できることが確認できる。
サンプルプログラムの実行結果_6_1

サンプルプログラムの実行結果_6_2 サンプルプログラムの実行結果_6_3

7) CSVファイルのチェックエラー時の処理は、以下のサイトの「サンプルプログラムの実行結果」7)~9)を参照のこと。

Pythonフレームワーク「Flask」を利用したWebアプリケーションでCSVファイルを取り込みJSON形式に変換してみたPythonのcsvパッケージやjsonパッケージを利用すると、CSVファイルのデータをJSON形式に簡単に変換することができる。 ...

要点まとめ

  • Pythonのcsvパッケージやjsonパッケージを利用すると、CSVファイルのデータをJSON形式に簡単に変換することができる。
  • AjaxとjQueryを利用すると、JSON形式で受け取ったデータを画面上に表示することができる。