浏览代码

Label prevent cross printing test

master
kelvin.yau 14 小时前
父节点
当前提交
9f16f31dd8
共有 2 个文件被更改,包括 69 次插入30 次删除
  1. +26
    -0
      src/main/java/com/ffii/core/utils/PrinterLockManager.kt
  2. +43
    -30
      src/main/java/com/ffii/core/utils/ZebraPrinterUtil.kt

+ 26
- 0
src/main/java/com/ffii/core/utils/PrinterLockManager.kt 查看文件

@@ -0,0 +1,26 @@
package com.ffii.core.utils

import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.locks.ReentrantLock

/**
* Single-server printer lock manager.
*
* Keyed by "ip:port" so all print jobs targeting the same printer are serialized,
* preventing interleaving outputs when multiple users print concurrently.
*/
object PrinterLockManager {
private val locks = ConcurrentHashMap<String, ReentrantLock>()

fun <T> withLock(printerIp: String, printerPort: Int, block: () -> T): T {
val key = "${printerIp.trim()}:$printerPort"
val lock = locks.computeIfAbsent(key) { ReentrantLock(true) } // fair lock
lock.lock()
try {
return block()
} finally {
lock.unlock()
}
}
}


+ 43
- 30
src/main/java/com/ffii/core/utils/ZebraPrinterUtil.kt 查看文件

@@ -7,6 +7,7 @@ import java.awt.Graphics2D
import java.awt.image.BufferedImage
import java.io.File
import java.io.OutputStream
import java.net.InetSocketAddress
import java.net.Socket
import java.util.*

@@ -42,39 +43,51 @@ open class ZebraPrinterUtil {
throw IllegalArgumentException("Error: File not found or not readable at path: ${pdfFile.absolutePath}")
}
val renderDpi = dpi ?: 203
val safeIp = printerIp.trim()
if (safeIp.isEmpty()) throw IllegalArgumentException("Error: Printer IP is blank")

try {
// 1. Load the PDF document
PDDocument.load(pdfFile).use { document ->
val renderer = PDFRenderer(document)
val totalPages = document.numberOfPages

println("DEBUG: PDF has $totalPages pages")

// Print each page for the specified quantity
repeat(printQty ?: 1) { copyIndex ->
println("DEBUG: Printing copy ${copyIndex + 1} of ${printQty ?: 1}")

// Iterate through all pages in the PDF
for (pageIndex in 0 until totalPages) {
println("DEBUG: Processing page ${pageIndex + 1} of $totalPages")

// 2. Render each page of the PDF as a monochrome image
val image = renderer.renderImage(pageIndex, renderDpi / 72f, ImageType.BINARY)

// 3. Convert the image to a ZPL format string
val zplCommand = convertImageToZpl(image, printDirection)

// 4. Send each page as a separate print job
Socket(printerIp, printerPort).use { socket ->
val os: OutputStream = socket.getOutputStream()
val printData = zplCommand.toByteArray()
os.write(printData)
os.flush()
println("DEBUG: Page ${pageIndex + 1} sent to printer")
// Serialize all jobs per printer to prevent interleaving.
PrinterLockManager.withLock(safeIp, printerPort) {
// 1. Load the PDF document
PDDocument.load(pdfFile).use { document ->
val renderer = PDFRenderer(document)
val totalPages = document.numberOfPages

println("DEBUG: PDF has $totalPages pages")

// 2. Open ONE connection and stream the whole job.
Socket().use { socket ->
socket.tcpNoDelay = true
socket.connect(InetSocketAddress(safeIp, printerPort), 5_000)

val os: OutputStream = socket.getOutputStream()
val copies = printQty ?: 1

// Print each page for the specified quantity
repeat(copies.coerceAtLeast(1)) { copyIndex ->
println("DEBUG: Printing copy ${copyIndex + 1} of ${copies.coerceAtLeast(1)}")

// Iterate through all pages in the PDF
for (pageIndex in 0 until totalPages) {
println("DEBUG: Processing page ${pageIndex + 1} of $totalPages")

// Render each page of the PDF as a monochrome image
val image = renderer.renderImage(pageIndex, renderDpi / 72f, ImageType.BINARY)

// Convert the image to a ZPL format string (contains ^XA ... ^XZ)
val zplCommand = convertImageToZpl(image, printDirection)

// Send to printer (same socket for whole job)
os.write(zplCommand.toByteArray(Charsets.US_ASCII))

// Small delay between pages to ensure printer can process each page
Thread.sleep(100)
}
}

// Small delay between pages to ensure printer can process each page
Thread.sleep(100)
os.flush()
println("DEBUG: Print job sent to printer ($safeIp:$printerPort)")
}
}
}


正在加载...
取消
保存