浏览代码

Faster Canon Printer

stable1
kelvin.yau 1周前
父节点
当前提交
4a3b0e482a
共有 4 个文件被更改,包括 88 次插入26 次删除
  1. +15
    -7
      src/main/java/com/ffii/core/utils/CanonPrinterUtil.kt
  2. +56
    -17
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt
  3. +16
    -1
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt
  4. +1
    -1
      src/main/java/com/ffii/fpsms/modules/master/print/A4PrintDriverRegistry.kt

+ 15
- 7
src/main/java/com/ffii/core/utils/CanonPrinterUtil.kt 查看文件

@@ -1,6 +1,7 @@
package com.ffii.core.utils

import org.apache.pdfbox.pdmodel.PDDocument
import org.slf4j.LoggerFactory
import java.io.File
import java.io.OutputStream
import java.net.Socket
@@ -19,6 +20,7 @@ open class CanonPrinterUtil {
}

companion object {
private val log = LoggerFactory.getLogger(CanonPrinterUtil::class.java)
/**
* Detects if a PDF document is in landscape (horizontal) orientation.
*
@@ -105,13 +107,10 @@ open class CanonPrinterUtil {
// 6. Read PDF file content
val pdfContent = pdfFile.readBytes()

println("DEBUG: PDF file size: ${pdfContent.size} bytes")

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

// 7. Send to printer via TCP/IP socket
val copies = printQty ?: 1
repeat(copies) { copyIndex ->
val tSend = System.nanoTime()
Socket(printerIp, printerPort).use { socket ->
val os: OutputStream = socket.getOutputStream()

@@ -126,8 +125,17 @@ open class CanonPrinterUtil {
os.write("\u001B%-12345X".toByteArray(Charsets.US_ASCII))

os.flush()
println("DEBUG: Copy ${copyIndex + 1} sent to printer")
}
val sendMs = (System.nanoTime() - tSend) / 1_000_000.0
log.info(
"Canon printPdfToCanon: copy {} of {} sendMs={} printer={}:{} pdfBytes={} (high sendMs: check LAN/WiFi, firewall, or printer 9100 queue)",
copyIndex + 1,
copies,
sendMs,
printerIp,
printerPort,
pdfContent.size,
)
}
} catch (e: Exception) {
// Re-throw the exception with a more descriptive message


+ 56
- 17
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt 查看文件

@@ -79,6 +79,8 @@ import com.ffii.fpsms.modules.master.entity.ItemsRepository
import kotlin.collections.emptyMap
import com.ffii.fpsms.modules.master.print.A4PrintDriverRegistry
import com.ffii.core.response.RecordsRes
import net.sf.jasperreports.engine.JasperReport
import org.slf4j.LoggerFactory
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
@@ -87,6 +89,8 @@ import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfoLiteD
import com.ffii.fpsms.modules.stock.entity.InventoryLotLine
import com.ffii.fpsms.modules.stock.entity.projection.StockOutLineInfo
import java.util.Locale
import org.slf4j.Logger

@Service
open class DeliveryOrderService(
private val deliveryOrderRepository: DeliveryOrderRepository,
@@ -116,7 +120,7 @@ open class DeliveryOrderService(
private val doPickOrderRepository: DoPickOrderRepository,
private val doPickOrderLineRepository: DoPickOrderLineRepository,
private val doPickOrderLineRecordRepository: DoPickOrderLineRecordRepository,
private val itemsRepository: ItemsRepository
private val itemsRepository: ItemsRepository,
) {
open fun searchDoLiteByPage(
code: String?,
@@ -1064,26 +1068,31 @@ open class DeliveryOrderService(
@Throws(IOException::class)
@Transactional
open fun exportDeliveryNote(request: ExportDeliveryNoteRequest): Map<String, Any> {

// INPUT STREAM SETUP
val DELIVERYNOTE_PDF = "DeliveryNote/DeliveryNotePDF.jrxml"
val resource = ClassPathResource(DELIVERYNOTE_PDF)
if (!resource.exists()) {
throw FileNotFoundException("Report file not found: $DELIVERYNOTE_PDF")
}

val inputStream = resource.inputStream
val deliveryNote = JasperCompileManager.compileReport(inputStream)
val tAll0 = System.nanoTime()
val tJ0 = System.nanoTime()
val deliveryNote = deliveryNoteJasperTemplate
val jasperGetMs = (System.nanoTime() - tJ0) / 1_000_000.0

val fields = mutableListOf<MutableMap<String, Any>>()
val params = mutableMapOf<String, Any>()

// DRAFT & RECORD SEPARATION
if (request.isDraft) {
return exportDeliveryNoteFromDraft(request, deliveryNote, fields, params)
val tFill0 = System.nanoTime()
val result = if (request.isDraft) {
exportDeliveryNoteFromDraft(request, deliveryNote, fields, params)
} else {
return exportDeliveryNoteFromRecord(request, deliveryNote, fields, params)
}
exportDeliveryNoteFromRecord(request, deliveryNote, fields, params)
}
val fillDataMs = (System.nanoTime() - tFill0) / 1_000_000.0
val totalMs = (System.nanoTime() - tAll0) / 1_000_000.0
log.info(
"DeliveryNote export timing: jasperGetMs={} fillDataMs={} totalMs={} doPickOrderId={} isDraft={}",
jasperGetMs,
fillDataMs,
totalMs,
request.doPickOrderId,
request.isDraft,
)
return result
}

// DRAFT
@@ -1413,6 +1422,7 @@ open class DeliveryOrderService(
//Print Delivery Note
@Transactional
open fun printDeliveryNote(request: PrintDeliveryNoteRequest) {
val t0 = System.nanoTime()
val printer =
printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer")

@@ -1429,15 +1439,30 @@ open class DeliveryOrderService(
val tempPdfFile = File.createTempFile("print_job_", ".pdf")

try {
val t1 = System.nanoTime()
JasperExportManager.exportReportToPdfFile(jasperPrint, tempPdfFile.absolutePath)
val exportPdfToFileMs = (System.nanoTime() - t1) / 1_000_000.0

val printQty = if (request.printQty == null || request.printQty <= 0) 1 else request.printQty

val t2 = System.nanoTime()
printer.ip?.let { ip ->
val port = printer.port ?: 9100
val driver = A4PrintDriverRegistry.getDriver(printer.brand)
driver.print(tempPdfFile, ip, port, printQty)
}
val printToPrinterMs = (System.nanoTime() - t2) / 1_000_000.0
val totalMs = (System.nanoTime() - t0) / 1_000_000.0
log.info(
"DeliveryNote print-DN timing: exportPdfToFileMs={} printToPrinterMs={} totalMs={} doPickOrderId={} printerId={} printQty={} printerIp={}",
exportPdfToFileMs,
printToPrinterMs,
totalMs,
request.doPickOrderId,
request.printerId,
printQty,
printer.ip ?: "null",
)
updateRecordCartonQty(request.doPickOrderId, request.numOfCarton)
} finally {
//tempPdfFile.delete()
@@ -2146,5 +2171,19 @@ val inventoryLotLine = illId?.let { inventoryLotLineMap[it] }
problems = problems
)
}

private companion object {
private val log: Logger = LoggerFactory.getLogger(DeliveryOrderService::class.java)

private const val DELIVERYNOTE_JRXML = "DeliveryNote/DeliveryNotePDF.jrxml"

/** Compile once; avoids per-request JRXML recompilation (shared by download + print). */
private val deliveryNoteJasperTemplate: JasperReport by lazy {
val resource = ClassPathResource(DELIVERYNOTE_JRXML)
if (!resource.exists()) {
throw FileNotFoundException("Report file not found: $DELIVERYNOTE_JRXML")
}
resource.inputStream.use { inputStream -> JasperCompileManager.compileReport(inputStream) }
}
}
}

