first commited
This commit is contained in:
parent
337a11c18d
commit
af7cbca0fa
|
@ -0,0 +1,14 @@
|
|||
.vscode/
|
||||
.vs/
|
||||
.VSCodeCounter/
|
||||
.idea/
|
||||
.venv/
|
||||
venv/
|
||||
__pycache__/
|
||||
|
||||
pkgs/*
|
||||
*.pyc
|
||||
media/*
|
||||
dist/*
|
||||
temp/*
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
"""
|
||||
@time:2024-07018
|
||||
@author:zhang
|
||||
@param:pdf_file
|
||||
PDF文件打印
|
||||
|
||||
"""
|
||||
import win32print
|
||||
import win32api
|
||||
import os
|
||||
import threading
|
||||
from flask import Flask, request, jsonify
|
||||
from PyPDF2 import PdfWriter, PdfReader
|
||||
from flask_cors import CORS
|
||||
import io
|
||||
import ctypes
|
||||
|
||||
import os
|
||||
import pystray
|
||||
import threading
|
||||
from PIL import Image
|
||||
from pystray import MenuItem
|
||||
import time
|
||||
# import requests
|
||||
from datetime import datetime
|
||||
import json
|
||||
from configparser import ConfigParser
|
||||
import socket
|
||||
import glob
|
||||
|
||||
import os
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import configparser
|
||||
|
||||
|
||||
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
log_path = os.path.join(CUR_DIR, 'printer.log')
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter('[%(asctime)s] [%(filename)s:%(lineno)d] [%(levelname)s]- %(message)s')
|
||||
|
||||
file_hander = RotatingFileHandler(log_path, maxBytes=1024*1024*10, backupCount=1)
|
||||
file_hander.setFormatter(formatter)
|
||||
file_hander.setLevel(logging.INFO)
|
||||
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(formatter)
|
||||
console_handler.setLevel(logging.DEBUG)
|
||||
|
||||
logger.addHandler(file_hander)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
log_command = f'start "" powershell -Command "Get-Content -Path \'{log_path}\' -Tail 10 -Wait"'
|
||||
|
||||
|
||||
|
||||
# 创建一个Flask应用
|
||||
app = Flask(__name__)
|
||||
CORS(app, supports_credentials=True)
|
||||
app.json.ensure_ascii = False
|
||||
|
||||
|
||||
class SnPost:
|
||||
|
||||
def __init__(self, server, port) -> None:
|
||||
self.is_one_instance = False
|
||||
self.is_working = False
|
||||
self.icon = None # 下标
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.check_one_instance()
|
||||
|
||||
|
||||
def check_one_instance(self):
|
||||
try:
|
||||
global s
|
||||
s = socket.socket()
|
||||
host = socket.gethostname()
|
||||
s.bind((host, 8080))
|
||||
self.is_one_instance = True
|
||||
except Exception:
|
||||
self.is_one_instance = False
|
||||
|
||||
def close(self):
|
||||
self.is_working = False
|
||||
self.icon.stop()
|
||||
|
||||
def log(self):
|
||||
os.system(log_command)
|
||||
|
||||
def run(self):
|
||||
if not self.is_one_instance:
|
||||
return
|
||||
|
||||
menu = (MenuItem('退出', self.close), MenuItem('查看日志', self.log))
|
||||
image = Image.open("favicon.ico")
|
||||
title = "打印机"
|
||||
self.icon = pystray.Icon(title, image, "打印机", menu)
|
||||
threading.Thread(target=self.icon.run, daemon=True).start()
|
||||
|
||||
|
||||
@app.route('/print/', methods=['POST', 'OPTIONS'])
|
||||
def pdf_printer():
|
||||
if request.method == 'OPTIONS': # 跨域请求预检
|
||||
return jsonify({"message": "OK"}), 200
|
||||
# if 'file' not in request.files:
|
||||
# return jsonify({"error_message": "No file part", "error_code": 400}), 400
|
||||
file = request.files['file']
|
||||
printer_name = request.form.get('printer_name', None)
|
||||
# Save the file temporarily
|
||||
temp_pdf_path = os.path.join(os.path.dirname(__file__), 'temp_pdf.pdf')
|
||||
|
||||
try:
|
||||
# Read the PDF binary
|
||||
file.save(temp_pdf_path)
|
||||
if printer_name:
|
||||
win32print.OpenPrinter(printer_name)
|
||||
win32print.SetDefaultPrinter(printer_name)
|
||||
win32print.GetDefaultPrinter()
|
||||
|
||||
win32api.ShellExecute(
|
||||
0,
|
||||
"print",
|
||||
temp_pdf_path,
|
||||
None,
|
||||
".",
|
||||
0
|
||||
)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(traceback.format_exc())
|
||||
return jsonify({"error_message": str(e), "error_code": "print_failed"}), 500
|
||||
finally:
|
||||
t = threading.Thread(target=del_file, args=(temp_pdf_path,))
|
||||
t.start()
|
||||
# # 清除打印文件
|
||||
return jsonify({}), 200
|
||||
|
||||
def del_file(path):
|
||||
import time
|
||||
time.sleep(5)
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
def save_pdf_from_binary(pdf_binary, file_path):
|
||||
"""将二进制数据写入 PDF 文件"""
|
||||
with open(file_path, 'wb') as file:
|
||||
file.write(pdf_binary)
|
||||
|
||||
|
||||
@app.route('/prints/', methods=['POST', 'OPTIONS'])
|
||||
def str_printer():
|
||||
if request.method == 'OPTIONS': # 跨域请求预检
|
||||
return jsonify({"message": "OK"}), 200
|
||||
print_commands = request.json.get('print_commands', None)
|
||||
print_name = request.json.get('print_name', None)
|
||||
print(print_commands)
|
||||
tsclibrary = ctypes.WinDLL(".//TSCLIB.dll")
|
||||
if print_name:
|
||||
tsclibrary.openportW(print_name)
|
||||
else:
|
||||
print_name = win32print.GetDefaultPrinter()
|
||||
tsclibrary.openportW(print_name)
|
||||
tsclibrary.clearbuffer()
|
||||
for item in print_commands:
|
||||
if 'WINTEXT' in item:
|
||||
item_list = item.replace('WINTEXT ', '').split(',')
|
||||
tsclibrary.windowsfontW(
|
||||
item_list[0],
|
||||
item_list[1],
|
||||
item_list[2],
|
||||
item_list[3],
|
||||
item_list[4],
|
||||
item_list[5],
|
||||
item_list[6],
|
||||
item_list[7])
|
||||
else:
|
||||
tsclibrary.sendcommandW(item)
|
||||
print(item, "33333")
|
||||
tsclibrary.closeport()
|
||||
|
||||
return jsonify({}), 200
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
obj = SnPost(server='localhost', port=8080)
|
||||
obj.run()
|
||||
app.run(port=8080, debug=True, host='0.0.0.0')
|
|
@ -0,0 +1,38 @@
|
|||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['PrintAgent.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='PrintAgent',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,29 @@
|
|||
import ctypes
|
||||
# wintext x,y,height,rotation,type(0,1,2,3),line(0,1,2),fontname(Arial),text
|
||||
print_commands = """SIZE 70 mm,90 mm\r\n
|
||||
GAP 2 mm,0 mm\r\n
|
||||
CLS\r\n
|
||||
TEXT 100,100,"4",0,1,1,"DEMO FOR TEXT"\r\n
|
||||
WINTEXT 100,200,36,0,0,0,Simhei,中国制造2025\r\n
|
||||
BARCODE 100,300,"128",108,0,0,2,4,"3474598772242444288"\r\n
|
||||
QRCODE 100,500,L,6,A,0,"www.baidu.com"\r\n
|
||||
PRINT 1"""
|
||||
tsclibrary = ctypes.WinDLL(".//TSCLIB.dll")
|
||||
tsclibrary.openportW("GP-3150TN")
|
||||
tsclibrary.clearbuffer()
|
||||
print_commands_list = print_commands.split("\r\n\n")
|
||||
for item in print_commands_list:
|
||||
if 'WINTEXT' in item:
|
||||
item_list = item.replace('WINTEXT ', '').split(',')
|
||||
tsclibrary.windowsfontW(
|
||||
item_list[0],
|
||||
item_list[1],
|
||||
item_list[2],
|
||||
item_list[3],
|
||||
item_list[4],
|
||||
item_list[5],
|
||||
item_list[6],
|
||||
item_list[7])
|
||||
else:
|
||||
tsclibrary.sendcommandW(item)
|
||||
tsclibrary.closeport()
|
Loading…
Reference in New Issue