打印元素绘制协议Java实现

news2025/2/28 10:58:13

我一直提倡的面向接口和约定编程,而打印元素绘制协议一直是我推荐的打印实现方式,我以前只是强调按打印元素绘制协议输出数据就行了,有实现程序按协议控制打印,说是可以用任何语言实现客户端程序而不影响打印业务,那么这次就用Java实现打印元素绘制协议,来感受一下按协议编程的魅力吧。

打印设计请参照打印设计

首先以前的M都由虚拟M层替代了,这个就是访问地址
在这里插入图片描述

然后实现Java调用虚拟M逻辑,客户端通过此逻辑调虚拟M拿到符合打印元素绘制协议的数据

package JRTPrintDraw.WebService;

import javax.net.ssl.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.X509Certificate;
import java.util.HashMap;

import JRTPrintDraw.WebService.Parameters;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * 请求Webservice得到数据
 */
public class WebGetData {

    /**
     * 调用虚拟M方法得到数据
     *
     * @param Address   地址
     * @param ClassName 类名
     * @param FuncName  方法名
     * @param Param     参数
     * @param Session   会话
     * @return
     * @throws Exception
     */
    public static String GetData(String Address, String ClassName, String FuncName, Parameters Param, String Session) throws Exception {
        System.out.println("ClassName:" + ClassName);
        System.out.println("FuncName:" + FuncName);
        String result = "";
        DealNullPara(Param);
        String paraStr = "Method=GetData&ClassName=" + ClassName + "&FuncName=" + FuncName + "&Param=" + URLEncoder.encode(JRTPrintDraw.JsonDealUtil.Object2Json(Param), "UTF-8") + "&Session=" + URLEncoder.encode(Session, "UTF-8");

        try {
            //返回接受的数据
            result = GetHttpStr(Address, paraStr);
            //调用报错了
            if (!result.contains("<Response>")) {
                result = "<Response><SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>" + result + "</Error><Node></Node><RowCount>0</RowCount></Response>";
            }
        } catch (Exception ex) {
            result += ",异常信息:" + ex.getMessage() + ",调用:" + ClassName + "," + FuncName + "," + Param + "," + Session;
        }
        return DealXmlToJson(result);
    }

    /**
     * 把xml处理成json串
     *
     * @param xmlStr
     * @return
     * @throws Exception
     */
    private static String DealXmlToJson(String xmlStr) throws Exception {
        System.out.println("返回串:" + xmlStr);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new InputSource(new StringReader(xmlStr)));
        // 获得根节点
        Element rootElement = document.getDocumentElement();
        // 获得根节点下的所有子节点
        NodeList childs = rootElement.getChildNodes();
        HashMap dataMap = new HashMap();
        String ResultName = "";
        for (int i = 0; i < childs.getLength(); i++) {
            // 由于节点多种类型,而一般我们需要处理的是元素节点
            Node childNode = childs.item(i);
            // 元素节点就是非空的子节点,也就是还有孩子的子节点
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                Element childElement = (Element) childNode;

                dataMap.put(childElement.getNodeName(), childElement.getTextContent());
                //不是对象配置元素就忽略
                if (childElement.getNodeName().equals("Node")) {
                    ResultName = childElement.getTextContent() + "Result";
                }
            }
        }
        String Error = dataMap.get("Error").toString();
        if (!Error.isEmpty()) {
            System.out.println("异常:" + Error);
            throw new Exception(Error);
        }
        String ResType = dataMap.get("ResType").toString();
        System.out.println("数据串:" + dataMap.get(ResultName).toString());
        return dataMap.get(ResultName).toString();
    }


    /// <summary>
    /// 处理空参数
    /// </summary>
    /// <param name="Param"></param>
    private static void DealNullPara(Parameters Param) {
        if (Param.P0 == null) {
            Param.P0 = "";
        }
        if (Param.P1 == null) {
            Param.P1 = "";
        }
        if (Param.P2 == null) {
            Param.P2 = "";
        }
        if (Param.P3 == null) {
            Param.P3 = "";
        }
        if (Param.P4 == null) {
            Param.P4 = "";
        }
        if (Param.P5 == null) {
            Param.P5 = "";
        }
        if (Param.P6 == null) {
            Param.P6 = "";
        }
        if (Param.P7 == null) {
            Param.P7 = "";
        }
        if (Param.P8 == null) {
            Param.P8 = "";
        }
        if (Param.P9 == null) {
            Param.P9 = "";
        }
        if (Param.P10 == null) {
            Param.P10 = "";
        }
        if (Param.P11 == null) {
            Param.P11 = "";
        }
        if (Param.P12 == null) {
            Param.P12 = "";
        }
        if (Param.P13 == null) {
            Param.P13 = "";
        }
        if (Param.P14 == null) {
            Param.P14 = "";
        }
    }

    /**
     * 从http下载文本
     *
     * @param url  url
     * @param para 参数
     * @return 文本串
     * @throws Exception
     */
    private static String GetHttpStr(String url, String para) throws Exception {
        byte[] bytes = para.getBytes("UTF-8");

        //忽略证书
        if (url.contains("https://")) {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }
            };

            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
        }

        URL u = new URL(url);
        HttpURLConnection http = (HttpURLConnection) u.openConnection();
        http.setAllowUserInteraction(true);
        http.setDoOutput(Boolean.TRUE);
        http.setDoInput(Boolean.TRUE);
        http.setUseCaches(false);
        http.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
        http.setInstanceFollowRedirects(false);
        http.setRequestMethod("POST");
        http.connect();

        OutputStream outputStream = http.getOutputStream();
        outputStream.write(bytes);
        outputStream.flush();
        outputStream.close();

        InputStream is = http.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line + System.lineSeparator());
        }
        return stringBuilder.toString();
    }
}

