escpos

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2025 License: MIT Imports: 7 Imported by: 0

README

go-escpos

Go Report Card Software License GoDoc

ESC/POS Thermal Printer library for Go with native Windows support.

This fork adds Windows API integration for direct printing to installed printers without network connectivity.

Features

  • ✅ Network printing (TCP/IP)
  • ✅ Serial/USB printing (any io.ReadWriteCloser)
  • Windows native printing (new!)
  • ✅ Text formatting (bold, underline, fonts, sizes)
  • ✅ Barcodes (UPC, EAN, Code39, Code93, Code128, etc.)
  • ✅ Image printing (8-bit and 24-bit)
  • ✅ Paper control (cut, feed)
  • ✅ Printer status queries
  • ✅ No external dependencies

Installation

go get github.com/DevLumuz/go-escpos

Usage

Windows Native Printing

Print directly to installed Windows printers:

package main

import (
	"log"
	"github.com/DevLumuz/go-escpos"
)

func main() {
	// List available printers
	printers, err := escpos.GetInstalledPrinters()
	if err != nil {
		log.Fatal(err)
	}

	// Connect to first printer
	printer, err := escpos.NewWindowsPrinter(printers[0])
	if err != nil {
		log.Fatal(err)
	}
	defer printer.Close()

	// Print receipt
	printer.Initialize()
	
	printer.Justify(escpos.CenterJustify)
	printer.SetBold(true)
	printer.Println("MY STORE")
	printer.SetBold(false)
	printer.LF()
	
	printer.Justify(escpos.LeftJustify)
	printer.Println("Item 1............$10.00")
	printer.Println("Item 2............$15.00")
	printer.Println("----------------------")
	printer.SetBold(true)
	printer.Println("TOTAL.............$25.00")
	printer.SetBold(false)
	
	printer.FeedLines(3)
	printer.Cut()
}
Network Printing (TCP/IP)
package main

import (
	"net"
	"github.com/DevLumuz/go-escpos"
)

func main() {
	conn, _ := net.Dial("tcp", "192.168.1.100:9100")
	defer conn.Close()

	printer := escpos.NewPrinter(conn)
	printer.Println("Hello World!")
	printer.Cut()
}
Serial/USB Printing
printer := escpos.NewPrinter(anyIOReadWriteCloser)
printer.Println("Hello!")
printer.Cut()

Demo Utility

The program in ./cmd/printhis/ is a demo utility to demonstrate some basic printing use cases.

Testing

What? Did I hear you ask for testing? You think we make useless mocks that only tests our assumptions about the hoin printer instead of REAL HONEST GOOD boots on the ground testing.

Run go run ./cmd/test-printer/ to print out our test program.

Really, how are we supposed to tests without a firmware dump? Total incongruity.

Also the test program assumes some things will work line printing and the such, cause how can we test functions without that. It'd be obvious if nothing prints. The goal is to test all the extra functions like horizontal tabbing, justifications, images, etc.

Windows API

GetInstalledPrinters()

List all installed printers on the system.

printers, err := escpos.GetInstalledPrinters()
// Returns: []string{"Printer 1", "Printer 2", ...}
NewWindowsPrinter(name)

Connect to a Windows printer by name.

printer, err := escpos.NewWindowsPrinter("Your Printer Name")
defer printer.Close()
Debug: Capture Bytes

Access raw bytes sent to printer for debugging.

wp := printer.dst.(*escpos.WindowsPrinter)
bytes := wp.Bytes()
fmt.Printf("Sent %d bytes\n", len(bytes))

Common Functions

// Text formatting
printer.SetBold(true)
printer.SetFont(escpos.FontB)
printer.SetCharacterSize(2, 2)

// Alignment
printer.Justify(escpos.LeftJustify)
printer.Justify(escpos.CenterJustify)
printer.Justify(escpos.RightJustify)

// Paper control
printer.Feed(50)
printer.FeedLines(3)
printer.Cut()

// Barcodes
printer.SetHRIPosition(escpos.HRIBelow)
printer.PrintBarCode(escpos.BcCODE39, "123456")

