見出し画像

アマゾン購買履歴のCSVからエクセルに

購買履歴のCSVをダウンロードするには

確定申告の基礎資料を作成するためと、過去に購入した本の一覧とURLを取得したいと思い立ちPythonでプログラムを書いてみました。CSVの解析と展開のしかたに手間取りました。ChatGPT に幾度か問い合わせを行い試行錯誤をしました。ほぼ「コピペ」ですのでプログラムを書いたのは数時間です。試行錯誤の方が圧倒的に時間が長かったです。
アマゾンの購買履歴のCSVをダウンロードする方法や、エクセルに展開する方法を教えてくれるホームページがあります。残念ながら、アマゾン・ビジネスでは使えないようです。

アマゾン購買履歴CSVの特徴

このCSVは、エクセルに展開することを想定しているようで、かなり複雑な構造をしています。
・単価と運賃と請求金額は別の行に書かれいます。CSVをエクセルに出力し分析する方が早かったと感じてます。
・Kindle などのデジタルデータは別ファイルのCSVでダウンロードが可能で、CSVの構図は同じようです。
・購買した本だけを抽出したエクセルファイルも作りたかったのでフィルターで対象となるデータを絞りました。その結果、著者の記載の無い雑誌などは対象から外れました。

Pythonのプログラム

《amazon_csv_data》のフォルダー名を作成し、このフォルダーの中に複数のファイルを入れれば全て集計してエクセルに展開します。
* windowsでは検証していません。

################
import os
import csv
from datetime import datetime

# ###############
# ○ はじめに指定のフォルダー内の複数のCSVファイル名を読み込みます.
# ###############
csv_data_list = []
data_list = []
folder_path = "./amazon_csv_data/"

# ○ 複数のCSVファイルからcsv_data_listを作成
file_list = os.listdir(folder_path)  # import os の機能を利用して file_listを作ります。
# 隠しファイルを取り除く(windows 対応)。 リスト内包表記の記述方式で List を整形。
file_list = [filename for filename in file_list if not (filename.startswith('.') or '~$' in filename)]

csv_data_list_m = []
data_list_unchin = []
# 複数のCSVファイルからcsv_data_listを作成。ファイルごとに処理を行う
for file_name in file_list:
    if file_name.endswith(".csv"):  # 拡張子が.csvのファイルを対象とする
        file_path = os.path.join(folder_path, file_name)
        #print(file_path)
        i = 0
        header_num = 1  # 
        # CSVファイルを読み込む。
        with open(file_path, encoding="utf-8") as f:
            csv_reader = csv.reader(f)

            for i, row in enumerate(csv_reader, start=1):
                # i を入れて行番号も取得する
                if i <= header_num or row == []:
                    continue

                #print(file_name)
                if row[5] != '' and row[6] != '':
                    data_list_meisi = [None, None, None, 0, 0, 0, None, None]
                    date_str = str(row[0])
                    # 文字列を datetime オブジェクトに変換
                    date_obj = datetime.strptime(date_str, '%Y/%m/%d')
                    # 必要な形式で文字列に変換
                    formatted_date = date_obj.strftime('%Y/%m/%d')
                    data_list_meisi[0] = formatted_date
                    data_list_meisi[1] = row[2][0:34]
                    text = row[3][0:20]
                    keyword = '販売:'  # 本の場合には'販売:'の前に著者名があるので
                    start_index = text.find(keyword)
                    # extracted_text = ''
                    if start_index != -1:
                        extracted_text = text[0:start_index]
                        text = extracted_text.rstrip()
                        text = text.replace(', ', ' ').replace(' ', '')
                        # print(text)

                    data_list_meisi[2] = text
                    data_list_meisi[3] = int(row[6])
                    data_list_meisi[6] = row[1]
                    data_list_meisi[7] = row[17]
                    #print(row[17])

                    data_list.append(data_list_meisi)
                    #print(row)
                    #print(data_list_meisi)

                elif row[2] == '(配送料・手数料)':  # 運賃の data_list_unchin を同時に作る
                    data_list_un = [None, None, 0]
                    data_list_un[0] = row[0]
                    data_list_un[1] = row[1]
                    data_list_un[2] = int(row[6])
                    data_list_unchin.append(data_list_un)
                    #print(data_list_un)

#print('*******')
book_list = []  # 本だけのリストを作る
oder_no = ''

for row in data_list:
    if row[2] != '':
        book_list.append(row)

for row in book_list:
    order_no = str(row[6])
    #print(oder_no)
    matching_elements = [item[2] for item in data_list_unchin if item[1] == order_no]
    # 注文No が一致した場合の処理
    #print(matching_elements)
    if matching_elements:
        # matching_elements に値がある場合の処理
        value = matching_elements[0]  # 例として最初の値を取り出す
        #print("値があります:", value)
        row[4] = int(value)
        #print(row)
        row[5] = value + row[3]

    row[5] = row[3] + row[4]  # 支払合計

book_list.sort(key=lambda x: x[0])  # 日付順にソート

# book_list[6] 注文No を 空白に
for row in book_list:
    row[6] = ''

    #print('new', row)

# ###### ############# #############
# ここから下はデータをエクセルに展開します。

# ############
# エクセル出力 
# ############
import openpyxl
from openpyxl.styles import Alignment, PatternFill, Font, Border, Side

# 下線のスタイルを定義 関数化
def set_underline_to_row(worksheet, row_num):
    underline = Side(border_style="thin", color="000000")  # 下線のスタイルを定義
    border = Border(bottom=underline)  # 下線を設定
    for i in range(1, worksheet.max_column - 1):
        cell = worksheet.cell(row=row_num, column=i)
        cell.border = border