然后实现打印元素绘制协议,这里把打印和绘图逻辑进行了分离,因为绘图逻辑后面还会给网站的在线打印预览用
在这里插入图片描述

在这里插入图片描述
按元素类型绘制
在这里插入图片描述

在这里插入图片描述

绘图与打印结合

package Monitor.Print;

import JRTPrintDraw.DrawConvert;
import JRTPrintDraw.DrawElement;
import JRTPrintDraw.JRTPrintDrawProtocol;
import JRTPrintDraw.JsonDealUtil;
import JRTPrintDraw.WebService.Parameters;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaTray;
import java.awt.*;
import java.awt.print.*;
import java.util.ArrayList;
import java.util.List;

public class PrintProtocol implements Printable {
    /**
     * 纸张名称
     */
    private String PageName;

    /**
     * 打印句柄
     */
    private JRTPrintDrawProtocol printHandeler=null;

    /**
     * 得到打印机
     * @param printerName
     * @return
     */
    public static PrintService GetPrinter(String printerName) {

        DocFlavor psInFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
        HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
        PrintService printService[] = PrintServiceLookup.lookupPrintServices(psInFormat, pras);
        PrintService myPrinter = null;
        //遍历所有打印机如果没有选择打印机或找不到该打印机则调用默认打印机
        for (PrintService printService2 : printService) {
            String svcName = printService2.toString();
            if (svcName.contains(printerName)) {
                myPrinter = printService2;
                break;
            }
        }
        if (myPrinter == null) {
            myPrinter = PrintServiceLookup.lookupDefaultPrintService();
            return myPrinter;
        }
        return myPrinter;
    }