// Sound
printer.Beep(3, 5)

Testing

Test Windows printing:

# List printers
go run ./cmd/test-windows -list

# Run default test (receipt)
go run ./cmd/test-windows

# Run all tests
go run ./cmd/test-windows -test all

# Specific tests
go run ./cmd/test-windows -test receipt
go run ./cmd/test-windows -test barcode
go run ./cmd/test-windows -test format

# Specify printer
go run ./cmd/test-windows -printer "Your Printer Name" -test all

Test with real hardware (network/USB):

go run ./cmd/test-printer/ 192.168.1.100:9100

Implementation

Windows support uses winspool.drv API via syscall:

  • OpenPrinterW - Open printer handle
  • StartDocPrinterW - Start print job
  • WritePrinter - Send RAW data
  • EnumPrintersW - List printers

No external dependencies required.

Requirements

  • Windows: Windows 7 or later
  • Go: 1.16+
  • Printer: Must support RAW mode and ESC/POS commands

Troubleshooting

"failed to open printer"

  • Use GetInstalledPrinters() to get exact names (case-sensitive)

Nothing prints

  • Call printer.Cut() at the end
  • Check printer has paper and is online

Garbled output

  • Printer must support ESC/POS commands

Fork Information

Fork of joeyak/go-escpos with Windows native printing support.

Changes:

  • Windows API integration (printer_windows.go)
  • GetInstalledPrinters() function
  • WindowsPrinter.Bytes() for debugging
  • Windows test utility (cmd/test-windows)

License

MIT License - See license.md

Original work Copyright 2022 joeyak
Windows support Copyright 2025 DevLumuz

Documentation

Index

Constants

View Source
const (
	// Default ip and port for hoin printers
	DefaultHoinIP = "192.168.1.23:9100"

	HT  = 0x09
	LF  = 0x0A
	CR  = 0x0D
	GS  = 0x1D
	ESC = 0x1B
	DLE = 0x10
)

Variables

This section is empty.

Functions

func GetInstalledPrinters added in v1.0.2

func GetInstalledPrinters() ([]string, error)

GetInstalledPrinters returns a list of all installed printers on the system. This function is only available on Windows systems.

Types

type BarCode

type BarCode int
const (
	BcUPCA BarCode = iota
	BcUPCE
	BcJAN13
	BcJAN8
	BcCODE39
	BcITF
	BcCODABAR
	BcCODE93  BarCode = 72
	BcCODE123 BarCode = 73
)

type Density

type Density int

Density represents the DPI to use when printing images.

const (
	// SingleDensity is 90dpi
	SingleDensity Density = iota
	// DoubleDensity is 180dpi
	DoubleDensity
)

type ErrorStatus

type ErrorStatus struct {
	AutoCutter, UnRecoverable, AutoRecoverable bool
}

type Font

type Font int
const (
	FontA Font = iota
	FontB
)

type HRIPosition

type HRIPosition int
const (
	HRINone HRIPosition = iota
	HRIAbove
	HRIBelow
	HRIBoth
)

type Justification

type Justification int
const (
	LeftJustify Justification = iota
	CenterJustify
	RightJustify
)

type OfflineStatus

type OfflineStatus struct {
	CoverOpen, FeedButton, PrintingStopped, ErrorOccured bool
}

type PaperSensorStatus

type PaperSensorStatus struct {
	NearEnd, RollEnd bool
}

type PrintModeMask

type PrintModeMask int
const (
	// bit 0: Font selection, 0: Font A (normal), 1: Font B (thin)
	ThinFont PrintModeMask = 1 << 0
	// bit 1 and 2 are unused
	// bit 3: Bold, 0: Off, 1: On
	Bold PrintModeMask = 1 << 3
	// bit 4: Double height, 0: Off, 1: On
	DoubleHeight PrintModeMask = 1 << 4
	// bit 5: Double width, 0: Off, 1
	DoubleWidth PrintModeMask = 1 << 5
	// bit 6 unused
	// bit 7: Underline, 0: Off, 1: On
	Underline PrintModeMask = 1 << 7
)

