PythonでQRコードを簡単に生成!qrcodeライブラリの基本的な使い方
QRコードは、URLやテキスト情報を簡単に共有できる便利な仕組みです。Pythonには「qrcode」というライブラリがあり、わずか数行のコードでQRコードを生成できます。本記事では、インストールから基本的な使い方、応用例までを解説します。
インストール方法
まずはライブラリをインストールしましょう。ターミナルやコマンドプロンプトで以下を実行します。
pip install qrcode[pil]
[pil]オプションを付けることで、画像処理ライブラリPillowも一緒にインストールされ、PNG画像として保存できるようになります。
基本的なQRコード生成
最もシンプルな使い方は以下の通りです。
import qrcode
# QRコードに埋め込むデータ
data = "https://techpara-blog.com"
# QRコード生成
img = qrcode.make(data)
# 画像を保存
img.save("qrcode_basic.png")
これだけで、指定したURLを含むQRコード画像が生成されます。
詳細設定を使ったQRコード生成
もう少し細かく制御したい場合は、QRCodeクラスを使います。
import qrcode
qr = qrcode.QRCode(
version=1, # QRコードのサイズ(1〜40)
error_correction=qrcode.constants.ERROR_CORRECT_H, # 誤り訂正レベル
box_size=10, # 1マスのピクセル数
border=4, # 外枠のマス数
)
qr.add_data("Hello, TechPara Blog!")
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save("qrcode_custom.png")
主なパラメータ
- version: QRコードのサイズ。大きいほど多くのデータを格納可能。
- error_correction: 誤り訂正レベル(L/M/Q/H)。Hは最も強力で、汚れや欠損に強い。
- box_size: 1セルのピクセル数。大きくすると画像が拡大される。
- border: 外枠のセル数。通常は4以上が推奨
Pythonのqrcodeライブラリを使えば、数行のコードでQRコードを生成できます。基本的な使い方から詳細設定まで理解すれば、ビジネスや趣味の場面で幅広く活用可能です。
「まずはURLをQRコード化してみる」ことから始めて、徐々にカスタマイズや応用に挑戦してみましょう!
応用編 ExcelのデータをQRコードに書き出す
製造業においては生産計画などExcelで管理したり出力したりすることもあるかと思います。Excelファイル内に列挙されたデータを一括でQRコードとして出力するためのPythonスクリプトを作ってみました。GUIで操作できるので現場でも受け入れてもらえるかもしれません。
スクリプトで使用する他のライブラリをインストール
pip3 install qrcode openpyxl
スクリプト全体
こちらのスクリプトをメモ帳などのコードエディタにコピペして実行してみましょう。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Requirements:
pip install qrcode[pil] openpyxl
Description:
- Select an Excel file (.xlsx/.xls) via a file dialog
- Read values from column A (first worksheet)
- Generate QR codes for each non-empty cell
- Output format selectable: SVG, PNG, JPG
- Scale selectable: 1–10 (box size)
- Saves files into an 'qrcodes_<format>_scale<scale>' folder next to the Excel file
"""
import os
import re
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
# QR code
import qrcode
from qrcode.image.svg import SvgImage, SvgPathImage, SvgFragmentImage
# Excel
from openpyxl import load_workbook
# -----------------------------
# Helpers
# -----------------------------
def sanitize_filename(s: str, fallback: str) -> str:
"""Make a safe filename from a string; use fallback if empty."""
if s is None:
return fallback
# Convert to string and strip
s = str(s).strip()
if not s:
return fallback
# Remove unsafe characters
s = re.sub(r'[\\/:*?"<>|]', '_', s)
# Limit length to avoid OS issues
return s[:150] if s else fallback
def read_column_a_values(excel_path: str):
"""Read non-empty values from column A in the active worksheet."""
wb = load_wb(excel_path)
ws = wb.active
values = []
for row in ws.iter_rows(min_row=1, max_col=1, values_only=True):
val = row[0]
if val is None:
continue
text = str(val).strip()
if text:
values.append(text)
return values
def load_wb(excel_path: str):
# openpyxl loads .xlsx; .xls is not supported. Warn if needed.
try:
return load_workbook(excel_path, data_only=True)
except Exception as e:
raise RuntimeError(f"Excelの読み込みに失敗しました: {e}")
def ensure_output_dir(excel_path: str, fmt: str, scale: int) -> str:
base_dir = os.path.dirname(os.path.abspath(excel_path))
out_dir = os.path.join(base_dir, f"qrcodes_{fmt.lower()}_scale{scale}")
os.makedirs(out_dir, exist_ok=True)
return out_dir
def make_qr(text: str, fmt: str, scale: int):
"""
Create a QRCode object for given text and format.
scale maps to box_size.
"""
# Common QR settings
qr = qrcode.QRCode(
version=None, # auto size
error_correction=qrcode.constants.ERROR_CORRECT_M,
box_size=max(1, int(scale)),
border=4
)
qr.add_data(text)
qr.make(fit=True)
if fmt.lower() == "svg":
# Use path-based SVG (smaller, cleaner)
img = qr.make_image(image_factory=SvgPathImage)
return img
else:
# PIL image for PNG/JPG
img = qr.make_image(fill_color="black", back_color="white")
return img
def save_qr(img, out_dir: str, base_name: str, fmt: str):
ext = fmt.lower()
filename = os.path.join(out_dir, f"{base_name}.{ext}")
# For JPG, enforce RGB (no alpha)
if ext == "jpg":
# PIL image path; convert if needed
try:
img = img.convert("RGB")
except Exception:
# SVG does not support convert; but we only call this branch for PIL images.
pass
img.save(filename)
return filename
# -----------------------------
# GUI Application
# -----------------------------
class QRApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("Excel A列 → QRコード生成")
self.geometry("640x400")
self.resizable(True, True)
self.excel_path = tk.StringVar(value="")
self.format_var = tk.StringVar(value="SVG")
self.scale_var = tk.IntVar(value=6)
self.create_widgets()
def create_widgets(self):
# Top frame: file selection
top = ttk.Frame(self, padding=(12, 12))
top.pack(fill="x")
ttk.Label(top, text="Excelファイル (.xlsx) を選択:").grid(row=0, column=0, sticky="w")
path_entry = ttk.Entry(top, textvariable=self.excel_path)
path_entry.grid(row=1, column=0, columnspan=2, sticky="ew", padx=(0, 8))
top.columnconfigure(0, weight=1)
select_btn = ttk.Button(top, text="参照...", command=self.select_excel)
select_btn.grid(row=1, column=2, sticky="e")
# Options frame
opts = ttk.LabelFrame(self, text="出力設定", padding=(12, 12))
opts.pack(fill="x", padx=12, pady=8)
ttk.Label(opts, text="フォーマット:").grid(row=0, column=0, sticky="w")
fmt_combo = ttk.Combobox(opts, textvariable=self.format_var, values=["SVG", "PNG", "JPG"], state="readonly", width=8)
fmt_combo.grid(row=0, column=1, sticky="w", padx=(8, 16))
ttk.Label(opts, text="スケール (1–10):").grid(row=0, column=2, sticky="w")
scale_spin = ttk.Spinbox(opts, from_=1, to=10, textvariable=self.scale_var, width=5)
scale_spin.grid(row=0, column=3, sticky="w", padx=(8, 0))
# Action buttons
actions = ttk.Frame(self, padding=(12, 0))
actions.pack(fill="x")
convert_btn = ttk.Button(actions, text="変換開始", command=self.convert)
convert_btn.pack(side="left")
# Log area
log_frame = ttk.LabelFrame(self, text="ログ", padding=(8, 8))
log_frame.pack(fill="both", expand=True, padx=12, pady=12)
self.log = tk.Text(log_frame, height=12, wrap="word")
self.log.pack(fill="both", expand=True)
def select_excel(self):
path = filedialog.askopenfilename(
title="Excelファイルを選択",
filetypes=[("Excel files", "*.xlsx"), ("All files", "*.*")]
)
if path:
self.excel_path.set(path)
self.append_log(f"選択: {path}")
def convert(self):
path = self.excel_path.get().strip()
fmt = self.format_var.get().strip().upper()
scale = int(self.scale_var.get())
if not path:
messagebox.showwarning("警告", "Excelファイルを選択してください。")
return
if not os.path.exists(path):
messagebox.showerror("エラー", "指定されたファイルが存在しません。")
return
if fmt not in {"SVG", "PNG", "JPG"}:
messagebox.showerror("エラー", "フォーマットが不正です。SVG/PNG/JPG から選択してください。")
return
try:
values = read_column_a_values(path)
except Exception as e:
messagebox.showerror("エラー", str(e))
self.append_log(str(e))
return
if not values:
messagebox.showinfo("情報", "A列に有効なデータが見つかりませんでした。")
self.append_log("A列にデータがありません。")
return
out_dir = ensure_output_dir(path, fmt, scale)
self.append_log(f"出力先: {out_dir}")
self.append_log(f"件数: {len(values)} / フォーマット: {fmt} / スケール: {scale}")
success = 0
for idx, text in enumerate(values, start=1):
try:
img = make_qr(text, fmt, scale)
base_name = sanitize_filename(text, fallback=f"row{idx}")
saved = save_qr(img, out_dir, base_name, fmt)
self.append_log(f"[OK] {idx}: {saved}")
success += 1
except Exception as e:
self.append_log(f"[NG] {idx}: {e}")
messagebox.showinfo("完了", f"変換完了: {success}/{len(values)} 件")
self.append_log("変換を完了しました。")
def append_log(self, msg: str):
self.log.insert("end", msg + "\n")
self.log.see("end")
# -----------------------------
# Entry point
# -----------------------------
def main():
app = QRApp()
app.mainloop()
if __name__ == "__main__":
main()

コメント