异步画图打印小票

一:先画出要打印的小票

这里算出整个画图的内容高度,方便调打印机

private int drawByGraphics(PrintSmallTicketTemplateConfig req, Graphics2D g){
        try {
            Map<String, Object> map = req.getMapList();
            List<PrintSmallTicketTemplateConfig.Draw> draws = req.getPrintConfig();
                int width = Integer.parseInt(draws.get(0).getForm().getWidth());
            draws = draws.stream().sorted(Comparator.comparing(i -> Integer.parseInt(i.getForm().getPositionTop()))).collect(Collectors.toList());

            g.setBackground(Color.white);
            int allHeight = 0;
            for (PrintSmallTicketTemplateConfig.Draw draw : draws) {
                //总高度
                if (draw.getType().equals("taodi")) {
                    //                        Color color = new Color(Integer.parseInt(draw.getFont().getColor().replaceAll("#", ""), 16));
                    //                        g.setColor(color);
                    //                        Font font = new Font("Microsoft YaHei", Font.PLAIN, draw.getFont().getSize());
                    //                        g.setFont(font);
                    //                        String value;
                    //                    g.setStroke(new BasicStroke(1.5f));
                    //                    g.setColor(Color.black);
                    //                    g.drawLine(0, 0, Integer.parseInt(draw.getForm().getWidth()), 0);
                    //                    g.drawLine(0, 0, 0, Integer.parseInt(draw.getForm().getHeight()));
                    //                    g.drawLine(0, Integer.parseInt(draw.getForm().getHeight()), Integer.parseInt(draw.getForm().getWidth()), Integer.parseInt(draw.getForm().getHeight()));
                    //                    g.drawLine(Integer.parseInt(draw.getForm().getWidth()), 0, Integer.parseInt(draw.getForm().getWidth()), Integer.parseInt(draw.getForm().getHeight()));
                } else if (draw.getType().equals("line")) {
                    int currentY = Integer.parseInt(draw.getForm().getPositionTop());
                    if (allHeight != 0) {
                        currentY += allHeight;
                    }
                    int currentX = Integer.parseInt(draw.getForm().getPositionLeft());
                    float[] dash1 = {2f, 0f, 2f};
                    if ("solid".equals(draw.getForm().getBorStyle())) {
                        g.setStroke(new BasicStroke(1.5f));
                    } else {
                        g.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT,

                                BasicStroke.JOIN_ROUND,

                                1.0f,

                                dash1,

                                2f));
                    }
                    g.setColor(new Color(Integer.parseInt(draw.getForm().getBorColor().replaceAll("#", ""), 16)));
                    g.drawLine(Integer.parseInt(draw.getForm().getPositionLeft()), currentY, Integer.parseInt(draw.getForm().getPositionLeft()) + Integer.parseInt(draw.getForm().getWidth()), currentY);

                }else if (draw.getType().equals("text")) {
                        Color color = new Color(Integer.parseInt(draw.getForm().getTextColor().replaceAll("#", ""), 16));
                        g.setColor(color);
                        Font font = new Font("Microsoft YaHei", Font.PLAIN, Integer.parseInt(draw.getForm().getSize()));
                        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
                        g.setFont(font);
                        String value;
                        String content="";
                        int staticStrWidth = 0;
                        int strWidth =0;
                        if ("static".equals(draw.getForm().getState())) {
                            value = draw.getForm().getContent();
                            if(!StringUtils.isEmpty(value)) {
                                strWidth = getWordWidth(font, value);
                            }
                        } else if ("onlyDynamic".equals(draw.getForm().getState())) {
                            value = (String) map.get(draw.getForm().getDynamicKey());
                            if(!StringUtils.isEmpty(value)) {
                                strWidth = getWordWidth(font, value);
                            }
                        } else {
                            value = draw.getForm().getContent() + (String) map.get(draw.getForm().getDynamicKey());
                            content=(String) map.get(draw.getForm().getDynamicKey());
                            if(!StringUtils.isEmpty(value)) {
                                staticStrWidth = getWordWidth(font, draw.getForm().getContent());
                            }if(!StringUtils.isEmpty(content)) {
                                strWidth = getWordWidth(font, content);
                            }
                        }
                        if (!StringUtils.isEmpty(value)) {

                            //静态内容宽度
                            System.out.println("字符总宽度:" + strWidth);
                            //第一行字符宽度
                            int ww = width - Integer.parseInt(draw.getForm().getPositionLeft())-staticStrWidth;
                            int rowstrnum = 0;
                            rowstrnum = (ww * value.length()) / strWidth;
                            System.out.println("每行的字符数:" + rowstrnum);

                            int rows = 0;
                            if (strWidth % ww > 0) {
                                rows = strWidth / ww + 1;
                            } else {
                                rows = strWidth / ww;
                            }
                            System.out.println("行数:" + rows);
                            int height1 = g.getFontMetrics().getHeight();
                            System.out.println("字符高度:" + height1);
                            g.setFont(font);
                            //当前y坐标
                            int currentY = Integer.parseInt(draw.getForm().getPositionTop());
                            if (allHeight != 0) {
                                currentY += allHeight;
                            }
                            if (strWidth > ww) {
                                String temp = "";
                                for (int i = 0; i < rows; i++) {
                                    //获取各行的String
                                    if (i == rows - 1) {
                                        //最后一行
                                        temp = value.substring(i * rowstrnum);
                                    } else {
                                        temp = value.substring(i * rowstrnum, i * rowstrnum + rowstrnum);
                                    }
                                    if (i > 0) {
                                        //第一行不需要增加字符高度,以后的每一行在换行的时候都需要增加字符高度
                                        currentY = currentY + height1;
                                    }if(i==0) {
                                        g.drawString(temp, Integer.parseInt(draw.getForm().getPositionLeft()) , currentY + metrics.getAscent());
                                    }else{
                                        g.drawString(temp, Integer.parseInt(draw.getForm().getPositionLeft())+ staticStrWidth, currentY + metrics.getAscent());
                                    }
                                }
                            } else {
                                //
                                g.setFont(font);
                                g.drawString(value, Integer.parseInt(draw.getForm().getPositionLeft()), currentY + metrics.getAscent());
                            }
                            if (rows > 1) {
                                allHeight += height1 * (rows-1);
                            }

                        }
                } else if (draw.getType().equals("table")) {
                    int x = Integer.parseInt(draw.getForm().getPositionLeft());
                    int currentY = Integer.parseInt(draw.getForm().getPositionTop());
                    if (allHeight != 0) {
                        currentY += allHeight;
                    }
                    g.setColor(Color.black);
                    Font font = new Font("Microsoft YaHei", Font.BOLD, Integer.parseInt(draw.getForm().getHeaderFsize()));
                    FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
                    int tableWidth = Integer.parseInt(draw.getForm().getPositionLeft());
                    for (int i = 0; i < draw.getForm().getTableColumn().size(); i++) {
                        if (i != 0) {
                            x += Integer.parseInt(draw.getForm().getTableColumn().get(i - 1).getWidth());
                        }
                        tableWidth += Integer.parseInt(draw.getForm().getTableColumn().get(i).getWidth());
                        String tableLabel = draw.getForm().getTableColumn().get(i).getLabel();
                        int wordWidth = getWordWidth(font, tableLabel);
                        // 添加字体的属性设置
                        g.setFont(font);
                        g.drawString(draw.getForm().getTableColumn().get(i).getLabel(), x + (Integer.parseInt(draw.getForm().getTableColumn().get(i).getWidth()) - wordWidth) / 2, currentY + metrics.getAscent());
                    }
                    if ("true".equals(draw.getForm().getIsBorder())) {
                        g.setStroke(new BasicStroke(1.5f));
                        g.drawLine(Integer.parseInt(draw.getForm().getPositionLeft()), currentY + metrics.getAscent() + metrics.getDescent(), tableWidth, currentY + metrics.getAscent() + metrics.getDescent());
                    }
                    currentY += 2 * metrics.getAscent() + metrics.getDescent();
                    int tableY = currentY;
                    g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 15));
                    java.util.List<Object> table = (List<Object>) map.get(draw.getForm().getTableName());
                    if (!CollectionUtils.isEmpty(table)) {
                        // 循环表格内容
                        for (Object o : table) {
                            font = new Font("Microsoft YaHei", Font.PLAIN, Integer.parseInt(draw.getForm().getCellFsize()));
                            g.setFont(font);
                            x = Integer.parseInt(draw.getForm().getPositionLeft());
                            Map<String, String> objectMap = (Map<String, String>) o;
                            int maxHeight = 0;
                            //循环表格每一行的数据
                            for (PrintSmallTicketTemplateConfig.Draw.Column s : draw.getForm().getTableColumn()) {

                                String value = objectMap.get(s.getProp());
                                char[] strcha = value.toCharArray();
                                int strWidth = g.getFontMetrics().charsWidth(strcha, 0, value.length());
                                int ww = Integer.parseInt(s.getWidth());
                                int rowstrnum = 0;
                                rowstrnum = (ww * value.length()) / strWidth;
                                System.out.println("每行的字符数:" + rowstrnum);
                                int hang = 0;
                                int rows = 0;
                                if (strWidth % ww > 0) {
                                    rows = strWidth / ww + 1;
                                } else {
                                    rows = strWidth / ww;
                                }
                                System.out.println("行数:" + rows);
                                int height1 = g.getFontMetrics().getHeight();
                                //一行高度
                                hang = height1 * (rows);
                                if (maxHeight < hang) {
                                    maxHeight = hang;
                                }
                                System.out.println("行数:" + rows);
                                int hei = g.getFontMetrics().getHeight();
                                System.out.println("字符高度:" + height1);
                                if (strWidth > ww) {
                                    String temp = "";
                                    for (int j = 0; j < rows; j++) {
                                        //获取各行的String
                                        if (j == rows - 1) {
                                            //最后一行
                                            temp = value.substring(j * rowstrnum);
                                        } else {
                                            temp = value.substring(j * rowstrnum, j * rowstrnum + rowstrnum);
                                        }
                                        if (j > 0) {
                                            //第一行不需要增加字符高度,以后的每一行在换行的时候都需要增加字符高度
                                            currentY = currentY + hei;
                                        }
                                        g.drawString(temp, x, currentY);

                                    }
                                    currentY = tableY;
                                    x += Integer.parseInt(s.getWidth());
                                } else {
                                    int wordWidth = getWordWidth(font, value);
                                    g.drawString(value, x + (Integer.parseInt(s.getWidth()) - wordWidth) / 2, currentY);
//                                    g.drawString(value, x, currentY);
                                    x += Integer.parseInt(s.getWidth());
                                }
                            }
                            currentY += maxHeight;
                            allHeight += maxHeight;
                            tableY += maxHeight;

                        }
                    }
                    if ("true".equals(draw.getForm().getIsBorder())) {
                        g.setStroke(new BasicStroke(1f));
                        g.drawLine(Integer.parseInt(draw.getForm().getPositionLeft()), currentY, tableWidth, currentY);
                    }
                } else if (draw.getType().equals("images")) {
                    int currentY = Integer.parseInt(draw.getForm().getPositionTop());
                    if (allHeight != 0) {
                        currentY += allHeight;
                    }
                    //定义一个URL对象,就是你想下载的图片的URL地址
                    URL url = new URL(draw.getForm().getSrc());
                    //打开连接
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    //设置请求方式为"GET"
                    conn.setRequestMethod("GET");
                    //超时响应时间为10秒
                    conn.setConnectTimeout(10 * 1000);
                    //通过输入流获取图片数据
                    InputStream is = conn.getInputStream();
                    Image chop = ImageIO.read(is);
                    log.info("画一次图片...");
                    g.drawImage(chop, Integer.parseInt(draw.getForm().getPositionLeft()), currentY, Integer.parseInt(draw.getForm().getWidth()), Integer.parseInt(draw.getForm().getHeight()), null);
                } else if (draw.getType().equals("qrcode")) {
                    String drawImg = QRCodeTool.createQRCodeToBase64(draw.getForm().getText(), 300, ErrorCorrectionLevel.L);
                    Image chop;
                    if (drawImg.contains("base64,")) {
                        String base64 = drawImg.replaceAll("data:image/jpeg;base64,", "");
                        base64 = base64.replaceAll("data:image/jpg;base64,", "");
                        String tmp = "E:\\xx.png";
                        Files.write(Paths.get(tmp), Base64.getDecoder().decode(base64), StandardOpenOption.CREATE);
                        ImageIcon imgIcon = new ImageIcon(tmp);
                        chop = imgIcon.getImage();
                        File tmpFile = new File(tmp);
                        tmpFile.delete();
                        log.info("画一次图片...");
                        int y = Integer.parseInt(draw.getForm().getPositionTop());
                        if (allHeight != 0) {
                            y = y + allHeight;
                        }
                        g.drawImage(chop, Integer.parseInt(draw.getForm().getPositionLeft()), y, Integer.parseInt(draw.getForm().getWidth()), Integer.parseInt(draw.getForm().getHeight()), null);
                    }
                } else if (draw.getType().equals("barcode")) {
                    int currentY = Integer.parseInt(draw.getForm().getPositionTop());
                    if (allHeight != 0) {
                        currentY += allHeight;
                    }

                    Pattern pattern = Pattern.compile("[\u4e00-\u9fa5]");
                    String s = draw.getForm().getText();
                    Matcher m = pattern.matcher(s);
                    if (!m.find()) {
                        // 如果字符串中含有中文,m.find()判断为true

                        /* 转换开始 */
                        byte[] bytes = BarCodeUtils.generateBarCode128(
                                draw.getForm().getText(), 10.00, 0.3, true, false);
                        if (!org.springframework.util.StringUtils.isEmpty(bytes)) {
                            ImageIcon imgIcon = new ImageIcon(bytes, "Miho");
                            Image chop = imgIcon.getImage();
                            log.info("画条形码...");
                            g.drawImage(chop, Integer.parseInt(draw.getForm().getPositionLeft()), currentY, 100, 50, null);
                        }
                    }
                }
            }
            g.dispose();
            int w = Integer.parseInt(draws.get(draws.size() - 1).getForm().getPositionTop()) + allHeight+20;
            if(draws.get(draws.size() - 1).getType().equals("qrcode")||draws.get(draws.size() - 1).getType().equals("barcode")){
                w+=Integer.parseInt(draws.get(draws.size() - 1).getForm().getHeight());
            }

            return w;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