type Printer

type Printer struct {
	// contains filtered or unexported fields
}

func NewIpPrinter

func NewIpPrinter(addr string) (Printer, error)

func NewPrinter

func NewPrinter(dst io.ReadWriteCloser) Printer

func NewWindowsPrinter added in v1.0.2

func NewWindowsPrinter(name string) (Printer, error)

NewWindowsPrinter creates a new printer connection to a Windows printer by name. This function is only available on Windows systems.

func (Printer) Beep

func (p Printer) Beep(n, t int) error

Beep makes a beep sound n times for t duration

Duration is dependent on the model. For the HOP-E802 each duration is around 100ms

func (Printer) CR

func (p Printer) CR() error

CR prints and does a carriage return

func (Printer) Close

func (p Printer) Close() error

func (Printer) Cut

func (p Printer) Cut() error

Cut cuts the paper

func (Printer) CutFeed

func (p Printer) CutFeed(n int) error

CutFeed feeds the paper n units and then cuts it

func (Printer) Feed

func (p Printer) Feed(n int) error

Feed feeds the paper n units

func (Printer) FeedLines

func (p Printer) FeedLines(n int) error

FeedLines feeds the paper n lines

func (Printer) HT

func (p Printer) HT() error

HT moves the print position to the next horizontal tab position

By default HT will do nothing if SetHT is not called with tab positions

func (Printer) Initialize

func (p Printer) Initialize() error

func (Printer) Justify

func (p Printer) Justify(j Justification) error

Justify sets the alignment to n

func (Printer) LF

func (p Printer) LF() error

LF prints the data in the print buffer and feeds one line

func (Printer) Morse

func (p Printer) Morse(message string) error

Morse beeps out the message in morse code

func (Printer) MorsePrint

func (p Printer) MorsePrint(message string) error

MorsePrint beeps out the morse message but also prints it to the paper

func (Printer) Print

func (p Printer) Print(a ...any) error

func (Printer) PrintBarCode

func (p Printer) PrintBarCode(barcodeType BarCode, data string) error

PrintBarCode prints the bar code passed in with data.

The size ranges are as follows in (Type: min, max):

BcUPCA: 11, 12
BcUPCE: 6, 7
BcJAN13: 12, 13
BcJAN8: 7, 8
BcCODE39: 0, 14
BcITF: 0, 22
BcCODABAR: 2, 19
BcCODE93: 1, 17
BcCODE123: 0, 65

For the accepted data values:

BcUPCA, BcUPCE, BcJAN13, BcJAN8, BcITF all only accept [0123456789]
BcCODE39, BcCODE93, BcCODE123 can accept [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.*$/+% ]
BcCODABAR:
  The first and last character of the CODABAR code bar has to be one of [ABCD]
  and the rest of the characters in between can be one of [0123456789-$:/.+]

Note on the CODE123 length:

...the docs say it's between 2 and 255 but the printer
does not have that limit. On one hand it can go down to 0 character, but also I could
not find the limit for max characters. At 15 characters it went off the page with a
HOP-E802 printer and at 34 characters it starts printing the HRI weird. At 66 0s
repeating it seems to break and stop printing, and the same at 65 As repeating.
Long story short...I think they didn't finish programming the checks on CODE123

func (Printer) PrintImage8

func (p Printer) PrintImage8(img image.Image, density Density) error

PrintImage8 prints an image in the 8-bit row format. In this format each row is 8 dots tall.

The density selects the horizontal DPI of the image. SingleDensity is 90dpi while DoubleDensity is 180dpi. Vertical DPI is always 60dpi for 8-bit image data.

No black and white conversion is performed on the provided image. The image should be converted before calling this function.

func (Printer) PrintImage24

func (p Printer) PrintImage24(img image.Image, density Density) error

PrintImage24 prints an image in the 24-bit row format. In this format each row is 24 dots tall.

This works the same as PrintImage8() with the only difference being the DPI of the printed image. SingleDensity is 90dpi while DoubleDensity is 180dpi. Vertical DPI is always 180dpi for 24-bit image data.

