エクセルファイルからCSVを吐き出すツールをexe化、公開まで


はじめに

Pythonでエクセルファイルからシート含めて一括でCSVを生成するツールを作ったので
それをリリースする手順をまとめます。

ツール内容

今回作成したツールはこちら
プログラム環境以外でも使える様にexeも用意してます。
exeファイルの方はエクセルがあるフォルダに入れてダブルクリックしてください。

exe

GitHub

2020/05/09追記
申し訳ございません!!
公開したと書きつつプライベートのままでした。。
公開しました。。。

経緯

TAの仕事をしているとよくCSVファイル、Jsonファイルを用意してごにょごにょが総じてあります。
しかし、CSVファイルのままだとセルの幅が崩れたとりと非常に入力しづらい。。
なので、エクセルで管理するが..今度は別名保存にして入力先が変わったりととにかく面倒..
そこでこの辺りを自動化するツールを作りつつ、
ついでにGitHubの公開回りまでをやってみたかったので作ってみました。

開発環境

  • Window10
  • Python3.8
  • Pythonパッケージ
    • Pipenv 2018.11.26(仮想環境用)
    • openpyxl 3.0.3(エクセルファイル読み込み)
    • PyInstaller 3.6(exe化)

ツール内容

内容的には結構シンプルです。
openpyxlのライブラリでエクセルファイルを読みとり、各シートをcsvで吐き出す感じです。
解説等は割愛させていただきますが、ご要望があれば...

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""同じディレクトリのエクセルファイルを一括でcsv化する
"""
import os
import sys
import csv
import openpyxl
# PyInstallerの__file__問題回避
if hasattr(sys, "frozen"):
    SEARCH_FILE_DIRECTORY = os.path.dirname(sys.argv[0])  # "..\\[exe_folder]"
# ファイル実行時
else:
    SCRIPT_PATH = os.path.dirname(__file__)  # "..\\src\\csv-masher"
    SRC_PATH = os.path.dirname(SCRIPT_PATH)  # "..\\src"
    SEARCH_FILE_DIRECTORY = os.path.join(SRC_PATH, "sample_file")  # "..\\src\\Sample"
EXCEL_EXTENSION = ".xlsx"
CSV_EXTENSION = ".csv"

class CSVMasher(object):
    """メイン生成機能
    """
    def __init__(self):
        self.__excel_files = []
        self.set_excel_files(self.__search_excel_file(SEARCH_FILE_DIRECTORY))
    def create_csv_file(self):
        """csvファイルを生成する
        """
        for excel_file in self.__excel_files:
            excel_name = os.path.basename(excel_file).split(".")[0]
            excel_current_directory = os.path.dirname(excel_file)
            book = openpyxl.load_workbook(excel_file, read_only=True, keep_vba=False)
            for sheet in book.worksheets:
                sheet_name = sheet.title
                export_name = "{excel_name}_{sheet_name}{extension}".format(excel_name=excel_name, sheet_name=sheet_name, extension=CSV_EXTENSION)
                export_csv_path = os.path.join(excel_current_directory, export_name)
                with open(export_csv_path, "w", encoding="utf-8") as f:
                    writer = csv.writer(f)
                    for cols in sheet.rows:
                        writer.writerow([str(_.value or "") for _ in cols])
    def __search_excel_file(self, search_directory):
        """エクセルファイルを取得する
        """
        hit_files = []
        for dir_path, dir_list, file_list in os.walk(search_directory):
            for file_name in file_list:
                if EXCEL_EXTENSION in file_name:
                    hit_files.append(os.path.join(dir_path, file_name))
        return hit_files
    def get_excel_files(self):
        """エクセルファイルを取得する
        Returns:
            list: エクセルのパスリスト
        """
        return self.__excel_files
    def set_excel_files(self, excel_files):
        """エクセルファイルをセットする
        Args:
            excel_files (list): excelのファイルパスリスト
        """
        self.__excel_files = excel_files

if __name__ == "__main__":
    csv_masher = CSVMasher()
    print(csv_masher.get_excel_files())
    csv_masher.create_csv_file()

公開する

中身作ったので公開!!っといきたい所ですが、
exe化したり、公開するにあたり考える事があります。

1.ライブラリのライセンスを確認する

今回exe化しているので、パッケージを取り込んでしまいます。
その場合ライブラリのライセンス的には「同封」となり、
通常の「使用」とは違う方法となるので、ライセンスを確認する必要があります。
(この辺り簡単な方法ご存じの方情報求ム)

1-1.パッケージのライセンスを収集する

今回依存関係も含めて使用するパッケージは下記
1つのライブラリのインポートだけですが、依存関係も考えると芋づる式に増えていくと思います..

  • openpyxl==3.0.3
    • Excel 2010のxlsx / xlsm / xltx / xltmファイルを読み書きするためのPythonライブラリ
    • MIT License (MIT)
      • et-xmlfile==1.0.1
        • MIT License (MIT)
        • openpyxlが使用。XMLファイル生成ライブラリ
      • jdcal==1.4.1
        • BSD License (BSD)
        • 日付の変換ライブラリ

1-2.exeファイルと一緒にLICENSEファイルを同封する

基本的に同封した場合著作権表示とライセンス文が義務付けされるので、
openpyxlとそれと依存関係にあるet-xmlfile、jdcalを著作権表示をしたら良いと考えます。
ライセンス文がかなり長くなりますが、表示せず意図せず作者を傷つけるよりはよいかなっと思います。

参考

2.exeファイルのリリース方法を考える

いくつか方法はありますが、
今回は勉強もかねて、GitHubのリリース機能で行きたいと思います。

使い方はこちらの記事がわかりやすいので、おすすめです。

3.実際に公開する

無事リリース完了。

4.ついでにGitHubのRepositoryも公開する

RepositoryのSettingsを開き

下にスクロールし、何やら怖い言い回しですが、DangerZone欄のMake publicで完了。

まとめ

思いのほか大変でした。。
特にライセンス回りは普通にimportして使うときは問題になりませんが、
exe化する場合気をつける必要がありそうです。