JRT和检验共用的打印层实现

之前对接的打印和导出是C#实现的,如果要完全Java化就需要用Java把打印元素绘制协议用Java实现,这次介绍实现主体搭建,最终使JRT达到完全信创和跨平台目标。到这篇后,所有的Java难题都解决完毕,几天到几周之内就可以把打印元素绘制协议完全实现,实现看着很快。至此可以一马平川的用Java了,没有M,一样可以领先,哈哈哈哈,框架完全体快出来了。

首先抽取消息处理接口

package Monitor.Msg;

import org.java_websocket.WebSocket;

/**
 * 抽取的处理前端传来的消息接口,不同类型的消息处理实现此接口从而实现不同的功能
 */
public interface IMessageDeal {
    /**
     * 处理消息
     * @param socket 套接字,可以获得id,发送消息给socket
     * @param message 约定#分割的第一位描述消息类型,收到的消息内容
     * @return 是否继续往后传递消息,true是,false否
     */
    public boolean DealMessage(WebSocket socket, String message);
}

然后实现打印消息处理

package Monitor.Msg;
import Monitor.Util.LogUtils;
import javafx.scene.control.Alert;
import org.java_websocket.WebSocket;

/**
 * 处理打印消息
 */
public class MessagePrintDeal implements Monitor.Msg.IMessageDeal {
    /**
     * 处理消息
     * @param socket 套接字,可以获得id,发送消息给socket
     * @param message 约定#分割的第一位描述消息类型,收到的消息内容
     * @return 是否继续往后传递消息,true是,false否
     */
    public boolean DealMessage(WebSocket socket, String message)
    {
        LogUtils.WriteDebugLog("识别以print#开头的消息");
        //识别打印消息
        if (message.split("#")[0].equals("print"))
        {
            LogUtils.WriteDebugLog("确定为打印消息,准备处理");
            int index = message.indexOf('#');
            String msg = message.substring(index + 1);
            String[] arrMsg = msg.split("@");

            //报告打印消息直接处理,不驱动exe,提高速度
            if (arrMsg.length > 5 && (!arrMsg[4].contains("PDF#")) && (arrMsg[0].equals("iMedicalLIS://0") || arrMsg[0].equals("iMedicalLIS://1")) && (!arrMsg[4].equals("ReportView")))
            {
                String cmdLine = msg.substring(14);
                String[] tmpStrings = cmdLine.split((char)64+"");
                String printFlag = tmpStrings[0];
                String connectString = tmpStrings[1].replace("&", "&");
                String rowids = tmpStrings[2];
                String userCode = tmpStrings[3];
                //PrintOut:打印  PrintPreview打印预览
                String printType = tmpStrings[4];
                //参数模块名称(LIS工作站,DOC医生,SELF自助,OTH其它)
                String paramList = tmpStrings[5];

                String clsName = "";
                String funName = "";
                if (tmpStrings.length >= 8)
                {
                    clsName = tmpStrings[6];
                    funName = tmpStrings[7];
                }

                //没传报告主键退出
                if (rowids == "" && printType != "ReportView")
                {
                    javafx.application.Platform.runLater(()->{

                        Alert alert = new Alert(Alert.AlertType.INFORMATION);
                        alert.setTitle("提示");
                        alert.setHeaderText("打印参数异常");
                        alert.setContentText("未传入报告主键");
                        alert.showAndWait();
                    });
                    return true;
                };
                String ip = "";
                String hostName = "";
                String mac = "";
                paramList = paramList + "^HN" + hostName + "^IP" + ip + "^MAC" + mac;
                //printFlag  0:打印所有报告 1:循环打印每一份报告
                if (printFlag.substring(0, 1).equals("0"))
                {
                    Monitor.Print.PrintProtocol reportPrint = new Monitor.Print.PrintProtocol(rowids, userCode, paramList, connectString, printType, clsName, funName);
                }
                else
                {
                    String[] tmpRowids = rowids.split((char)94+"");
                    for (int i = 0; i < tmpRowids.length; i++)
                    {
                        rowids = tmpRowids[i];
                        if (rowids != "")
                        {
                            Monitor.Print.PrintProtocol reportPrint = new Monitor.Print.PrintProtocol(rowids, userCode, paramList, connectString, printType, clsName, funName);
                        }
                    }
                }
            }
            return false;
        }
        LogUtils.WriteDebugLog("不是打印消息,传递消息链");
        return true;
    }
}