func (Printer) Printf

func (p Printer) Printf(format string, a ...any) error

func (Printer) Println

func (p Printer) Println(a ...any) error

func (Printer) Read

func (p Printer) Read(b []byte) (int, error)

func (Printer) ResetBarCodeHeight

func (p Printer) ResetBarCodeHeight() error

ResetBarCodeHeight sets the bar code height to 162

func (Printer) ResetLineSpacing

func (p Printer) ResetLineSpacing() error

ResetLineSpacing sets the spacing to the default which is 1/6-inch lines (approx. 4.23mm)

func (Printer) SelectPrintMode

func (p Printer) SelectPrintMode(modes ...PrintModeMask) error

SelectPrintMode sets the print mode for the printer. The modes are as follows and are provided as variadic arguments:

  • ThinFont: Font selection, 0: Font A (normal), 1: Font B (thin)
  • Bold: Emphasized mode, 0: Off, 1: On (Emphasized mode just prints the text bold, hence the flag is named 'bold')
  • DoubleHeight: Double height, 0: Off (normal), 1: On (double height font)
  • DoubleWidth: Double width, 0: Off (normal), 1: On (double width font)
  • Underline: Underline, 0: Off (normal), 1: On (underlined font)

func (Printer) SetBarCodeHeight

func (p Printer) SetBarCodeHeight(n int) error

SetBarCodeHeight sets the bar code height in n dots

func (Printer) SetBold

func (p Printer) SetBold(b bool) error

SetBold turns emphasized mode on or off

func (Printer) SetCharacterSize

func (p Printer) SetCharacterSize(width, height int) error

SetCharacterSize sets both the width and height of text characters. The values for height and width must be between 0 and 7, inclusively.

While the printer may accept all valid values, it may not print text correctly.

func (Printer) SetFont

func (p Printer) SetFont(f Font) error

SetFont changes the font

n=0 selects font A n=1 selects font B

func (Printer) SetHRIPosition

func (p Printer) SetHRIPosition(hp HRIPosition) error

SetHRIPosition sets the printing position of the HRI characters in relation to the barcode

func (Printer) SetHT

func (p Printer) SetHT(positions ...int) error

SetHT sets the horizontal tab positions

This command cancels previous SetHT commands Multiple positions can be set for tabbing A max of 32 positions can be set Calling SetHT with no argments resets the tab positions

func (Printer) SetLineSpacing

func (p Printer) SetLineSpacing(n int) error

SetLineSpacing sets the line spacing to n * v/h motion units in inches

func (Printer) SetReversePrinting

func (p Printer) SetReversePrinting(b bool) error

SetReversePrinting sets the white/black printing mode

If b is true then it will print black text on white background If b is false then it will print white text on black background

func (Printer) SetRotate90

func (p Printer) SetRotate90(b bool) error

SetRotate90 turns on 90 clockwise rotation mode for the text

When text is double-width or double-height the text will be mirrored

func (Printer) SetTabs

func (p Printer) SetTabs(width int) error

SetTabs will set up to 32 tab positions at the given width intervals. If the tab value exceeds 256, fewer than 32 positions will be set.

func (Printer) SetUpsideDown

func (p Printer) SetUpsideDown(upsidedown bool) error

SetUpsideDown will either set or clear printing text upside-down. This setting does not affect images or barcodes.

func (Printer) TransmitErrorStatus

func (p Printer) TransmitErrorStatus() (ErrorStatus, error)

func (Printer) TransmitOfflineStatus

func (p Printer) TransmitOfflineStatus() (OfflineStatus, error)

func (Printer) TransmitPaperSensorStatus

func (p Printer) TransmitPaperSensorStatus() (PaperSensorStatus, error)

func (Printer) TransmitPrinterStatus

func (p Printer) TransmitPrinterStatus() (PrinterStatus, error)

func (Printer) Write

func (p Printer) Write(b []byte) (int, error)

type PrinterStatus

type PrinterStatus struct {
	DrawerOpen bool
}

Directories

Path Synopsis
cmd
printhis command
test-printer command
test-windows command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL