search
LoginSignup
16

More than 1 year has passed since last update.

posted at

updated at

pythonでレシートプリンターを操作する

関連記事

困っていること

まずは何あれ、問題定義!
私は、タスク管理ツールを何度も使ってみては、失敗してを繰り返しているのですが、それは、スマホでいちいちタスクを開くのが面倒くさいから、物理的に見えないからなのではないかと思い、プリンターで印刷してしまえばいいのではと思いこれらを作成しました。

機能

  • プリンターで文字と画像を印刷する
  • PILにフォントを設定する

使用するもの

設計

1. 設定とコーディング1

まずはプリンターの設定と何がレシートプリンターでどんな文字が印刷できるかの調査

pythonで使用するライブラリをインストール

pip install python-escpos
pip install Pillow

フォントはフリーのフォントを使用させていただきました。

フリーフォントサイト

プリンターでの印刷

from escpos.printer import Usb
from escpos import *

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# レシートプリンターを使った印刷

width = 500
height = 250

image = Image.new('1', (width, height), 255)
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('FLOPDesignFont.ttf', 50, encoding='unic')
draw.text((0, 0), "日本語" + " ", font=font, fill=0)
font = ImageFont.truetype('FLOPDesignFont.ttf', 28, encoding='unic')
draw.text((0, 82), "abcdefghijklmnopqrstuvwxyz", font=font, fill=0)
draw.text((0, 112), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", font=font, fill=0)
draw.text((0, 142), "1234567890" + " ", font=font, fill=0)
draw.text((0, 172), "!\"#$%&'()=~|+*<>?_{}" + " ", font=font, fill=0)

p = Usb(0x0416, 0x5011, 0, 0x81, 0x03)
p.text("Hello World\n")
p.image(image)
p.cut()

こちらを印刷したものが下記のようになります。
p.text("Hello World\n")でテキストを実行する場合、最初の位置文字が消えるので、気をつけてください。

IMG_20200620_103642.jpg

USBの設定

レシートプリンターで印刷する場合は、こちらを設定する必要があります。
それについて、確認していきます。

p = Usb(0x0416, 0x5011, 0, 0x81, 0x03)

まずは、lsusbを実行しましょう

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 006: ID 8087:07dc Intel Corp. 
Bus 001 Device 005: ID 0bda:579a Realtek Semiconductor Corp. 
Bus 001 Device 004: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
Bus 001 Device 003: ID 0bda:b812 Realtek Semiconductor Corp. 
Bus 001 Device 008: ID 0416:5011 Winbond Electronics Corp. Virtual Com Port
Bus 001 Device 002: ID 062a:4102 Creative Labs 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

下記のものがレシートプリンターに接続されているものです。
Bus 001 Device 008: ID 0416:5011 Winbond Electronicのs Corp. Virtual Com Port
この0416:5011の部分がUsb引数の1つめと、2つめとなります。

これだけでもsudoをつけて、root権限でpythonを実行すれば、印刷ができます。
このときに、一般ユーザーからもこのデバイスにアクセスできるように udev にルールを追加して、udev のルールを読み込ませてやります。

udev
簡単に説明するとUSBデバイスを抜き差ししても、このUSBが何かを管理してくれるものです。(正確にはリンクで確認してください。)

udevの設定
/etc/udev/rules.d/10-printer.rulesファイルを作成し、下記を記載します。
先のlsusbで デバイスID: 0416: 5011 が異なる場合には、こちらも合わせてください。

SUBSYSTEM=="usb", ATTR{idVendor}=="0416", ATTR{idProduct}=="5011", MODE="0666", GROUP="plugdev"

2. 設定とコーディング2

指定の画像をロゴごとして追加して印刷する
下記の画像を先程作成したデータに追加して印刷する。

qiita-logo.png

from escpos.printer import Usb
from escpos import *

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# レシートプリンターを使った印刷

width = 500
height = 400

image = Image.new('1', (width, height), 255)
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('FLOPDesignFont.ttf', 50, encoding='unic')
draw.text((0, 100), "日本語" + " ", font=font, fill=0)
font = ImageFont.truetype('storage/font/FLOPDesignFont.ttf', 28, encoding='unic')
draw.text((0, 182), "abcdefghijklmnopqrstuvwxyz", font=font, fill=0)
draw.text((0, 212), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", font=font, fill=0)
draw.text((0, 242), "1234567890" + " ", font=font, fill=0)
draw.text((0, 272), "!\"#$%&'()=~|+*<>?_{}" + " ", font=font, fill=0)

logo = Image.open('qiita-logo.png')

image.paste(logo, (150, 10))

# image.show()
p = Usb(0x0416, 0x5011, 0, 0x81, 0x03)
p.text(" \n")
p.image(image)
p.cut()

IMG_20200620_114940.jpg

まとめ

これで、テキストや簡単な画像をレシートプリンターで印刷できるようになりました。
ちなみに今回レシートプリンターを選択したのは、単純に金額が安価なためです。レシートプリンターが4500円/ レジペーパーも5個で900円程度ですしね!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
16