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 } }() }