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

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

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

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

Python

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

解決済

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

miraMirar
miraMirar

総合スコア0

openpyxl

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

Python

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

1回答

0評価

0クリップ

1780閲覧

投稿2021/04/21 05:10

編集2022/01/12 10:58

前提・実現したいこと

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

import glob import re import pandas as pd import openpyxl from openpyxl.styles import Font import numpy as np import os #すべてのフォルダ内の該当ファイルを取得,商品名リスト生成 files = glob.glob('2021/**/商品名*.xlsx') items = [0] for file in files: wb = openpyxl.load_workbook(file) sheet = wb[sheet1] item = sheet['A1'].value items.append(item) items = items[1:] #表にしてエクセルで保存 df = pd.DataFrame([items], columns='商品名']) df.index = df.index+1 df.to_excel('商品リスト.xlsx', sheet_name='リスト') #エクセルを開いて編集 book = openpyxl.load_workbook('商品リスト.xlsx') sheet = book['リスト'] font_link = Font(color="0000ff") n_items = len(df)+1 #商品の数+タイトル行

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

Python

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

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

試したこと

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

Python

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

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

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

回答いただいた内容に従って
for 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[row]+','+files[row]+')'

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

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

openpyxl

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

Python

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