# セルのスタイルを定義
def set_color_row(worksheet,row_num,str_column,end_column):
    underline = Side(border_style="thin", color="000000")
    border = Border(bottom=underline)  # 下線を設定
    fill_0 = PatternFill(patternType='solid', fgColor='FFFF00')  # 黄色
    for i in range(str_column, end_column):
        # print("row:", row_number)
        worksheet.cell(row=row_num, column=i).fill = fill_0
        cell = worksheet.cell(row= row_num -1, column= i)
        cell.border = border

# ############
# ここからエクセルに展開
# ############
workbook = openpyxl.Workbook()
worksheet = workbook.active
worksheet.title = "(本)アマゾン注文一覧"  # 新しいシート名を設定

# ヘッダー(項目)を追加 書式を設定
headers = ['日付', '署名', '著者名', '金額', '運賃', '総額', '', 'URL']
worksheet.append(headers)
for cell in worksheet['1']:
    cell.alignment = Alignment(horizontal='center', vertical='center')  # セルを中央寄せにする
    fill_1 = PatternFill(patternType='solid', fgColor='d9e367')  # シャトルーズグリーン
    for i in range(1, 9):
        worksheet.cell(1, column=i).fill = fill_1
# 下線を引く 
target_row = 1
set_underline_to_row(worksheet, target_row)

# 列の幅を指定
column_widths = [12, 60, 28 , 10, 10, 10, 4, 80]
for i, width in enumerate(column_widths, start=1):
    worksheet.column_dimensions[openpyxl.utils.get_column_letter(i)].width = width

# Write the data into the Excel file
ii = 0
for row_data in book_list:
    ii += 1
    worksheet.append(row_data)

# 4、5、6列目 合計計算
row_max = worksheet.max_row
worksheet.cell(row_max + 1, column=4).value = '=sum(D2:D' + str(row_max) + ')'
worksheet.cell(row_max + 1, column=5).value = '=sum(E2:E' + str(row_max) + ')'
worksheet.cell(row_max + 1, column=6).value = '=sum(F2:F' + str(row_max) + ')'

# 最後に罫線を引く
row_num = row_max
set_underline_to_row(worksheet, row_num)

# 数値の書式を設定
for i in ['D', 'E', 'F']:
    for cell in worksheet[i]:
        cell.number_format = '#,##0'

# #######################
# ファイル名に 処理日、対象ファイルの月を計算
import datetime
# 現在の日付を取得
current_date = datetime.date.today()
syori_date = str(current_date)[2:]

file_name = "(本) 処理日:" + syori_date + 'アマゾン注文一覧.xlsx'

# print(file_name)
workbook.save(file_name)
workbook.close()

# #######################
# 申告用
# #######################
amazon_data = []

for row in data_list:
    # amazon_m = [None, None, None, 0, 0, 0, None]
    #print(len(row))
    amazon_m = row[:6]  # data_list 先頭の人ような要素を入れる
    amazon_m[5] = row[3] + row[4]  # 合計金額の計算
    amazon_m.append(row[7])  # URL を加える
    # amazon_m[6] = row[7] ではamazon_m[6] が存在しないのでエラーになります。
    # append(row[7])で要素を付け足します。 
    #print(row[7])

    amazon_data.append(amazon_m)  # 明細データを加える

amazon_data.sort(key=lambda x: x[0])  #

for row in amazon_data:
    print(row)

# ###### ############# #############
# ここから下はデータをエクセルに展開します。
# ############
# エクセル出力 
# ############
import openpyxl
from openpyxl.styles import Alignment, PatternFill, Font, Border, Side

workbook = openpyxl.Workbook()
worksheet = workbook.active
worksheet.title = "(全)アマゾン購入一覧"  # 新しいシート名を設定

# ヘッダー(項目)を追加 書式を設定
headers = ['日付', '署名', '著者名', '金額', '運賃', '総額', 'URL']
worksheet.append(headers)
for cell in worksheet['1']:
    cell.alignment = Alignment(horizontal='center', vertical='center')  # セルを中央寄せにする
    fill_1 = PatternFill(patternType='solid', fgColor='d9e367')  # シャトルーズグリーン
    for i in range(1, 8):
        worksheet.cell(1, column=i).fill = fill_1
# 下線を引く 
target_row = 1
set_underline_to_row(worksheet, target_row)

# 列の幅を指定
column_widths = [12, 60, 28 , 10, 10, 10, 80]
for i, width in enumerate(column_widths, start=1):
    worksheet.column_dimensions[openpyxl.utils.get_column_letter(i)].width = width

# Write the data into the Excel file
ii = 0
for row_data in amazon_data:
    ii += 1
    worksheet.append(row_data)


# 4、5、6列目 合計計算
row_max = worksheet.max_row
worksheet.cell(row_max + 1, column=4).value = '=sum(D2:D' + str(row_max) + ')'
worksheet.cell(row_max + 1, column=5).value = '=sum(E2:E' + str(row_max) + ')'
worksheet.cell(row_max + 1, column=6).value = '=sum(F2:F' + str(row_max) + ')'

# 最後に罫線を引く
row_num = row_max
set_underline_to_row(worksheet, row_num)

# 数値の書式を設定
for i in ['D', 'E', 'F']:
    for cell in worksheet[i]:
        cell.number_format = '#,##0'

# #######################
# ファイル名に 処理日、対象ファイルの月を計算
import datetime
# 現在の日付を取得
current_date = datetime.date.today()
syori_date = str(current_date)[2:]

file_name = "(全)処理日:" + syori_date + 'アマゾン購入一覧.xlsx'

# print(file_name)
workbook.save(file_name)
workbook.close()


この記事が気に入ったらサポートをしてみませんか?