然后实现Websockt对接消息、

package Monitor.Websocket;

import Monitor.Util.LogUtils;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import Monitor.Msg.IMessageDeal;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

public class WebsocketServer extends WebSocketServer {
    /**
     * 存所有套接字
     */
    private static List<WebSocket> allSockets = new ArrayList<>();

    /**
     * 处理消息链对象
     */
    public List<IMessageDeal> LinkList=new ArrayList<>();

    /**
     * 构造函数
     * @param port
     */
    public WebsocketServer(int port) {
        super(new InetSocketAddress(port));
        Monitor.Util.LogUtils.WriteDebugLog("启动Websockt在"+port);
    }

    /**
     * 打开链接
     * @param conn 连接
     * @param handshake 握手
     */
    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
        LogUtils.WriteDebugLog("新客户端接入:" + conn.getRemoteSocketAddress());
        allSockets.add(conn);
    }

    /**
     * 断开连接
     * @param conn 连接
     * @param code 代码
     * @param reason 原因
     * @param remote 是否远程
     */
    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        LogUtils.WriteDebugLog("客户端断开:" + conn.getRemoteSocketAddress());
        allSockets.remove(conn);
    }

    /**
     * 收到消息
     * @param conn 连接
     * @param message 消息
     */
    @Override
    public void onMessage(WebSocket conn, String message) {
        System.out.println("收到消息:" + conn.getRemoteSocketAddress() + ": " + message);
        LogUtils.WriteDebugLog("#WS消息服务准备调用消息链...");
        try
        {
            if (LinkList.size() > 0)
            {
                for(IMessageDeal deal:LinkList)
                {
                    LogUtils.WriteDebugLog("#WS调用:" + deal.getClass().getName() + "...");
                    boolean ret = deal.DealMessage(conn, message);
                    LogUtils.WriteDebugLog("#WS调用:" + deal.getClass().getName() + "结束...");
                    //返回false不传递消息了
                    if (ret == false)
                    {
                        LogUtils.WriteDebugLog("#WS消息链不继续传递消息...");
                        break;
                    }
                }
            }
            LogUtils.WriteDebugLog("#WS消息服务调用消息链结束...");
        }
        catch (Exception ex)
        {
            LogUtils.WriteExceptionLog("#WS消息服务调用消息链异常", ex);
        }
    }

    /**
     * 发生错误
     * @param conn 连接
     * @param ex 异常
     */
    @Override
    public void onError(WebSocket conn, Exception ex) {
        LogUtils.WriteExceptionLog("发生错误:" + conn.getRemoteSocketAddress(),ex);
    }

    /**
     * 启动事件
     */
    @Override
    public void onStart() {

    }

}

包装log4j

package Monitor.Util;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogUtils {

    //调试日志
    static final Logger loggerDebug = LoggerFactory.getLogger("Debug");


    /**
     * 书写调试日志
     * @param message 日志内容
     */
    public static void WriteDebugLog(String message)
    {
        loggerDebug.error(message);
    }

    /**
     * 书写异常日志
     * @param message 描述
     * @param exception 异常
     */
    public static void WriteExceptionLog(String message, Exception exception)
    {
        loggerDebug.error(message, exception);
    }

}

实现exe程序

package Monitor;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import Monitor.Websocket.WebsocketServer;
import Monitor.Msg.MessagePrintDeal;

import java.net.URL;
import java.nio.file.Paths;

public class Main extends Application {

    // 创建一个TextArea控件
    TextArea textInfo = new TextArea();

    //日志路径
    String logPath="";