    /**
     * 按打印元素绘制协议实现打印
     * @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) throws Exception{
        try {
            Parameters para=new Parameters();
            para.P0=rowids;
            para.P1=userCode;
            para.P2=paramList;
            para.P3=rowids;
            String json=JRTPrintDraw.WebService.WebGetData.GetData(connectString,className,funcName,para,"");
            System.out.println("打印数据:"+json);
            List<DrawElement> elementList= JsonDealUtil.Json2List(json,new DrawElement());
            System.out.println("转换List");
            // 通俗理解就是书、文档
            Book book = new Book();
            printHandeler=new JRTPrintDrawProtocol();
            int pageNum=printHandeler.JRTPrintDrawInit(elementList);
            System.out.println("页数:"+pageNum);
            // 获取打印服务对象
            PrinterJob job = PrinterJob.getPrinterJob();
            // 设置打印类
            job.setPageable(book);
            //设置成竖打
            PageFormat pf = new PageFormat();
            pf.setOrientation(PageFormat.PORTRAIT);
            boolean hasSetPaper=false;
            //控制打印机的数据
            if(elementList.get(0).PrintType.contains("PRINTER"))
            {
                DrawElement dr=elementList.get(0);
                //打印机名称
                String tPrinterName = elementList.get(0).PrintFlag;
                //选择打印机
                if(tPrinterName!=null&&!tPrinterName.isEmpty())
                {
                    PrintService printService=GetPrinter(tPrinterName);
                    job.setPrintService(printService);
                }

                //设置打印机其他参数
                if(dr.PrintType.equals("PRINTER"))
                {
                    //设置打印机宽度
                    int PrinterWidth = DrawConvert.ToInt32(dr.PrintWidth);
                    //设置打印机高度
                    int PrinterHeight = DrawConvert.ToInt32(dr.PrintHeight);
                    printHandeler.WriteLog("PRINTER得到纸张宽高:" + PrinterWidth + " " + PrinterHeight);
                    //页面名称
                    PageName = dr.DataField;
                    //停靠
                    String ReportLayout = dr.PrintAlignment;
                    printHandeler.WriteLog("PRINTER得打印机名称:" + tPrinterName);
                    //指定打印机送纸来源
                    int iPaperSource = DrawConvert.ToInt32(dr.PrintFont);
                    if (ReportLayout == "Landscape")
                    {
                        pf.setOrientation(PageFormat.LANDSCAPE);
                        printHandeler.WriteLog("PRINTER旋转纸张:Landscape");
                    }
                    //宽高大于0就控制
                    if(PrinterWidth>0&&PrinterHeight>0)
                    {
                        //通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
                        Paper paper = new Paper();
                        // 设置纸张大小为 A4 大小(210 mm × 297 mm)
                        int width = PrinterWidth;
                        int height = PrinterHeight;
                        //旋转
                        if (ReportLayout == "Landscape") {
                            int tmp=width;
                            width=height;
                            height=tmp;
                        }
                        double margin = 0;
                        paper.setSize(width, height);
                        paper.setImageableArea(margin, margin, width - 2 * margin, height - 2 * margin);
                        pf.setPaper(paper);
                        hasSetPaper=true;

                    }
                }
            }
            if(hasSetPaper==false)
            {
                Paper paper = new Paper();
                // 设置纸张大小为 A4 大小(210 mm × 297 mm)
                int width = 794;
                int height = 1123;
                double margin = 0;
                paper.setSize(width, height);
                paper.setImageableArea(margin, margin, width - 2 * margin, height - 2 * margin);
                pf.setPaper(paper);
            }
            book.append(this, pf,pageNum);
            if(printFlag.contains("PrintPreview"))
            {
                System.out.println("打印设置");
                job.print();
            }
            else
            {
                System.out.println("打印");
                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;
        if(printHandeler!=null)
        {
            try {
                int drawOneRet=printHandeler.DrawOnePage(g2, pageIndex);
                System.out.println(pageIndex+":"+drawOneRet);
                return drawOneRet;
            }
            catch (Exception ex)
            {
                if(ex.getCause()!=null)
                {
                    printHandeler.WriteLog(ex.getCause().getMessage());
                }
                else
                {
                    printHandeler.WriteLog(ex.getMessage());
                }
                ex.printStackTrace();
                return 1;
            }
        }
        return 1;
    }
}

这样就实现了Java的打印层,只要按打印元素绘制协议打印的业务不需要改就能话环境执行了

C#的效果
在这里插入图片描述

Java的效果
在这里插入图片描述

打磨好之后再把导出Excel实现了就基本实现JRT的最终目标了,导出一样的实现的有导出协议,我一般不直接写死业务,到时候开发换Linux都没毛病了,实现可以用任何语言都行,为啥打印也有Java呢,因为成本,不可能客户端程序再用一套编程语言实现,增加维护和开发成本,虽然写的比C#丑陋很多,也得忍着把实现了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++——初始化列表

初始化列表&#xff1a;一一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个“成员变量”后面跟一个放在括号中的初始值或表达式。 #include <iostream> using namespace std; class Date { public:Date(int year, int month, int day): _ye…

国标GBT 27930关键点梳理

1、充电总流程 整个充电过程包括六个阶段:物理连接完成、低压辅助上电、充电握手阶段、充电参数配置阶段、充电阶段和充电结束阶段。 在各个阶段,充电机和 BMS 如果在规定的时间内没有收到对方报文或没有收到正确报文,即判定为超时(超时指在规定时间内没有收到对方的完整数据包…

Hdoop学习笔记(HDP)-Part.06 安装OracleJDK

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

酷开科技 | 酷开系统,让家庭娱乐方式焕然一新!

在这个快节奏的社会&#xff0c;家庭娱乐已成为我们日常生活中不可或缺的一部分&#xff0c;为了给家庭带来更多欢笑与感动&#xff0c;酷开科技发力研发出拥有丰富内容和技术的智能电视操作系统——酷开系统&#xff0c;它集合了电影、电视剧、综艺、游戏、音乐等海量内容&…

大数据Doris(三十二):Doris高级功能

文章目录 Doris高级功能 一、​​​​​​​表结构变更

基于spring boot电子商务系统

一、 系统总体结构设计 (一) 功能结构图 图1-1 后台管理子系统 图1-2 电子商务子系统功能结构图 (二) 项目结构目录截图&#xff08;例如下图&#xff09; 图 1-3 系统目录图 (三) 系统依赖截图 图 1-2 所有依赖截图 (四) 配置文件 1、 全局配置文件 2、 其他配置文…

链表数组插入排序

InsertSort 插入排序算法&#xff0c;比如打扑克牌的算法时&#xff0c;按照从左到右&#xff0c;找到对应的位置插入排序 最重要的是位置移动 找到对应位置值 #include "iostream" #include "bits/stdc.h"using namespace std;void sort(vector<in…

高级前端面试中的三个 “送命题” !!!

原型与原型链 说到原型&#xff0c;就不得不提一下构造函数&#xff0c;首先我们看下面一个简单的例子&#xff1a; function Dog(name,age){this.name name;this.age age; }let dog1 new Dog("哈士奇",3); let dog2 new Dog("泰迪",2);首先创造空的…

Go GORM简介

GORM&#xff08;Go Object-Relational Mapping&#xff09;是一个用于Go语言的ORM库&#xff0c;它提供了一种简单、优雅的方式来操作数据库。GORM支持多种数据库&#xff0c;包括MySQL、PostgreSQL、SQLite和SQL Server。以下是GORM的一些主要特性 全功能ORM&#xff1a;GORM…

leetCode 47. 全排列 II + 回溯算法 + 图解 + 笔记

给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]] 示例 2&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2…

uniapp 微信小程序连接蓝牙卡死

解决方法&#xff0c;需要同意隐私保护协议&#xff0c;否则不能开启蓝牙权限和定位权限&#xff0c;会导致定位失败

.NET8构建统计Extreme Optimization Numerical Libraries

为 .NET 8 构建统计应用程序 Extreme Optimization Numerical Libraries for .NET V8.1.22 添加了对 .NET 8 的支持&#xff0c;使您可以使用最新版本的 Microsoft 平台。 Extreme Optimization Numerical Libraries for .NET 是通用数学和统计类的集合&#xff0c;为技术和统计…

基于 Python+flask 构建态势感知系统(附完整源码)

一、开发 一个基于linux的态势感知系统&#xff0c;基于python和flask框架开发&#xff0c;项目文件目录如下&#xff1a; admin -核心算法 charts -图表生成 model -类 app.py -主文件 config.py -配置文件 install.py -安装文件 二、安装 1、配置 数据库密码默认设…

进程的创建:fork()

引入 创建进程的方式我们已经学习了一个&#xff01;在我们运行指令(或者运行我们自己写的可执行程序)的时候不就是创建了一个进程嘛&#xff1f;那个创建进程的方式称为指令级别的创建子进程&#xff01; 那如果我们想要在代码中创建进程该怎么办呢&#xff1f; fork() for…

SSM框架(五):Maven进阶

文章目录 一、分模块开发1.1 分模块开发的意义1.2 步骤 二、依赖管理2.1 依赖传递2.2 可选依赖和排除依赖 三、继承与聚合3.1 聚合3.2 继承3.3 聚合和继承区别 四、属性4.1 pom文件的依赖使用属性4.2 资源文件使用属性 五、多环境开发六、跳过测试七、私服7.1 下载与使用7.2 私…

禁止谷歌浏览器自动更新

禁止谷歌浏览器自动更新 在使用Python包selenium的时候浏览器版版本发生变化后产生很多问题如&#xff1a; 1、直接版本不对应无法运行 2、版本不一致导致debug启动浏览器超级慢 这里是已谷歌浏览器为代表的。 禁止自动更新的方法如下&#xff1a; 1、WinR调出运行&#x…

一小时玩转【负载均衡】

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

SpringBoot 是如何启动一个内置的Tomcat

为什么说Spring Boot框架内置Tomcat 容器,Spring Boot框架又是怎么样去启动Tomcat的?我简单总结下学习过程。 一:简单了解SpringBoot的启动类 我们都知道Spring Boot框架的启动类上是需要使用 @SpringBootApplication 注解标注的, @SpringBootApplication 是一个复合注解…

Redis--10--Pipeline

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Pipeline举例比较普通模式与 PipeLine 模式小结&#xff1a; Pipeline 前面我们已经说过&#xff0c;Redis客户端执行一条命令分为如下4个部分:1&#xff09;发送命…

前端入门(五)Vue3组合式API特性

文章目录 Vue3简介创建Vue3工程使用vite创建vue-cli方式 常用 Composition API启动项 - setup()setup的执行时机与参数 响应式原理vue2中的响应式vue3中的响应式ref函数reactive函数reactive与ref对比 计算属性 - computed监视属性 - watchwatchEffect Vue3生命周期自定义hook函…