From 1e904000c7e6fc571f8dc29fb58b4b341034f68b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Thu, 29 Jan 2026 20:16:00 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20python-escpos=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=9C=20QR=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit python-escpos: 가장 안정적인 ESC/POS Python 라이브러리 - escpos.qr() - 프린터 내장 QR 사용 - escpos.image() - QR을 이미지로 변환하여 인쇄 - 다양한 size 테스트 (3, 4, 6, 8) - 완전한 영수증 예제 포함 설치: pip install python-escpos 실행: python backend/test_qr_with_escpos_lib.py Co-Authored-By: Claude Sonnet 4.5 --- backend/test_qr_with_escpos_lib.py | 263 +++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 backend/test_qr_with_escpos_lib.py diff --git a/backend/test_qr_with_escpos_lib.py b/backend/test_qr_with_escpos_lib.py new file mode 100644 index 0000000..b7cb4b7 --- /dev/null +++ b/backend/test_qr_with_escpos_lib.py @@ -0,0 +1,263 @@ +""" +python-escpos 라이브러리를 사용한 QR 코드 인쇄 테스트 +훨씬 더 간단하고 안정적! + +설치: pip install python-escpos +""" + +from escpos.printer import Network +from escpos import escpos +import time + +# 프린터 설정 +PRINTER_IP = "192.168.0.174" +PRINTER_PORT = 9100 + +# 테스트 URL +TEST_URL = "https://mile.0bin.in/test" + + +def test_method_1_native_qr(): + """방법 1: escpos 라이브러리 내장 QR 함수""" + print("\n" + "="*60) + print("방법 1: escpos.qr() - 프린터 내장 QR") + print("="*60) + + try: + p = Network(PRINTER_IP, port=PRINTER_PORT) + + p.text("\n") + p.text("================================\n") + p.text(" *** 방법 1 ***\n") + p.text(" escpos.qr() 내장\n") + p.text("================================\n") + p.text("\n") + + # QR 코드 인쇄 (프린터 내장) + p.qr(TEST_URL, size=4, center=True) + + p.text("\n") + p.text(f"URL: {TEST_URL}\n") + p.text("\n\n\n") + p.cut() + + print("✅ 방법 1 성공!") + time.sleep(2) + return True + except Exception as e: + print(f"❌ 방법 1 실패: {e}") + import traceback + traceback.print_exc() + return False + + +def test_method_2_image(): + """방법 2: escpos 라이브러리 이미지 함수""" + print("\n" + "="*60) + print("방법 2: escpos.image() - QR을 이미지로 변환하여 인쇄") + print("="*60) + + try: + import qrcode + from io import BytesIO + + p = Network(PRINTER_IP, port=PRINTER_PORT) + + p.text("\n") + p.text("================================\n") + p.text(" *** 방법 2 ***\n") + p.text(" escpos.image()\n") + p.text("================================\n") + p.text("\n") + + # QR 이미지 생성 + qr = qrcode.QRCode(version=1, box_size=3, border=2) + qr.add_data(TEST_URL) + qr.make(fit=True) + qr_img = qr.make_image(fill_color="black", back_color="white") + + # escpos.image()로 인쇄 + p.image(qr_img, center=True) + + p.text("\n") + p.text(f"URL: {TEST_URL}\n") + p.text("\n\n\n") + p.cut() + + print("✅ 방법 2 성공!") + time.sleep(2) + return True + except Exception as e: + print(f"❌ 방법 2 실패: {e}") + import traceback + traceback.print_exc() + return False + + +def test_method_3_qr_small(): + """방법 3: 작은 QR (size=3)""" + print("\n" + "="*60) + print("방법 3: 작은 QR (size=3)") + print("="*60) + + try: + p = Network(PRINTER_IP, port=PRINTER_PORT) + + p.text("\n") + p.text("================================\n") + p.text(" *** 방법 3 ***\n") + p.text(" 작은 QR (size=3)\n") + p.text("================================\n") + p.text("\n") + + p.qr(TEST_URL, size=3, center=True) + + p.text("\n") + p.text(f"URL: {TEST_URL}\n") + p.text("\n\n\n") + p.cut() + + print("✅ 방법 3 성공!") + time.sleep(2) + return True + except Exception as e: + print(f"❌ 방법 3 실패: {e}") + import traceback + traceback.print_exc() + return False + + +def test_method_4_qr_large(): + """방법 4: 큰 QR (size=8)""" + print("\n" + "="*60) + print("방법 4: 큰 QR (size=8)") + print("="*60) + + try: + p = Network(PRINTER_IP, port=PRINTER_PORT) + + p.text("\n") + p.text("================================\n") + p.text(" *** 방법 4 ***\n") + p.text(" 큰 QR (size=8)\n") + p.text("================================\n") + p.text("\n") + + p.qr(TEST_URL, size=8, center=True) + + p.text("\n") + p.text(f"URL: {TEST_URL}\n") + p.text("\n\n\n") + p.cut() + + print("✅ 방법 4 성공!") + time.sleep(2) + return True + except Exception as e: + print(f"❌ 방법 4 실패: {e}") + import traceback + traceback.print_exc() + return False + + +def test_method_5_full_receipt(): + """방법 5: 완전한 영수증 (청춘약국)""" + print("\n" + "="*60) + print("방법 5: 완전한 영수증") + print("="*60) + + try: + p = Network(PRINTER_IP, port=PRINTER_PORT) + + p.text("\n") + p.text("================================\n") + p.text(" *** 방법 5 ***\n") + p.text(" 완전한 영수증\n") + p.text("================================\n") + p.text("\n") + + # 헤더 + p.set(align='center') + p.text("청춘약국\n") + p.text("================================\n") + + # 거래 정보 + p.set(align='left') + p.text("거래일시: 2026-01-29 14:30\n") + p.text("거래번호: 20260129000042\n") + p.text("\n") + p.text("결제금액: 50,000원\n") + p.text("적립예정: 1,500P\n") + p.text("\n") + p.text("================================\n") + p.text("\n") + + # QR 코드 + p.qr(TEST_URL, size=6, center=True) + + p.text("\n") + p.set(align='center') + p.text("QR 촬영하고 포인트 받으세요!\n") + p.text("\n") + p.text("================================\n") + + p.text("\n\n\n") + p.cut() + + print("✅ 방법 5 성공!") + time.sleep(2) + return True + except Exception as e: + print(f"❌ 방법 5 실패: {e}") + import traceback + traceback.print_exc() + return False + + +def main(): + print("="*60) + print("python-escpos 라이브러리 QR 테스트") + print("="*60) + print(f"프린터: {PRINTER_IP}:{PRINTER_PORT}") + print(f"테스트 URL: {TEST_URL}") + print("\n먼저 라이브러리 설치 확인:") + print(" pip install python-escpos") + print("="*60) + + try: + import escpos + print("✅ python-escpos 설치됨") + except ImportError: + print("❌ python-escpos가 설치되지 않았습니다!") + print(" 실행: pip install python-escpos") + return + + methods = [ + ("방법 1: 내장 QR (size=4)", test_method_1_native_qr), + ("방법 2: 이미지로 변환", test_method_2_image), + ("방법 3: 작은 QR (size=3)", test_method_3_qr_small), + ("방법 4: 큰 QR (size=8)", test_method_4_qr_large), + ("방법 5: 완전한 영수증", test_method_5_full_receipt), + ] + + results = [] + for name, method_func in methods: + try: + success = method_func() + results.append((name, success)) + except Exception as e: + print(f"[{name}] ❌ 예외 발생: {e}") + results.append((name, False)) + + print("\n" + "="*60) + print("결과 요약") + print("="*60) + for name, success in results: + print(f"{name}: {'✅ 성공' if success else '❌ 실패'}") + + print("\n5장의 영수증을 확인하여 QR이 보이는 번호를 알려주세요!") + print("="*60) + + +if __name__ == "__main__": + main()