在电子秤中称肉类产品并打印标签在ODOO中使用

1. 应用背景

冷库中的肉需要分割包装后,打印专有的称重标签(标签条码前几位为产品,后五位用来定位重量,重量位前三位整数部分,后两位小数部分),超市中的电子秤完全可以满足需求. 正好有一台现成的电子秤(称重数据来自串口),标签打印机使用佳博打印机.需要做一个简单的产品称重功能.

2. 应用环境

  1. 现成的电子秤一台(带电脑,window 7 系统.已经装好标签打印机驱动)
  2. gprinter 标签打印机
  3. 开发在python3 环境下

3. 使用的开发工具(python3类库)

  1. flask: 做成web服务
  2. flask-socket: 用来传输电子秤的重量数据
  3. ean128 条码编码
  4. PIL(图片库): 生成图片(打印图片)

4. 关键代码

生成标签图


# 形成图片
from PIL import Image, ImageWin,ImageFont,ImageDraw
import code128


def saveImage(data):
    # 输出图像,tempimage/

    # 60*40 mm 毫米
    width = 480
    height = 320

    # font_size
    font_size = 20
    y_step = 24
    im = Image.new('RGB', (width, height), (255, 255, 255))
    textColor = (0,0,0)
    font = font=ImageFont.truetype('font/siyuan.otf',font_size)
    draw = ImageDraw.Draw(im)
    # 10,左边10
    offsetX = 10
    offsetY = 10
    # 第一行品名
    draw.text((offsetX,offsetY),"品名:"+data.get('product_name'),font=font,fill=textColor)
    offsetY += y_step
    # 第二行 产地
    draw.text((offsetX, offsetY), "产地:"+data.get('production_place'), font=font, fill=textColor)
    offsetY += y_step
    # 单价
    draw.text((offsetX, offsetY), "单价:"+data.get('price_list')+'元/kg', font=font, fill=textColor)
    offsetY += y_step
    # 克重
    draw.text((offsetX, offsetY), "克重:"+data.get('weight_g')+'g', font=font, fill=textColor)
    offsetY += y_step
    # 生产商
    draw.text((offsetX, offsetY), "生产商:"+data.get('manufacturer'), font=font, fill=textColor)
    offsetY += y_step
    # 进口商
    draw.text((offsetX, offsetY), "进口商:"+data.get('importer'), font=font, fill=textColor)
    offsetY += y_step
    # 生产日期
    draw.text((offsetX, offsetY), "生产日期:"+data.get('production_date'), font=font, fill=textColor)
    offsetY += y_step
    # 分切日期
    draw.text((offsetX, offsetY), "分切日期:"+data.get('baozhi_date'), font=font, fill=textColor)
    offsetY += y_step
    # 保存条件
    draw.text((offsetX, offsetY), "保存条件:"+data.get('storage_conditions'), font=font, fill=textColor)
    offsetY += y_step
    # 保质期
    draw.text((offsetX, offsetY), "保质期:"+data.get('baozhi_str'), font=font, fill=textColor)
    offsetY += y_step
    # 条码
    codeText = data.get('barcode').upper()


    offsetY += y_step
    # code 128
    options = {
        'ttf_font':'font/msyh.ttc',
        'ttf_fontsize':12,
        'bottom_border':15,
        'height':70,
        'label_border':2
    }

    codeImage = code128.image(codeText)
    im.paste(codeImage,(offsetX,offsetY))
    im.save('tempimg/code.png','png')


调用标签打印机


import win32print
import win32ui
from PIL import Image, ImageWin

def print_p():
    #
    # Constants for GetDeviceCaps
    #
    #
    # HORZRES / VERTRES = printable area
    #
    HORZRES = 8
    VERTRES = 10
    #
    # LOGPIXELS = dots per inch
    #
    LOGPIXELSX = 88
    LOGPIXELSY = 90
    #
    # PHYSICALWIDTH/HEIGHT = total area
    #
    PHYSICALWIDTH = 110
    PHYSICALHEIGHT = 111
    #
    # PHYSICALOFFSETX/Y = left / top margin
    #
    PHYSICALOFFSETX = 112
    PHYSICALOFFSETY = 113

    printer_name = win32print.GetDefaultPrinter()
    printer_name = 'Gprinter GP-3150TN'
    file_name = "tempimg/code.png"

    #
    # You can only write a Device-independent bitmap
    #  directly to a Windows device context; therefore
    #  we need (for ease) to use the Python Imaging
    #  Library to manipulate the image.
    #
    # Create a device context from a named printer
    #  and assess the printable size of the paper.
    #
    hDC = win32ui.CreateDC()
    hDC.CreatePrinterDC(printer_name)
    printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES)
    printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)
    printer_margins = hDC.GetDeviceCaps(PHYSICALOFFSETX), hDC.GetDeviceCaps(PHYSICALOFFSETY)

    print(printable_area, printer_size, printer_margins)
    #
    # Open the image, rotate it if it's wider than
    #  it is high, and work out how much to multiply
    #  each pixel by to get it as big as possible on
    #  the page without distorting.
    #
    bmp = Image.open(file_name)
    # if bmp.size[0] > bmp.size[1]:
    #  bmp = bmp.rotate (90)

    ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]
    scale = min(ratios)

    #
    # Start the print job, and draw the bitmap to
    #  the printer device at the scaled size.
    #
    hDC.StartDoc(file_name)
    hDC.StartPage()

    dib = ImageWin.Dib(bmp)
    scaled_width, scaled_height = [int(scale * i) for i in bmp.size]
    x1 = int((printer_size[0] - scaled_width) / 2)
    y1 = int((printer_size[1] - scaled_height) / 2)
    x2 = x1 + scaled_width
    y2 = y1 + scaled_height
    dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))
    print(x1, y1, x2, y2)
    hDC.EndPage()
    hDC.EndDoc()
    hDC.DeleteDC()

5. 整体思路

*. 浏览器展示要选择的产品
*. 称重产品,选择产品,称重.打印
*. 通过websocket传输称重数据(包含去皮等功能)
*. 传输要称重的产品基本信息和重量,替换原始编码,带上重量,生成标签图片,然后进行图片打印.

6. 问题

标签打印

之前思路使用”tsclib.dll”(只能使用 python 的32位版本)做打印,但是总是调不通.最后直接使用图片打印方案.

7. 参考

*. python win32 相关文档
*. python win32 打印相关案例

微信扫一扫交流

作者:SUN
微信关注:一个小胖
本文出处:http://www.fsmgsports.com/post/scale-odoo-gpprinter/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。