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] EelでExcelの表から特定の項目を抽出するアプリを作る

Posted at

はじめに

はじめまして、未経験/独学からフロントエンドエンジニアとしての就職を目指しているYuuhaと申します。
技術力向上のため、日々新しい技術を取り入れて学習するようにしています。

今回は、デスクトップアプリを一度作成してみたいと思っていたので、Eelを使用してExcelを扱うアプリを作った時の話です。

制作の背景

何か問題解決のために技術を使いたいと思い、身内に聞き取りをしてみたところ、「Excelの表から特定の項目だけ抽出して新しいExcelに変換する機能が欲しい」ということでアプリの内容が決まりました。

Eelを選んだ理由は単純で、Pythonなら少し触ったことがあったこと、早くリリースするために学習コストがかからないHTML,CSSでUIが実装できるという点がポイントでした。

制作したもの

今回制作したものは、学習目的かつ、実際に機能することと早くリリースすることを優先していたので、プロダクトとしてのクオリティは保証できないので、その点はご了承ください。

アプリの概要

アプリの概要は下のような表があった場合、特定の項目(列)を抽出したい(例えば、itemAとitemDの列だけ抜き出して2×2の表を作る)という簡単なものです。

itemA itemB itemC itemD
1 A-1 B-1 C-1 D-1
2 A-2 B-2 C-2 D-2

表が上記のようなパターンのみであれば、PythonのライブラリのPandasを利用すれば簡単に実現できます。ただし、大きく分けて以下の3パターンのような特殊なパターンの表があったので、その場合にも対応できるようにしたいと思います。

1.表の項目が複数ある場合

以下のような表の場合、itemCは合計の値(itemCの最後の列)だけ抽出します。

itemA itemB itemC
itemC-1 itemC-2 itemC-3 合計
1 A-1 B-1 C-11 C-12 C-13 C-sum1
2 A-1 B-1 C-11 C-22 C-23 C-sum2

2.Excelのシート1枚に対して複数の表が存在する場合

以下のような場合、各列の項目が一致しないので、各表ごとに分割して処理する必要があります。

itemA itemB itemC
1 A-1 B-1 C-1
2 A-2 B-2 C-2
itemA itemD itemE
1 A-1 D-1 E-1
2 A-2 D-2 E-2

3.目的となる表以外に関係のない表が存在する

こちらも似たような処理ですが、必要ない表は無視して進める処理が必要になります。
(この場合、上の表が必要ないものになります)

単価 数量 単位
1 100 5 kg
2 200 2 L
itemA itemB itemC
1 A-1 B-1 C-1
2 A-2 B-2 C-2

以上の3パターンに対応できるように実装しました。次の項で、今回それぞれのパターンに合わせて行った実装を紹介します。

Excel処理部分の実装の概要

複数の表がある場合、各表ごとに分割する

詳しい解説は省きますが、groupby()によって空白の行があればそこを境界として表を分割し、dropna()で空白行を消去しています。

input_file = pd.ExcelFile(pathnames)
    sheet_names = input_file.sheet_names
    
    for sheet_name in sheet_names:
        main_columns = {}
        for i in range(max):
            main_columns[i] = {}
        df = pd.read_excel(p,index_col=None,header=None,sheet_name=sheet_name)
        filtered_df = df.iloc[1:,:end]
        dfg = filtered_df.groupby((df.isnull().all(axis=1)).cumsum())

        for index, g in dfg:
            g = g.dropna(how="all")
            if len(g) > 0:
                g = g.values
                d = pd.DataFrame(g[1:,:], columns=g[0])
            

分割した表をさらに項目ごとに分解する

下記で登場するdivisionsは列の項目の始点の番号です。したがって、2つ目以降のdivisionsの1つ前の番号は、1つ前の項目の最終列になります。なので、下記のようにcolumn_itemはすべての列の項目の最終列に該当します。

                    #上記の続き
                    num = 0
                        prev = 0
                        for i in divisions:
                            if i >= 1:
                                if num == 0:
                                    column_item = d.iloc[:,0:i]
                                else:
                                    column_item = d.iloc[:,prev:i]
                                num += 1
                                prev = i

実装の基本的な考え方は以上となります。あとは、抽出したい項目などをsqlite3などのデータベースを使用して記録・呼び出しすることで、表の抽出ができるようにしました。

まとめ

以上が今回制作したデスクトップアプリの概要でした。
より良い実装方法や間違いなどございましたら、コメントなどでご指摘いただけると幸いです。
もし、このアプリを使用したいという方は、githubのリポジトリからdist.zipにexeファイルが入っているので、そちらをご利用ください。(exeファイル化には、pyinstallerを使用しているので、ウイルスファイル扱いされる可能性があります。その点はご注意ください。)

アプリの内容自体は簡単なものでしたが、新しい言語を学習することで、これまで触っていた言語の復習になったり、新しい発見があったりしたので、これからもいろいろな分野に触れていこうと思います。

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?