    @Override
    public void start(Stage primaryStage) throws Exception{
        String projectPath = System.getProperty("user.dir");
        Monitor.Util.LogUtils.WriteDebugLog("项目路径:" + projectPath);
        URL url = Main.class.getResource("");
        String bashPath = url.getPath();
        Monitor.Util.LogUtils.WriteDebugLog("程序路径:"+bashPath);
        //日志路径
        logPath= Paths.get(projectPath,"logs","Debug.log").toString();


        // 设置文本自动换行
        textInfo.setWrapText(true);

        Monitor.Util.LogUtils.WriteDebugLog("启动Websockt");
        WebsocketServer server=new WebsocketServer(8082);
        MessagePrintDeal printDeal=new MessagePrintDeal();
        server.LinkList.add(printDeal);
        server.start();

        SplitPane splitPane = new SplitPane();
        splitPane.setOrientation(Orientation.VERTICAL);

        // 刷新日志按钮
        Button btnRefresh = new Button("刷新日志");
        btnRefresh.setOnMouseClicked(e -> {
            RefreshLogs();
        });
        btnRefresh.setPrefHeight(30);

        // 清空日志按钮
        Button btnDelete = new Button("清空日志");
        btnDelete.setOnMouseClicked(e -> {
            DeleteLogs();
        });
        btnDelete.setPrefHeight(30);


        HBox top  = new HBox(20,btnRefresh,btnDelete);
        top.setPadding(new Insets(5,5,5,5));
        top.setPrefHeight(40);
        top.setMaxHeight(40);

        HBox bottom = new HBox(textInfo);
        textInfo.prefWidthProperty().bind(bottom.widthProperty());
        RefreshLogs();
        //VBox left = new VBox(new Label("left"));
        //VBox center = new VBox(new Label("center"));
        //VBox right = new VBox(new Label("right"));
        //SplitPane splitPane1 = new SplitPane();
        //splitPane1.getItems().setAll(left,center,right);

        splitPane.getItems().addAll(top, bottom);
        Scene scene = new Scene(splitPane);
        //primaryStage.setScene(scene);

        //Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
        //primaryStage.setTitle("JRTClient");
        primaryStage.setOnCloseRequest(event -> {
            try {
                server.stop();
            }
            catch (Exception ex)
            {

            }
        });
        primaryStage.setScene(scene);
        primaryStage.setMaximized(true);
        primaryStage.show();

    }

    /**
     * 刷新日志
     */
    public void RefreshLogs()
    {
        try {
            textInfo.setText(Monitor.Util.TxtUtil.ReadTextStr(logPath));
        }
        catch (Exception ex)
        {
        }
    }

