質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

7785閲覧

Pythonでopenpyxlを使って表中にハイパーリンクを自動生成したい

miraMirar

総合スコア10

openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/04/21 05:10

編集2021/04/22 10:36

前提・実現したいこと

Pythonでエクセルファイルを作成し、その中にディレクトリへのハイパーリンクを張りたいです。

発生している問題・エラーメッセージ

Pythonのファイルが置いてあるディレクトリと同じ階層に以下のような構成のディレクトリがあります。

2021/
フォルダ1/商品TD-1.xlsx, 議事録.docx
フォルダ2/商品AR-2.xlsx, 販促.xlsx
フォルダ3/商品TDW-5.xlsx, 資料.xlsx, memo.docx
フォルダ4/商品ASR-3.xlsx, フォルダ4-1/写真.jpg

この2021というフォルダからPythonで「商品*.xlsx」というファイルのみを探します。
「商品*.xlsx」はすべてsheet1¥A1セルに商品名が入っており、これを取得して一覧表を作成します。
これをxlsxファイルとして保存します。
そして、エクセルファイル上で商品名をクリックすると「フォルダx」が開くようにしたいです。
各商品と紐づいた関連資料を探せるようにするのが目的です。

該当のソースコード

まず以下のコードで、表を作成してエクセルを編集できるところまでいきました。

Python

1import glob 2import re 3import pandas as pd 4import openpyxl 5from openpyxl.styles import Font 6import numpy as np 7import os 8 9#すべてのフォルダ内の該当ファイルを取得,商品名リスト生成 10files = glob.glob('2021/**/商品名*.xlsx') 11items = [0] 12 13for file in files: 14 wb = openpyxl.load_workbook(file) 15 sheet = wb[sheet1] 16 item = sheet['A1'].value 17 items.append(item) 18 19items = items[1:] 20 21#表にしてエクセルで保存 22df = pd.DataFrame([items], columns='商品名']) 23df.index = df.index+1 24df.to_excel('商品リスト.xlsx', sheet_name='リスト') 25 26#エクセルを開いて編集 27book = openpyxl.load_workbook('商品リスト.xlsx') 28sheet = book['リスト'] 29font_link = Font(color="0000ff") 30n_items = len(df)+1 #商品の数+タイトル行

生成したエクセルファイルはA列に番号、B列に商品名が入っており、1行目がタイトル、2行目以降が商品名です。
この商品名をクリックすると、フォルダが開くようにします。
ハイパーリンクは以下のように書きたいです。
openpyxlのhyperkinkモジュールを使うと、ファイルは開いたのですがフォルダを開くことができなかったのでexcelのHYPERLINK関数を書き込む形にしています。

Python

1sheet['B2'].value = '=HYPERLINK("2021/フォルダ1","TD-1")' #TD-1は商品名 2sheet['B2'].font = font_link

これをdirectories(ディレクトリ名のリスト;下記)とitems(商品名のリスト)を使って自動で行いたいです。

試したこと

以下のように書いたところ、list object is not callableというエラーが出ました。

Python

1directories = list(map(os.path.dirname, files)) #ディレクトリのパス 2for row in sheet.iter_rows(min_col=2, mac_col=2, min_row=2, max_row=n_items): 3 for cell in row: 4 cell.value = 'HYPERLINK(' + directories(row)+','+items(row)+')'

うまくいく方法がありましたら教えてください。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

回答いただいた内容に従って

Python

1for row in sheet.iter_rows(min_col=2, min_row=2, max_col=2, max_row=n_reports): 2 for cell in row: 3 cell.value = '=HYPERLINK('+directories[row]+','+files[row]+')'

と書くとPythonのエラーは出なくなりました。ただ、生成したexcelを開こうとすると
「”.xlsx”の一部の内容に問題が見つかりました。可能な限り内容を回復しますか? ブックの発行元が信頼できる場合は、[はい]をクリックしてください」という警告が出て
[はい]で開くとB列2行目以降の商品名が空欄になった状態で出てきました。
これは、セル内に「=HYPERLINK(“パス名”,”表示文字列”)」と書かなければならないところが
「=HYPERLINK(パス名,表示文字列)」になっていたためで、以下のように修正したところ解決しました。

Python

1for i, row in enumerate(sheet.iter_rows(min_col=2, min_row=2, max_col=2, max_row=n_reports)): 2 for cell in row: 3 cell.value = '=HYPERLINK("'+directories[i]+'","'+titles[i]+'")'

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

items(row) で、リストであるdirectoriesの後ろに()を付けて関数のように呼び出すことは出来ません。

というエラーメッセージです。

python

1directories = list(map(os.path.dirname, files)) #ディレクトリのパス 2for i, row in enumerate(sheet.iter_rows(min_col=2, mac_col=2, min_row=2, max_row=n_items)): 3 for cell in row: 4 cell.value = '=HYPERLINK(' + directories[i]+','+items[i]+')'

と変えれば、このエラーは出なくなるでしょう。

投稿2021/04/21 07:43

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miraMirar

2021/04/22 10:34 編集

ありがとうございます! 最初に for i, row in sheet.iter_rows(min_col=2, min_row=2, max_col=2, max_row=n_reports): for cell in row: cell.value = '=HYPERLINK('+directories[i]+','+files[i]+')' としたらnot enough values to unpackというエラーが出ていたのですが、enumerateを使えばよいのですね。 おかげできちんと動くようになりました。助かりました。 ただ、リンクの書き方にも問題があり、そちらは自己解決したので質問本文に追記しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問