package Engine
|
|
|
|
import (
|
|
"fmt"
|
|
"LAPP_PRN_Service/common"
|
|
conf "LAPP_PRN_Service/config"
|
|
"LAPP_PRN_Service/db"
|
|
"LAPP_PRN_Service/glog"
|
|
"net"
|
|
"os/exec"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
type Printer struct {
|
|
PrinterId string // 打印机ID
|
|
PrinterName string // 打印机名
|
|
PrinterType string // 打印机类型,N=网络端口打印,L=文件打印
|
|
Ip string // 打印机IP地址
|
|
Port int // 打印机端口号
|
|
SerialName string // 串口名称
|
|
SerialPort int // 串口号
|
|
Interval int // 打印机打印间隔时间,单位:秒
|
|
conn net.Conn // 打印机连接句柄
|
|
InTaskChan chan db.PrintTask // 任务接入管道
|
|
Printertab db.Printer // 打印机信息
|
|
printer syscall.Handle
|
|
}
|
|
|
|
// 创建打印机对象
|
|
func (p *Printer) Create(printertab db.Printer) {
|
|
p.PrinterId = printertab.PrinterId
|
|
p.PrinterName = printertab.PrinterName
|
|
p.PrinterType = printertab.PrinterType
|
|
p.Ip = printertab.IpAddress
|
|
p.Port = printertab.Port
|
|
p.Interval = printertab.PrintInterval
|
|
p.SerialName = printertab.SerialName
|
|
p.SerialPort = printertab.SerialPort
|
|
|
|
p.Printertab = printertab
|
|
p.InTaskChan = make(chan db.PrintTask, 1000)
|
|
}
|
|
|
|
// 输出打印任务到端口
|
|
// 打印任务是以ByteArray数组类型的文件行
|
|
func (p *Printer) printTaskBytesFile(bytesFile []common.ByteFile) error {
|
|
var (
|
|
err error
|
|
bytesRow common.ByteFile
|
|
)
|
|
for _, bytesRow = range bytesFile {
|
|
if _, err = p.conn.Write(bytesRow.ByteLine); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *Printer) printTaskBytesRow(bytes []byte) error {
|
|
var err error
|
|
if _, err = p.conn.Write(bytes); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *Printer) getSocketAddress() string {
|
|
return fmt.Sprintf("%s:%d", p.Ip, p.Port)
|
|
}
|
|
|
|
// 通过TCP打开端口
|
|
func (p *Printer) openSocket() error {
|
|
var err error
|
|
if p.conn, err = net.Dial("tcp", p.getSocketAddress()); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 关闭通信端口
|
|
func (p *Printer) closeSocket() error {
|
|
return p.conn.Close()
|
|
}
|
|
|
|
// 通过端口打印
|
|
func (p *Printer) printBySocket(conf *conf.EnvConfig, saveChan chan db.PrintTask) {
|
|
var (
|
|
t db.PrintTask
|
|
err error
|
|
bytesFile []common.ByteFile
|
|
)
|
|
|
|
// 从缓存队列的头部取出一个任务并输出打印
|
|
for {
|
|
t = <-p.InTaskChan
|
|
if bytesFile, err = t.GenBytesFile(conf); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to generate bytes for task : ", t)
|
|
continue
|
|
}
|
|
if err = p.openSocket(); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to open the socket: ", p.Ip, p.Port)
|
|
time.Sleep(time.Duration(p.Interval) * time.Second)
|
|
continue
|
|
}
|
|
if err = p.printTaskBytesFile(bytesFile); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to print the content due to: ", err)
|
|
continue
|
|
}
|
|
if err = p.closeSocket(); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to close the socket due to: ", err)
|
|
continue
|
|
}
|
|
// 将输出打印的任务输出到保存管道
|
|
saveChan <- t
|
|
if p.Interval > 0 {
|
|
time.Sleep(time.Duration(p.Interval) * time.Second)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 通过输出文件打印
|
|
func (p *Printer) printByFile(conf *conf.EnvConfig, saveChan chan db.PrintTask) {
|
|
var (
|
|
t db.PrintTask
|
|
err error
|
|
)
|
|
|
|
for {
|
|
t = <-p.InTaskChan
|
|
if err = t.GenPrintFile(conf); err != nil {
|
|
glog.InfoExtln("Printer", "printByFile: Failed to generate print file for task : due to: ", t, err)
|
|
continue
|
|
}
|
|
// 通过windows文件输出方式打印
|
|
c := exec.Command("cmd", "/C", "COPY", "/B", t.TaskFile, p.PrinterName)
|
|
if err = c.Run(); err != nil {
|
|
glog.InfoExtln("Printer", "PrintByFile: copy file to printer error: ", err)
|
|
continue
|
|
}
|
|
|
|
saveChan <- t
|
|
if p.Interval > 0 {
|
|
time.Sleep(time.Duration(p.Interval) * time.Second)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 通过输出文件打印
|
|
func (p *Printer) printByDLL(conf *conf.EnvConfig, saveChan chan db.PrintTask) {
|
|
var (
|
|
t db.PrintTask
|
|
err error
|
|
)
|
|
|
|
for {
|
|
t = <-p.InTaskChan
|
|
if err = t.GenPrintFile(conf); err != nil {
|
|
glog.InfoExtln("Printer", "printByFile: Failed to generate print file for task : due to: ", t, err)
|
|
continue
|
|
}
|
|
// 通过windows文件输出方式打印
|
|
if err = common.SendFileToPrinter(t.TaskFile, p.Ip, p.Port); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to by dll: ", err)
|
|
continue
|
|
}
|
|
saveChan <- t
|
|
if p.Interval > 0 {
|
|
time.Sleep(time.Duration(p.Interval) * time.Second)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *Printer) printByExcel(conf *conf.EnvConfig, printChan chan db.PrintTask) {
|
|
var (
|
|
t db.PrintTask
|
|
err error
|
|
)
|
|
|
|
for {
|
|
t = <-p.InTaskChan
|
|
if err = t.GenExcelFile(conf); err != nil {
|
|
glog.InfoExtln("Printer", "printByFile: Failed to generate print file for task : due to: ", t, err)
|
|
continue
|
|
}
|
|
|
|
// 通过windows文件输出方式打印
|
|
printChan <- t
|
|
if p.Interval > 0 {
|
|
time.Sleep(time.Duration(p.Interval) * time.Second)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *Printer) printBySerial(conf *conf.EnvConfig, saveChan chan db.PrintTask) {
|
|
var (
|
|
t db.PrintTask
|
|
err error
|
|
strsFile string
|
|
)
|
|
|
|
for {
|
|
t = <-p.InTaskChan
|
|
if strsFile, err = t.GenStrsFile(conf); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to generate bytes for task : ", t)
|
|
continue
|
|
}
|
|
// 通过串口形式打印
|
|
if err = common.SendFileBySerial(strsFile, p.SerialName, p.SerialPort); err != nil {
|
|
glog.InfoExtln("Printer", "Failed to printBySerial: ", err)
|
|
continue
|
|
}
|
|
saveChan <- t
|
|
if p.Interval > 0 {
|
|
time.Sleep(time.Duration(p.Interval) * time.Second)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 创建打印机对象
|
|
func CreatePrinter(printertab db.Printer) (p *Printer) {
|
|
p = &Printer{}
|
|
p.PrinterName = printertab.PrinterName
|
|
p.PrinterType = printertab.PrinterType
|
|
p.Ip = printertab.IpAddress
|
|
p.Port = printertab.Port
|
|
p.Interval = printertab.PrintInterval
|
|
|
|
p.Printertab = printertab
|
|
p.InTaskChan = make(chan db.PrintTask, 1000)
|
|
|
|
return p
|
|
}
|
|
|
|
// 启动打印机的打印服务
|
|
func StartPrinter(p *Printer, conf *conf.EnvConfig, printChan, outChan chan db.PrintTask) {
|
|
switch p.PrinterType {
|
|
case "N": // 网络端口打印
|
|
go func() {
|
|
p.printBySocket(conf, outChan)
|
|
}()
|
|
case "L": // 输出文件打印
|
|
go func() {
|
|
p.printByFile(conf, outChan)
|
|
}()
|
|
case "D": // TSC打印机输出文件打印
|
|
go func() {
|
|
p.printByDLL(conf, outChan)
|
|
}()
|
|
case "E": // Excel表单打印机
|
|
go func() {
|
|
p.printByExcel(conf, printChan)
|
|
}()
|
|
case "S": // 串口打印机
|
|
go func() {
|
|
p.printBySerial(conf, outChan)
|
|
}()
|
|
}
|
|
}
|
|
|
|
// 串行打印表单文件并输出到任务保存队列
|
|
func StartSheetSerialPrintService(prnDict map[string]*Printer, printChan, outChan chan db.PrintTask) {
|
|
var (
|
|
prn *Printer
|
|
t db.PrintTask
|
|
err error
|
|
ok bool
|
|
)
|
|
|
|
go func() {
|
|
for {
|
|
t = <-printChan
|
|
if prn, ok = prnDict[t.PrinterId]; !ok {
|
|
glog.InfoExtln("Printer", "SheetPrintService: Task: printer: was not in the printer list.", t.TaskId, t.PrinterId)
|
|
continue
|
|
}
|
|
// 通过windows文件输出方式打印
|
|
common.SetDefaultPrinter(prn.PrinterName)
|
|
if err = common.ShellExecute(0, "print", t.TaskFile, prn.PrinterName, ".", 0); err != nil {
|
|
glog.InfoExtln("Printer", "PrintExcelFile: failed to print the file: due to: ", t.TaskFile, err)
|
|
continue
|
|
}
|
|
outChan <- t
|
|
}
|
|
}()
|
|
}
|