+ 16
- 1
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt 查看文件

@@ -44,6 +44,7 @@ import com.ffii.fpsms.modules.deliveryOrder.web.models.Check4FTruckBatchResponse
import com.ffii.fpsms.modules.deliveryOrder.web.models.DoSearchRowResponse
import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfoLite
import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfoLiteDto
import org.slf4j.LoggerFactory

@RequestMapping("/do")
@RestController
@@ -53,6 +54,8 @@ class DeliveryOrderController(
private val doPickOrderService: DoPickOrderService,
) {
private val log = LoggerFactory.getLogger(javaClass)

@PostMapping("/search-do-lite")
fun searchDoLite(@RequestBody request: SearchDeliveryOrderInfoRequest): RecordsRes<DeliveryOrderInfoLiteDto> {
println("DEBUG: searchDoLite - request: code=${request.code}, shopName=${request.shopName}, status=${request.status}")
@@ -233,13 +236,25 @@ class DeliveryOrderController(
@PostMapping("/DN")
@Throws(UnsupportedEncodingException::class, NoSuchMessageException::class, ParseException::class, Exception::class)
fun printDN(@Valid @RequestBody request: ExportDeliveryNoteRequest, response: HttpServletResponse){
val t0 = System.nanoTime()
response.characterEncoding = "utf-8"
response.contentType = "application/pdf"
val out: OutputStream = response.outputStream
val pdf = deliveryOrderService.exportDeliveryNote(request)
val jasperPrint = pdf["report"] as JasperPrint
response.addHeader("filename", "${pdf["filename"]}.pdf")
out.write(JasperExportManager.exportReportToPdf(jasperPrint))
val t1 = System.nanoTime()
val bytes = JasperExportManager.exportReportToPdf(jasperPrint)
val jasperExportToPdfBytesMs = (System.nanoTime() - t1) / 1_000_000.0
out.write(bytes)
val totalHttpMs = (System.nanoTime() - t0) / 1_000_000.0
log.info(
"DeliveryNote POST /do/DN (download) timing: jasperExportToPdfBytesMs={} totalResponseMs={} doPickOrderId={} isDraft={}",
jasperExportToPdfBytesMs,
totalHttpMs,
request.doPickOrderId,
request.isDraft,
)
}

@GetMapping("/print-DN")


+ 1
- 1
src/main/java/com/ffii/fpsms/modules/master/print/A4PrintDriverRegistry.kt 查看文件

@@ -3,7 +3,7 @@ package com.ffii.fpsms.modules.master.print
object A4PrintDriverRegistry {
private val drivers = mapOf(
"Canon" to CanonA4Driver(),
"Brother" to BrotherA4Driver()
"Brother" to BrotherA4Driver(),
)
private val defaultDriver = CanonA4Driver()



正在加载...
取消
保存