残プロ　第-28回　~Flaskでcsvを操作する~

# Bootstrapで表を作成

表の各要素にフォームを作成することで，セルごとに編集できるようになっています．
関数getCSVでは取得した配列を文字列に変換し，変数の受け渡しを実現しています．

~~~ html:csv.html
{% extends 'layout.html' %}

{% block content %}
    <table class='table'>
        <thead>
            <tr>
                <th scope='col'>
                    <div class="form-group">
                        <input type="text" id="00" class="form-control" placeholder={{ csv_file[0][0] }}>
                    </div>
                </th>
                <th scope='col'>
                    <div class="form-group">
                        <input type="text" id="01" class="form-control" placeholder={{ csv_file[0][1] }}>
                    </div>
                </th>
                <th scope='col'>
                    <div class="form-group">
                        <input type="text" id="02" class="form-control" placeholder={{ csv_file[0][2] }}>
                    </div>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope='row'>
                    <div class="form-group">
                        <input type="text" id="10" class="form-control" placeholder={{ csv_file[1][0] }}>
                    </div>
                </th>
                <td>
                    <div class="form-group">
                        <input type="text" id="11" class="form-control" placeholder={{ csv_file[1][1] }}>
                    </div>
                </td>
                ...
                <td>
                    <div class="form-group">
                        <input type="text" id="32" class="form-control" placeholder={{ csv_file[3][2] }}>
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    <button type="button" class="btn btn-primary" onClick="getCSV();">取得</button>
    <a id="save" href="{{ url_for('save', saving_file=csv_file) }}">保存</a>
    <script>
        let id;
        let element;
        const row_n = {{ row_n }};
        const column_n = {{ column_n }};
        let saving_file = []

        function getCSV(){
            for (let i=0; i<row_n; i++) {
                let temp = []
                for (let j=0; j<column_n; j++) {
                    id = String(i) + String(j);
                    element = document.getElementById(id);
                    if (element.value == "") {
                        temp[j] = element.placeholder;
                    }
                    else {
                        temp[j] = element.value;
                    }
                }
                temp = temp.join()
                saving_file[i] = temp
            }
            saving_file = saving_file.join()
            console.log(saving_file)
        }
    </script>
{% endblock %}
~~~


# Flaskで.csvの読込，保存

正規表現を使ってスペースと[]の削除をしたのち，splitメソッドを使用しています．
今回扱っている配列は２次元配列のため，スライスを用いて配列を成形します．


~~~ python:
from flask import Flask, render_template, url_for
import csv
import re

app = Flask(__name__)

@app.route('/')
def csv_show():
    csv_file = []
    with open('test.csv') as f:
        reader = csv.reader(f)
        for row in reader:
            csv_file.append(row)
    row_n = len(csv_file)
    global column_n
    column_n = len(csv_file[0])
    return render_template("csv.html", csv_file=csv_file, row_n=row_n, column_n=column_n)

@app.route('/save/<string:saving_file>')
def save(saving_file):
    saving_file = re.sub('(\[|\'|\]|\s)', '', saving_file).split(',')
    saving_file = [saving_file[i:i+column_n] for i in range(0, len(saving_file), column_n)]
    with open('test_save.csv', 'wb') as f:
        writer = csv.writer(f)
        writer.writerows(saving_file)
    return render_template("csv.html", csv_file=saving_file)



if __name__ == '__main__':
    app.run(debug=True)
~~~