diff --git a/src/main/java/com/utopiaindustries/service/BarcodeService.java b/src/main/java/com/utopiaindustries/service/BarcodeService.java index 8883dce..ad699c0 100644 --- a/src/main/java/com/utopiaindustries/service/BarcodeService.java +++ b/src/main/java/com/utopiaindustries/service/BarcodeService.java @@ -1,11 +1,16 @@ package com.utopiaindustries.service; import com.google.zxing.BarcodeFormat; +import com.itextpdf.io.font.constants.StandardFonts; +import com.itextpdf.io.image.ImageData; import com.itextpdf.kernel.colors.ColorConstants; +import com.itextpdf.kernel.font.PdfFont; +import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.layout.element.AreaBreak; import com.itextpdf.layout.element.Paragraph; +import com.itextpdf.layout.property.AreaBreakType; import com.itextpdf.layout.property.TextAlignment; import com.utopiaindustries.dao.ctp.*; import com.utopiaindustries.model.ctp.*; @@ -29,6 +34,7 @@ import com.itextpdf.layout.element.Image; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; +import java.net.Socket; import java.nio.file.Path; import java.nio.file.FileSystems; @@ -58,6 +64,18 @@ public class BarcodeService { @Value("${ctp.printer.port}") private int port; + @Value("${ctp.printer.bundleIpAdd}") + private String bundleIpAddress; + + @Value("${ctp.printer.bundlePort}") + private int bundlePort; + + @Value("${ctp.printer.stitchQRPath}") + private String stitchPath; + + @Value("${ctp.printer.bundlePath}") + private String bundlePath; + private final BundleDAO bundleDAO; private final JobCardDAO jobCardDAO; private final MasterBundleDAO masterBundleDAO; @@ -94,7 +112,7 @@ public class BarcodeService { String sizeForStitchItem = BarcodeStickerSize.SIZE_1_X_2.name(); BarcodeStickerSize stickerSizeForStitchItem = BarcodeStickerSize.getSize(sizeForStitchItem); list = stitchingOfflineItemDAO.findByIds(ids); - getBarcodeImagesForStitchItems(list, stickerSizeForStitchItem, artifactType); + getBarcodeImagesForStitchItems(list, stickerSizeForStitchItem); } } @@ -107,7 +125,7 @@ public class BarcodeService { int cols = 2; int totalStickersPerPage = rows * cols; int totalPages = (int) Math.ceil((double) artifacts.size() / totalStickersPerPage); // Total required pages - + List bufferedImages = new ArrayList<>(); for (int page = 0; page < totalPages; page++) { // Create a Blank A4 Page Image BufferedImage a4Image = new BufferedImage(pageWidth, pageHeight, BufferedImage.TYPE_INT_ARGB); @@ -199,19 +217,62 @@ public class BarcodeService { String concatenatedIds = bundles.stream() .map(bundle -> String.valueOf(bundle.getId())) .collect(Collectors.joining("\\")); - this.drawCenteredText(g2d, "Sub-Bundles: " + concatenatedIds, detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 290, stickerSize.getMarginLeft()); } this.drawCenteredText(g2d, String.valueOf(artifact.getId()), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 330, 0); } - - // Finalize Drawing g2d.dispose(); - Path path = FileSystems.getDefault().getPath("./src/main/resources/static/barcode_a4_" + (page + 1) + ".png"); - File outputFile = path.toFile(); - ImageIO.write(a4Image, "PNG", outputFile); + bufferedImages.add(a4Image); } + saveA4ImageToPDF(bufferedImages,bundlePath); + try { + printPDF(bundleIpAddress, bundlePath); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void printPDF(String printerIP, String pdfFilePath) throws Exception { + File pdfFile = new File(pdfFilePath); + FileInputStream fis = new FileInputStream(pdfFile); + + Socket printerSocket = new Socket(printerIP, port); + OutputStream out = printerSocket.getOutputStream(); + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fis.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + out.flush(); + out.close(); + fis.close(); + printerSocket.close(); + } + + public void saveA4ImageToPDF(List a4Images, String outputFilePath) throws Exception { + PdfWriter writer = new PdfWriter(outputFilePath); + PdfDocument pdfDoc = new PdfDocument(writer); + Document document = new Document(pdfDoc, PageSize.A4); + document.setMargins(0, 0, 0, 0); + + for (int i = 0; i < a4Images.size(); i++) { + if (i > 0) { + document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(a4Images.get(i), "png", baos); + byte[] imageBytes = baos.toByteArray(); + ImageData imageData = ImageDataFactory.create(imageBytes); + Image image = new Image(imageData); + + // Scale and position correctly + image.scaleToFit(pdfDoc.getDefaultPageSize().getWidth(), pdfDoc.getDefaultPageSize().getHeight()); + image.setFixedPosition(0, 30); + document.add(image); + } + document.close(); } private void drawCenteredText(Graphics2D g2d, String text, Font font, int x, int y, int pageWidth, int cols, int marginTop, int marginLeft) { @@ -224,10 +285,9 @@ public class BarcodeService { public void getBarcodeImagesForStitchItems(List artifacts, - BarcodeStickerSize stickerSize, - String artifactType) throws Exception { + BarcodeStickerSize stickerSize) throws Exception { - Path pdfPath = FileSystems.getDefault().getPath("./src/main/resources/static/sample_qr_output.pdf"); + Path pdfPath = FileSystems.getDefault().getPath(stitchPath); PdfWriter writer = new PdfWriter(pdfPath.toFile()); PdfDocument pdfDoc = new PdfDocument(writer); Document document = new Document(pdfDoc); @@ -242,7 +302,7 @@ public class BarcodeService { canvas.rectangle(0, 0, stickerSize.getWidth(), stickerSize.getHeight()); canvas.fill(); - // Draw QR Code on Left Side** + // Draw QR Code on Left Side byte[] imgBytes = generateQRCodeImageByteArray(artifact.getBarcode(), stickerSize.getImageWidthBarcode(), stickerSize.getImageHeightBarcode()); Image qrCodeImage = new Image(ImageDataFactory.create(imgBytes)); @@ -253,40 +313,48 @@ public class BarcodeService { document.add(qrCodeImage); float textX = stickerSize.getMarginLeft() + 40; - float textY = stickerSize.getMarginTop() +40; + float textY = stickerSize.getMarginTop() + 40; String sku = artifact.getSku(); String jobCardCode = jobCard.getCode(); String combinedText = sku + " \\ " + jobCardCode + " \\ " + artifact.getBundleId(); + combinedText = combinedText.replaceAll("\\s+", ""); int maxLength = 14; List lines = new ArrayList<>(); for (int i = 0; i < 3; i++) { int start = i * maxLength; if (start < combinedText.length()) { - String part = combinedText.substring(start, Math.min(start + maxLength, combinedText.length())).trim(); + String part = combinedText.substring(start, Math.min(start + maxLength, combinedText.length())).replaceAll("\\s+", ""); lines.add(part); } } + float labelWidth = 67.69f; + float textBoxWidth = 220; float textY1 = textY-30; + float textXCenter = textX + (labelWidth / 2) - (textBoxWidth / 2)-50; + for (String line : lines) { Paragraph rotatedText = new Paragraph(line) .setFontColor(ColorConstants.BLACK) - .setFontSize((float) (stickerSize.getTextSize()+2)) - .setTextAlignment(TextAlignment.LEFT) - .setFixedPosition( textX-48, textY1-18, 220); + .setFontSize(stickerSize.getTextSize() + 2) + .setTextAlignment(TextAlignment.CENTER) + .setFixedPosition(textXCenter, textY1-18, textBoxWidth); document.add(rotatedText); textY1 -= 6; } + PdfFont font = PdfFontFactory.createFont(StandardFonts.COURIER_OBLIQUE); String id = String.valueOf(artifact.getId()); document.add(new Paragraph(id) + .setFont(font) .setFontColor(ColorConstants.BLACK) - .setFontSize(stickerSize.getTextSize()+6) + .setBold() + .setFontSize(stickerSize.getTextSize() + 8) .setTextAlignment(TextAlignment.LEFT) - .setFixedPosition(textX-21, textY + 10, 140)); + .setFixedPosition(textX - 25, textY + 8, 140)); float dottedLine = textY - 60; for(int i= 0 ;i<16;i++){ @@ -294,7 +362,7 @@ public class BarcodeService { .setFontSize(stickerSize.getTextSize()) .setFontColor(ColorConstants.BLACK) .setBold() - .setRotationAngle(-Math.PI / 2) // ✅ -90 Degree Rotate + .setRotationAngle(-Math.PI / 2) .setTextAlignment(TextAlignment.LEFT) .setFixedPosition(dottedLine,textX+40, 100)); @@ -307,17 +375,20 @@ public class BarcodeService { .setFontSize(stickerSize.getTextSize()) .setFontColor(ColorConstants.BLACK) .setBold() - .setRotationAngle(-Math.PI / 2) // ✅ -90 Degree Rotate + .setRotationAngle(-Math.PI / 2) .setTextAlignment(TextAlignment.LEFT) .setFixedPosition(dottedLine2,textX+75, 100)); dottedLine2 += 7; } - if (artifact != artifacts.get(artifacts.size() - 1)) { + if (!artifact.equals(artifacts.get(artifacts.size() - 1))) { document.add(new AreaBreak()); } } + if (pdfDoc.getNumberOfPages() > artifacts.size()) { + pdfDoc.removePage(pdfDoc.getNumberOfPages()); + } document.close(); sendPdfToZebraPrinter(pdfPath.toFile()); } @@ -336,7 +407,7 @@ public class BarcodeService { try { QRCodeWriter qrCodeWriter = new QRCodeWriter(); Map hintMap = new HashMap<>(); - hintMap.put(EncodeHintType.MARGIN, 1); // Optional: control margin size + hintMap.put(EncodeHintType.MARGIN, 0); BitMatrix bitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, width, height, hintMap); BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); qrImage.createGraphics().fillRect(0, 0, width, height); @@ -356,12 +427,41 @@ public class BarcodeService { } } - public void printLabel( BufferedImage bufferedImage ) throws Exception { - Connection connection = new TcpConnection( ipAddress, port ); + public void printLabel(BufferedImage bufferedImage) throws Exception { + Connection connection = new TcpConnection(ipAddress, port); connection.open(); - ZebraPrinter printer = ZebraPrinterFactory.getInstance( connection ); - ZebraImage zebraImage = new ZebraImage( bufferedImage ); - printer.printImage( zebraImage, 0, 0, 0, 0, false ); + + ZebraPrinter printer = ZebraPrinterFactory.getInstance(connection); + + //Reset Printer Settings + String resetSettings = "^XA^JUS^XZ"; + printer.sendCommand(resetSettings); + + //Force Label Length & Disable Auto Feed + String lengthFix = "^XA^LL555^PON^XZ"; // **Reduce Length (880) & Disable Auto Feed + printer.sendCommand(lengthFix); + + //Apply New Settings + String settings = "^XA" + + "^MMT" + // Continuous Mode + "^MTT" + // Thermal Transfer Mode + "^LH0,0" + // Home Position + "^PR6" + // Print Speed (~120mm/sec) + "^MD25" + // Darkness Level + "^PW541" + // Label Width (67.69mm for 203 DPI) + "^LL550" + // Reduced Label Length (fix gap) + "^PN0" + // No Extra Page Feed + "^PON" + // Disable Printer's Auto Feed Mode + "^XZ"; + + printer.sendCommand(settings); + + // Convert BufferedImage to ZebraImage + ZebraImage zebraImage = new ZebraImage(bufferedImage); + + // Print image + printer.printImage(zebraImage, 0, 0, 0, 0, false); + connection.close(); } } \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index b27236e..c69b363 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -32,5 +32,9 @@ spring: ctp: printer: - ipAdd: 172.16.53.32 - port: 9100 \ No newline at end of file + ipAdd: 172.16.53.53 + port: 9100 + stitchQRPath: ./src/main/resources/static/sample_qr_output.pdf + bundleIpAdd: 172.16.53.22 + bundlePort: 9100 + bundlePath: ./src/main/resources/static/bundle.pdf \ No newline at end of file