二,调用打印机打印图片

 @Override
    public void sync(PrintSmallTicketTemplateConfig req, CompletableFuture<ApiResp> future) {
        if(LocalPluginApplication.ifPrinting) {
            System.out.println("1111111");
            future.completeExceptionally(new RuntimeException(String.valueOf(RespEnum.PRINTER_PING_BUSY)));
            return;
        }
//获取本地主机
        try{
            InetAddress net=InetAddress.getLocalHost();
            //输出
            System.out.println(net);
log.info("局域网地址ip--------------------------------------{}",net);
        }catch(UnknownHostException e){
            e.printStackTrace();
        }
        LocalPluginApplication.ifPrinting = true;

//        BufferedImage bimage = new BufferedImage(200, 550, BufferedImage.TYPE_INT_RGB);
//        Graphics2D g2d = bimage.createGraphics();
//        g2d.setPaint(Color.white);
//        g2d.fillRect(0,0,200,550);
//        g2d.setColor(Color.BLACK);
//        g2d.setFont(new Font("Serif", Font.PLAIN, 20));
//        g2d.drawString("测试测试1212", 10,30);
//        g2d.drawString("测试测试3331", 10,120);
//        g2d.drawString("测试测试6611", 10,120);
//        g2d.dispose();

//        future.complete(bimage);
//
//        log.info(">>> 1111111111111111111111111111111");

        Book book = new Book();
        // 打印格式
        PageFormat pf = new PageFormat();
        // 原点在纸张的左上方,x 指向右方,y 指向下方。
        pf.setOrientation(PageFormat.PORTRAIT);
        // 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
        Paper p = new Paper();
        int width = Integer.parseInt(req.getPrintConfig().get(0).getForm().getWidth());
        // 页面宽度 页面高度
        p.setSize(width, 100000);
        // x轴 y轴 宽度 高度
        p.setImageableArea(0, 0, width, 100000);
        pf.setPaper(p);

        book.append((graphics, pageFormat, pageIndex) -> {
            int height = drawByGraphics(req, (Graphics2D) graphics);

            if(height > 0) {
                BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics2D gimg = bimage.createGraphics();
                gimg.fillRect(0,0,width, height);
                drawByGraphics(req, gimg);
                gimg.dispose();

                ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
                try {
                    ImageIO.write(bimage, "png", baos);//写入流中
                } catch (IOException e) {
                    e.printStackTrace();
                }
                byte[] bytes = baos.toByteArray();//转换成字节
                BASE64Encoder encoder = new BASE64Encoder();
                String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
                png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
                Map<String,String> resultMap = new HashMap<>();
                resultMap.put("image", "data:image/png;base64," + png_base64);
                future.complete(ApiResp.buildSuccess(null, null, resultMap));
            }

            return Printable.PAGE_EXISTS;
        }, pf);

        // 指定打印机打印(printerName打印机名称)
        HashAttributeSet hs = new HashAttributeSet();
        String printerName = "XP-80C";
        hs.add(new PrinterName(printerName, null));
        javax.print.PrintService[] pss = PrintServiceLookup.lookupPrintServices(null, hs);
        if (pss.length == 0) {
            System.out.println("无法找到打印机:" + printerName);
            try {
                throw new PrinterException(String.valueOf(RespEnum.PRINT_EXCEPTION));
            } catch (PrinterException e) {
                e.printStackTrace();
            }
            return;
        }
        // 获取打印服务对象
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setJobName("测试打印明");
        // 写入书
        job.setPageable(book);
        try {
            // 添加指定的打印机
            job.setPrintService(pss[0]);
            // 打印执行
            job.print();

            //
        } catch (PrinterException e) {
            try {
                throw new PrinterException(String.valueOf(RespEnum.PRINT_EXCEPTION));
            } catch (PrinterException printerException) {
                printerException.printStackTrace();
            }
        }


        LocalPluginApplication.ifPrinting = false;

    }

算出内容的宽度

 public static int getWordWidth(Font font, String content) {
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int width = 0;
        for (int i = 0; i < content.length(); i++) {
            width += metrics.charWidth(content.charAt(i));
        }
        return width;
    }

三.异步返回图片和打印小票

  @PostMapping(value = "/image")
    public DeferredResult<ApiResp> sync(@RequestBody PrintSmallTicketTemplateConfig req){
        DeferredResult<ApiResp> deferredResult = new DeferredResult<>(30000l);
        CompletableFuture<ApiResp> future = new CompletableFuture<>();

        printService.sync(req, future);
        future.whenComplete((result, error) -> {
            if(error == null) {
                deferredResult.setResult(result);
            }else {
                deferredResult.setErrorResult(null);
            }
        });
        return deferredResult;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值