    /**
     * 清空日志
     */
    public void DeleteLogs()
    {
        try {
            Monitor.Util.TxtUtil.WriteText2File(logPath,"");
            textInfo.setText("");
        }
        catch (Exception ex)
        {
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}

实现打印画图类

package Monitor.Print;

import java.awt.*;
import java.awt.print.*;

public class PrintProtocol implements Printable {
    /**
     * 按打印元素绘制协议实现打印
     * @param rowids 数据主键
     * @param userCode 用户
     * @param paramList 参数
     * @param connectString 连接串
     * @param printFlag 打印标识
     * @param className 调用类名
     * @param funcName 方法名称
     */
    public PrintProtocol(String rowids, String userCode, String paramList, String connectString, String printFlag, String className, String funcName){
        try {
            // 通俗理解就是书、文档
            Book book = new Book();
            // 设置成竖打
            PageFormat pf = new PageFormat();
            pf.setOrientation(PageFormat.PORTRAIT);

            // 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
            Paper paper = new Paper();
            // 设置纸张大小为 A4 大小(210 mm × 297 mm)
            double width = 827;
            double height = 1169;
            double margin = 10.0;
            paper.setSize(width, height);
            paper.setImageableArea(margin, margin, width - 2 * margin, height - 2 * margin);
            pf.setPaper(paper);
            book.append(this, pf,2);

            // 获取打印服务对象
            PrinterJob job = PrinterJob.getPrinterJob();
            // 设置打印类
            job.setPageable(book);
            job.print();
        } catch (PrinterException e) {
            e.printStackTrace();
        }
    }

    /**
     * 安逸画图
     * @param graphics
     * @param pageFormat
     * @param pageIndex
     * @return
     * @throws PrinterException
     */
    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        // 转换成Graphics2D 拿到画笔
        Graphics2D g2 = (Graphics2D) graphics;
        // 设置打印颜色为黑色
        g2.setColor(Color.black);

        //打印起点坐标
        double x = pageFormat.getImageableX();
        double y = pageFormat.getImageableY();
        if(pageIndex==0) {
            //设置打印字体(字体名称、样式和点大小)(字体名称可以是物理或者逻辑名称)
            Font font = new Font("宋体", Font.BOLD, 14);
            // 设置字体
            g2.setFont(font);
            //字体高度
            float heigth = font.getSize2D();
            g2.drawString("Java打印测试", (float) 10, 10);
            font = new Font("宋体", Font.BOLD, 12);
            // 设置字体
            g2.setFont(font);
            // 字体高度
            heigth = font.getSize2D();
            g2.drawString("张联珠", (float) 10, 60);
            g2.drawString("1890075****", (float) 10, 90);
            g2.drawString("张联珠", 10, 120);
            g2.drawString("0947809", 120, 120);

            font = new Font("宋体", Font.BOLD, 12);
            g2.setFont(font);
            heigth = font.getSize2D();
            g2.drawString("湖南长沙", 10, 150);
            g2.drawString("pageIndex:" + pageIndex, 10, 180);
            return PAGE_EXISTS;
        }
        else if(pageIndex==1) {
            //设置打印字体(字体名称、样式和点大小)(字体名称可以是物理或者逻辑名称)
            Font font = new Font("宋体", Font.BOLD, 14);
            // 设置字体
            g2.setFont(font);
            //字体高度
            float heigth = font.getSize2D();
            g2.drawString("Java打印测试", (float) 10, 10);
            font = new Font("宋体", Font.BOLD, 12);
            // 设置字体
            g2.setFont(font);
            // 字体高度
            heigth = font.getSize2D();
            g2.drawString("张联珠", (float) 10, 60);
            g2.drawString("18900752521", (float) 10, 90);
            g2.drawString("张联珠", 10, 120);
            g2.drawString("0947809", 120, 120);

            font = new Font("宋体", Font.BOLD, 12);
            g2.setFont(font);
            heigth = font.getSize2D();
            g2.drawString("湖南长沙", 10, 150);
            g2.drawString("第2页" , 10, 180);
            return PAGE_EXISTS;
        }
        else
        {
            return NO_SUCH_PAGE;
        }

    }
}

测试
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/204745.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++-多态常见试题的总结

关于C多态的介绍&#xff1a;C-多态-CSDN博客 1. A.只有类的成员方法才可以被virtual修饰&#xff0c;其他的函数并不可以 B.正确 C.virtual关键字只在声明时加上&#xff0c;在类外实现时不能加 D.static和virtual是不能同时使用的 2. A.多态分为编译时多态和运行时多态&…

算法通关村第十三关-白银挑战数字与数学高频问题

大家好我是苏麟 , 今天带来数字与数学的高频问题 . 加一 描述 : 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个…

ElementPlusError: [ElPagination] 你使用了一些已被废弃的用法,请参考 el-pagination 的官方文档

使用element table出现这个错误好几回了&#xff0c;今天把它记录一下&#xff0c;并把错误原因复盘一遍。具体如下&#xff1a; 错误截图 原因 其实这个错误挺迷的&#xff0c;我把各种情况都测试了一遍&#xff0c;最后发现是因为给 翻页参数 total 传值错误导致的。 总结…

.net-去重的几种情况

文章目录 前言1. int 类型的list 去重2. string类型的 list 去重3. T泛型 List去重4. 使用HashSet List去重5. 创建静态扩展方法 总结 前言 .net 去重的几种情况 1. int 类型的list 去重 // List<int> List<int> myList new List<int>(){ 100 , 200 ,100…

基于SSM的影视创作论坛设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

element ui 表格合计项合并

如图所示&#xff1a; 代码&#xff1a; <el-table height"400px" :data"tableData " borderstyle"width: 100%"stripe show-summaryref"table"id"table"> </el-table>监听表格 watch: { //监听table这个对象…

虚拟数字人有什么用?有哪些应用场景?

​​过去三年&#xff0c;元宇宙概念进入到大众视野&#xff0c;虚拟数字人备受关注。抖音达人柳夜熙、洛天依、网红虚拟偶像AYAYI等&#xff0c;随着元宇宙的流行&#xff0c;数字人也逐渐成为一种趋势。据行业预测&#xff0c;到2030年&#xff0c;中国的数字人总市场规模将达…

Android自动化测试中使用ADB进行网络状态管理!

技术分享&#xff1a;使用ADB进行Android网络状态管理 Android自动化测试中的网络状态切换是提高测试覆盖率、捕获潜在问题的关键步骤之一&#xff0c;本文将介绍 如何使用ADB检测和管理Android设备的网络状态。 自动化测试中的网络状态切换变得尤为重要。 网络状态查询 adb s…

websocket 消息包粗解

最近在搞websocket解析&#xff0c;记录一下: 原始字符串 &#xfffd;~&#xfffd;{"t":"d","d":{"b":{"p":"comds/comdssqmosm7k","d":{"comdss":{"cmdn":"success",…

postman打开白屏

现状&#xff1a;postman打开白屏如下图 window环境变量&#xff1a; Win R 快捷键打开 sysdm.cpl 增加环境变量&#xff1a; 变量名&#xff1a;POSTMAN_DISABLE_GPU 值&#xff1a;true 重新打开postman

【Python笔记】PyAutoGUI模块知识点整理

PyAutoGUI简介 pyautogul这个模块是用来模拟用户操作的模块&#xff0c;他可以模拟你的鼠标键盘等操作。可以说他是对我们个人而言最实用的库了。&#xff08;玩游戏再也不用重复无聊的操作&#xff0c;被迫做打工仔了&#xff09; 模块安装指令 python -m pip install -U py…

统信UOS_麒麟KYLINOS配置日志轮转

原文链接&#xff1a;统信UOS/麒麟KYLINOS配置日志轮转 hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇在统信UOS/麒麟KYLINOS上配置日志轮转的文章。本文举例的内容如下&#xff1a;首先我们创建一个定时任务&#xff0c;在每天00:00给/var/log/hello路径下的hello…

Yolov8实现瓶盖正反面检测

一、模型介绍 模型基于 yolov8n数据集采用SKU-110k&#xff0c;这数据集太大了十几个 G&#xff0c;所以只训练了 10 轮左右就拿来微调了 基于原木数据微调&#xff1a;训练 200 轮的效果 10 轮SKU-110k 20 轮原木 200 轮瓶盖正反面 微调模型下载地址https://wwxd.lanzouu.co…

新建的springboot项目中application.xml没有绿色小叶子(不可用)

经常有朋友会遇到新建了一个springboot项目&#xff0c;发现为啥我创建的application.xml配置文件不是绿色的&#xff1f;&#xff1f;&#xff1f; 下面教大家如何解决&#xff0c;这也是博主在做测试的时候遇到的&#xff1a; 将当前位置application.xml删掉&#xff0c;重新…

销售客户分配管理细则

随着市场竞争的不断加剧&#xff0c;销售团队的有效管理变得愈发重要。其中&#xff0c;客户分配是销售团队成功的关键之一。一个科学合理的销售客户分配管理细则不仅可以提高销售团队的整体工作效率&#xff0c;还能够优化客户体验&#xff0c;促使销售业绩持续增长。下面是一…

排序分析(Ordination analysis)及R实现

在生态学、统计学和生物学等领域&#xff0c;排序分析是一种用于探索和展示数据结构的多元统计技术。这种分析方法通过将多维数据集中的样本或变量映射到低维空间&#xff0c;以便更容易理解和可视化数据之间的关系。排序分析常用于研究物种组成、生态系统结构等生态学和生物学…

将360调配成绿色无弹窗软件

相信很多小伙伴都跟我一样喜欢杀毒软件的功能。而小编认为最好用的杀毒软件就是360了。360功能齐全&#xff0c;界面美观&#xff0c;但总是有很多弹窗小广告&#xff0c;怎么办呢&#xff1f; 今天就来就来教大家如何将360设置为绿色无弹窗软件 将360调配成绿色无弹窗软件 一…

9款高效绘图神器,提升你的工作效率

在日常工作或生活中&#xff0c;我们必须绘制各种图表、流程图、思维导图等图形&#xff0c;或者想用画笔描述自己的想法。然而&#xff0c;我们在许多绘图软件面前感到困惑。我们不知道哪个绘图软件好&#xff0c;也没有足够的时间一一尝试 在接下来的空间里&#xff0c;我们…

python之pyqt专栏9-鼠标事件

目录 需求 UI界面 代码实现 代码解析&#xff1a; Label初始化设置 重写鼠标按下事件 重写鼠标释放事件 重写鼠标移动事件 运行结果 需求 当鼠标进入窗口时&#xff0c;点击鼠标左键&#xff0c;出现一个label并在显示光标在窗口的坐标&#xff1b;按住左键不释放拖动…

Java学习day15:Object类、set集合(知识点+例题详解)

声明&#xff1a;该专栏本人重新过一遍java知识点时候的笔记汇总&#xff0c;主要是每天的知识点题解&#xff0c;算是让自己巩固复习&#xff0c;也希望能给初学的朋友们一点帮助&#xff0c;大佬们不喜勿喷(抱拳了老铁&#xff01;) 往期回顾 Java学习day14&#xff1a;权限…