JRT实现在线打印预览

在JRT打印元素绘制协议一篇已经介绍过打印把绘图和打印逻辑进行了分离,这是和老设计最大的不同。因为老的设计时候没想着做在线预览功能,是后面硬性扩出来的。这次从最初设计就考虑绘图逻辑各处共用,包括打印预览,在线打印预览等、后面还会再加PDF之类的。

总之:设计很重要,设计不到位后期功能难做,复杂度也会很高。

先看效果:
在这里插入图片描述

在这里插入图片描述

后台ashx对接绘图

import JRT.Core.Dto.OutValue;
import JRT.Core.MultiPlatform.FileCollection;
import JRT.Model.Bussiness.Parameters;
import JRTBLLBase.BaseHttpHandlerNoSession;
import JRTBLLBase.Helper;
import JRT.Core.Dto.HashParam;
import JRT.Core.Dto.ParamDto;
import JRT.Core.Dto.OutParam;
import JRT.Model.Entity.*;
import JRT.Core.Util.Convert;
import JRT.Core.MultiPlatform.JRTContext;
import JRTPrintDraw.DrawElement;
import JRTPrintDraw.JRTPrintDrawProtocol;
import JRTPrintDraw.JsonDealUtil;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.List;/*** 打印绘图在线预览的后台类,对接打印绘图库,由于打印元素绘制协议是完全剥离的,所以很好共用,这样体现了设计的优势*/
public class ashJRTPrintDrawView  extends BaseHttpHandlerNoSession {/*** 得到打印画图的图片。分页的话有多张图片,在C#层面对接,返回串自己在前面加data:image/png;base64,后给图片绑定。分页多个图的Base64串以^分隔* @return* @throws Exception*/public String QryPrintDrawImgs() throws Exception{//打印M类名String ClassName = Helper.ValidParam(JRTContext.GetRequest(Request,"ClassName"), "");//打印M方法名String FuncName = Helper.ValidParam(JRTContext.GetRequest(Request,"FuncName"), "");//绘图宽度int Width = Helper.ValidParam(JRTContext.GetRequest(Request,"Width"), 827);//绘图高度int Height = Helper.ValidParam(JRTContext.GetRequest(Request,"Height"), 583);//返回类型String RetType = "BASE64";//文件名String FileName = Helper.ValidParam(JRTContext.GetRequest(Request,"FileName"), "PrintImg.bmp");Parameters param = new Parameters();param.P0 = Helper.ValidParam(JRTContext.GetRequest(Request,"P0"), "");param.P1 = Helper.ValidParam(JRTContext.GetRequest(Request,"P1"), "");param.P2 = Helper.ValidParam(JRTContext.GetRequest(Request,"P2"), "");param.P3 = Helper.ValidParam(JRTContext.GetRequest(Request,"P3"), "");param.P4 = Helper.ValidParam(JRTContext.GetRequest(Request,"P4"), "");param.P5 = Helper.ValidParam(JRTContext.GetRequest(Request,"P5"), "");param.P6 = Helper.ValidParam(JRTContext.GetRequest(Request,"P6"), "");param.P7 = Helper.ValidParam(JRTContext.GetRequest(Request,"P7"), "");param.P8 = Helper.ValidParam(JRTContext.GetRequest(Request,"P8"), "");param.P9 = Helper.ValidParam(JRTContext.GetRequest(Request,"P9"), "");param.P10 = Helper.ValidParam(JRTContext.GetRequest(Request,"P10"), "");param.P11 = Helper.ValidParam(JRTContext.GetRequest(Request,"P11"), "");param.P12 = Helper.ValidParam(JRTContext.GetRequest(Request,"P12"), "");param.P13 = Helper.ValidParam(JRTContext.GetRequest(Request,"P13"), "");String strRet = "";int rowCount = 0;String logInfo = "^^^^";String json = Helper.GetVMData(ClassName, FuncName, param, null, null);List<DrawElement> elementList = JsonDealUtil.Json2List(json, DrawElement.class);JRTPrintDrawProtocol PrintHandeler = new JRTPrintDrawProtocol();int AllPageNum = PrintHandeler.JRTPrintDrawInit(elementList);for(int p=0;p<AllPageNum;p++){List<DrawElement> onePageData=PrintHandeler.GetOnePageData(p);float maxY = 0;for (int j = 0; j < onePageData.size(); j++){DrawElement curRow = onePageData.get(j);float PrintY = 0;if (!curRow.PrintY.isEmpty()){PrintY = Convert.ToFloat(curRow.PrintY);}if (maxY < PrintY){maxY = PrintY;}//图片元素if (curRow.PrintType.equals("Graph")){float PrintHeight = 0;if (!curRow.PrintHeight.isEmpty()){PrintHeight = Convert.ToFloat(curRow.PrintHeight);}if (maxY < PrintY+ PrintHeight){maxY = PrintY+ PrintHeight;}}//是外送文件if (curRow.PrintType.equals("FILE")){if (strRet.isEmpty()){strRet = curRow.DataField;}else{strRet = strRet + "~" + curRow.DataField;}}}//A4if (maxY > 583){Height = 1169;}BufferedImage img = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_ARGB);Graphics g = img.getGraphics();g.setColor(Color.WHITE);g.fillRect(0, 0, img.getWidth(), img.getHeight());PrintHandeler.DrawOnePage(g, p);if (strRet.isEmpty()){strRet = ImgToBase64(img);}else{strRet = strRet + "~" + ImgToBase64(img);;}}return strRet;}/*** 图片转Base64串* @param img* @return* @throws Exception*/private String ImgToBase64(BufferedImage img) throws Exception {ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(img, "png", baos);byte[] bytes = baos.toByteArray();String base64Image = Base64.getEncoder().encodeToString(bytes);return base64Image;}
}

在线预览界面实现

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>打印绘图预览</title><script type="text/javascript">var sysTheme = '';</script><script src="../../resource/common/js/JRTBSBase.js" type="text/javascript"></script><script language="javascript" type="text/javascript">SYSPageCommonInfo.Init(true);var BasePath = '';var ResourcePath = '';var WebServicAddress = SYSPageCommonInfo.Data.WebServicAddress;var SessionStr = SYSPageCommonInfo.Data.SessionStr;</script><script src="../../jrtprint/js/JRTPrint.js" type="text/javascript"></script><style type="text/css">.btnMini {z-index:9999;position:relative;right:10px;top:0px;}</style><script type="text/javascript">//得到传入的打印主参数var PrintDR = requestUrlParam(location.href, "PrintDR").replace("#", "");//打印类名var PrintClassName = requestUrlParam(location.href, "PrintClassName").replace("#", "");//仅仅浏览模式var OnlyView = requestUrlParam(location.href, "OnlyView").replace("#", "");var UserDR = requestUrlParam(location.href, "UserDR").replace("#", "");var Align = requestUrlParam(location.href, "Align").replace("#", "");//显示顶部按钮var ShowTopBtn = requestUrlParam(location.href, "ShowTopBtn").replace("#", "");var userCode = UserDR;//1:报告处理打印 2:自助打印 3:医生打印var paramList = "1";//所有页面数var AllPageNum = 1;var AllPageArr = null;var AllPageBllIDArr = null;$(function () {if (OnlyView == "1") {//批量预览if (PrintDR == "") {PrintDR = localStorage["OnlyViewPrintDR"];}$("#btnPrint").hide();$("#btnPDF").hide();$("#btnPrintMini").remove();$("#btnPDFMini").remove();}//不显示顶部按钮if (ShowTopBtn == "0") {$("#divOper").hide();}else {$(".btnMini").hide();}//没传打印类的默认类if (PrintClassName == null || PrintClassName == "") {PrintClassName = "vm.test.PrintBarCodeTest";}if (Align == "Left") {$("#divOper").css("margin", "0 0 0 0");$("#divMian").css("margin", "0 0 0 0");}//打印$("#btnPrint").click(function () {InvokePrint("1");});$("#btnPrintMini").click(function () {InvokePrint("1");});//导出PDF$("#btnPDF").click(function () {InvokePrint("3");});$("#btnPDFMini").click(function () {InvokePrint("3");});//页数回车$("#txtCurPage").keydown(function (event) {if (event.keyCode == "13") {var curPage = $("#txtCurPage").val();var curPage = parseInt(curPage);if (curPage < 1) {curPage = 1;}if (curPage > AllPageNum) {curPage = AllPageNum;}ShowOnePage(curPage);}});//快捷键$(window).keydown(function (e) {if (e.key == "PageUp" || e.key == "ArrowUp") {PrePage();}else if (e.key == "ArrowLeft") {PrePage();}else if (e.key == "PageDown" || e.key == "ArrowDown") {NextPage();}else if (e.key == "ArrowRight") {NextPage();}else if (e.key == "F6") {UnCheckParent();}});//前一页$("#btnPrePage").click(function () {PrePage();});$("#btnPrePageMini").click(function () {PrePage();});//前一页function PrePage() {var curPage = $("#txtCurPage").val();var curPage = parseInt(curPage);curPage = curPage - 1;if (curPage < 1) {curPage = 1;}$("#txtCurPage").val(curPage);ShowOnePage(curPage);}//后一页$("#btnNextPage").click(function () {NextPage();});$("#btnNextPageMini").click(function () {NextPage();});//下一页function NextPage() {var curPage = $("#txtCurPage").val();var curPage = parseInt(curPage);curPage = curPage + 1;if (curPage > AllPageNum) {curPage = AllPageNum;}$("#txtCurPage").val(curPage);ShowOnePage(curPage);}//显示一页function ShowOnePage(curPage) {var imgStr = '';if ((AllPageArr[curPage - 1].toLowerCase().indexOf("../../") > -1) || (AllPageArr[curPage - 1].toLowerCase().indexOf("ftp://") > -1) || (AllPageArr[curPage - 1].toLowerCase().indexOf("http://") > -1) || (AllPageArr[curPage - 1].toLowerCase().indexOf("https://") > -1)) {if (curPage > 0) {imgStr += '<div style="font-weight:bold;color:#ff5252;">第' + curPage + '页</div><iframe src="' + DealPdfViewUrl(AllPageArr[curPage - 1]) + '"  style="margin-bottom:10px;width:827px;height:1189px;"/>';}else {imgStr += '<iframe src="' + DealPdfViewUrl(AllPageArr[curPage - 1]) + '"  style="margin-bottom:10px;width:827px;height:1189px;"/>';}}else {if (curPage > 0) {imgStr += '<div style="font-weight:bold;color:#ff5252;">第' + curPage + '页</div><img src="' + "data:image/png;base64," + AllPageArr[curPage - 1] + '" alt="报告" style="margin-bottom:10px;"/>';}else {imgStr += '<img src="' + "data:image/png;base64," + AllPageArr[curPage - 1] + '" alt="报告" style="margin-bottom:10px;"/>';}}$("#divMian").html(imgStr);}//校验参数if (PrintDR == "") {$("#spPage").html("没按要求传入PrintDR!");return;}//请求打印$.ajax({type: "get",dataType: "text", //text, json, xmlcache: false, //async: true, //为true时,异步,不等待后台返回值,为false时强制等待;-asirurl: '../ashx/ashJRTPrintDrawView.ashx?Method=QryPrintDrawImgs',data: { ClassName: PrintClassName, FuncName: "GetData", Width: 827, Height: 583, P0: PrintDR, P1: userCode, P2: paramList, RetBll: "1" },success: function (data) {AllPageArr = data.split("~");var imgStr = '';AllPageBllIDArr = [];for (var i = 0; i < AllPageArr.length; i++) {var onePage = AllPageArr[i];var onePageArr = onePage.split('^');var oneBll = "";if (onePageArr.length > 1) {oneBll = onePageArr[1];}AllPageBllIDArr.push(oneBll);AllPageArr[i] = onePageArr[0];}AllPageNum = AllPageArr.length;for (var i = 0; i < AllPageArr.length; i++) {if ((AllPageArr[i].toLowerCase().indexOf("../../") > -1) || (AllPageArr[i].toLowerCase().indexOf("ftp://") > -1) || (AllPageArr[i].toLowerCase().indexOf("http://") > -1) || (AllPageArr[i].toLowerCase().indexOf("https://") > -1)) {if (i > 0) {imgStr += '<div style="font-weight:bold;color:#ff5252;">第' + (i + 1) + '页</div><iframe src="' + DealPdfViewUrl(AllPageArr[i]) + '"  style="margin-bottom:10px;width:827px;height:1189px;"/>';}else {imgStr += '<iframe src="' + DealPdfViewUrl(AllPageArr[i]) + '"  style="margin-bottom:10px;width:827px;height:1189px;"/>';}}else {if (i > 0) {imgStr += '<div style="font-weight:bold;color:#ff5252;">第' + (i + 1) + '页</div><img src="' + "data:image/png;base64," + AllPageArr[i] + '" alt="报告" style="margin-bottom:10px;"/>';}else {imgStr += '<img src="' + "data:image/png;base64," + AllPageArr[i] + '" alt="报告" style="margin-bottom:10px;"/>';}}}$("#spPage").html("当前报告共(" + AllPageArr.length + ")页");$("#divMian").html(imgStr);}});$("#txtCurPage").focus();});//打印function InvokePrint(type) {//0:打印所有报告 1:循环打印每一份报告var printFlag = "0";var rowids = PrintDR;//打印用户 var userCode = UserDR;//PrintOut:打印  PrintPreview打印预览  PDF#地址  【0用户选  -1桌面  具体地址】//1:报告处理打印 2:自助打印 3:医生打印var paramList = "LIS";if (type == null || type == "1") {//PrintOut:打印  PrintPreview打印预览var printType = "PrintOut";}else if (type == "2") {//PrintOut:打印  PrintPreview打印预览var printType = "PrintPreview";}else if (type == "3") {//打印预览printType = "PDF#0";}var Param = printFlag + "@" + WebServicAddress + "@" + rowids + "@" + userCode + "@" + printType + "@" + paramList + "@" + PrintClassName + "@GetData";JRTBasePrint(Param);}</script>
</head>
<body><div id="divOper" style="margin: auto auto; width: 850px; background-color: #F5F5F5; text-align: center; padding-top: 5px; padding-bottom: 5px;"><a id="btnPrint" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left: 10px;">打印</a>&nbsp&nbsp<a id="btnPDF" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-export',plain:true">导出PDF</a>&nbsp&nbsp<a id="btnPrePage" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-arrow-left',plain:true" title="PgLeft">上一页</a>&nbsp&nbsp<a id="btnNextPage" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-arrow-right',plain:true" title="PgRight">下一页</a>&nbsp&nbsp<input id="txtCurPage" type="text" style="width: 40px;" class="easyui-validatebox" value="1" />&nbsp&nbsp<span id="spPage" style="font-weight: bold; color: #ff793e; font-size: 14px;"></span><span style="font-weight: bold; color: #AAAAAA; font-size: 14px; float: right; margin-right: 10px;">JRT在线浏览</span></div><div style="margin: auto auto; width: 850px;text-align:center;"><div class="btnMini"><a id="btnPrintMini" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-print',plain:true" title="打印"></a><span class="jrtsp6>"></span><a id="btnPDFMini" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-export',plain:true" title="导出PDF"></a><span class="jrtsp6>"></span><a id="btnPrePageMini" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-arrow-left',plain:true" title="上一页[PgLeft]"></a><span class="jrtsp6>"></span><a id="btnNextPageMini" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-arrow-right',plain:true" title="下一页[PgRight]"></a><span class="jrtsp6>"></span></div><div id="divMian" style="margin: auto auto; width: 850px; background-color: #DDDDDD; text-align: center; padding-top: 10px;"></div></div></body>
</html>

其他页面使用
在这里插入图片描述

这样就可以实现在线预览功能,客户端不用环境也能进行打印预览,包括一些业务场景可以让用户看到图的效果,提高体验,也方便外部系统看一些报告和各种单据,只需要推送URL即可

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

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

相关文章

JS代码输出题:return Promise.resolve() 情况

题目&#xff1a; Promise.resolve().then(() > {console.log(0);return Promise.resolve(4);}).then((res) > {console.log(res)})Promise.resolve().then(() > {console.log(1)}).then(() > {console.log(2)}).then(() > {console.log(3)}).then(() > {con…

MDK编译过程和文件类型

MDK是一款IDE软件&#xff0c;具有&#xff0c;编辑&#xff0c;编译&#xff0c;链接&#xff0c;下载&#xff0c;调试等等的功能。 1.编译器介绍&#xff1a; MDK可以编译C/C文件和汇编文件&#xff0c;MDK只是一款IDE软件&#xff0c;那他内部使用的是什么编译器呢&#x…

Python-折线图可视化

折线图可视化 1.JSON数据格式2.pyecharts模块介绍3.pyecharts快速入门4.创建折线图 1.JSON数据格式 1.1什么是JSON JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据JSON本质上是一个带有特定格式的字符串 1.2主要功能json就是一种在各个编程语言中流…

JavaSE第7篇:封装

文章目录 一、封装1、好处:2、使用 二、四种权限修饰符三、构造器1、作用2、说明3、属性赋值的过程 一、封装 封装就是将类的属性私有化,提供公有的方法访问私有属性 不对外暴露打的私有的方法 单例模式 1、好处: 1.只能通过规定的方法来访问数据 2.隐藏类的实例细节,方便…

CSS篇之圆角梯形

附上一篇文章&#xff1a;梯形tab按钮-基于clip-path path函数实现 - JSRUN.NET 他这个区别在于&#xff0c;收尾两侧都是直角的&#xff0c;如图 下面这个是圆角&#xff1a; 思路&#xff1a; 代码如下&#xff1a; <template><div class"wrap"><…

时序数据库选型TimescaleDB

最近要做一个数字车间的物联网项目&#xff0c;数据存储成了首先要解决的问题&#xff0c;整个车间一共104台数控机床&#xff0c;1s钟采集1次数据&#xff0c;360024365*1043,279,744,000 &#xff0c;一年要产生32亿条记录&#xff0c;这个数据量用常见的关系型数据库肯定是不…

【C语言加油站】qsort函数的模拟实现

qsort函数的模拟实现 导言一、回调函数二、冒泡排序2.1 冒泡排序实现升序 三、qsort函数3.1 qsort函数的使用3.2 比较函数 四、通过冒泡排序模拟实现qsort函数4.1 任务需求4.2 函数参数4.3 函数定义与声明4.4 函数实现4.4.1 函数主体4.4.2 比较函数4.4.3 元素交换 4.5 my_qsort…

Mrdoc知识文档

MrDoc知识文档平台是一款基于Python开发的在线文档系统&#xff0c;适合作为个人和中小型团队的私有云文档、云笔记和知识管理工具&#xff0c;致力于成为优秀的私有化在线文档部署方案。我现在主要把markdown笔记放在上面&#xff0c;因为平时老是需要查询一些知识点&#xff…

mysql使用st_distance_sphere函数报错Incorrect arguments to st_distance_sphere

前言 最近使用空间点位查询数据时函数报错Incorrect arguments to st_distance_sphere报错。 发现问题 因为之前是没有问题的&#xff0c;所以把问题指向了数据&#xff0c;因为是外部数据&#xff0c;不是通过系统打点获取&#xff0c;发现是因为经纬度反了&#xff0c;loc…

软件测试指南

软件测试指南 软件集成测试软件系统测试&#xff08;功能性测试&#xff0c;性能测试&#xff09;

事件监听的艺术:掌握`addEventListener`的魅力

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【Vulnhub 靶场】【IA: Keyring (1.0.1)】【中等】【20210730】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/ia-keyring-101,718/ 靶场下载&#xff1a;https://download.vulnhub.com/ia/keyring-v1.01.ova 靶场难度&#xff1a;中等 发布日期&#xff1a;2021年07月30日 文件大小&#xff1a;1.1 GB 靶场作者&#xf…

基于Mamdani模糊神经网络的调速控制系统simulink建模与仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 模糊神经网络控制器概述 4.2 模糊神经网络控制器基本原理 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................…

UE5 项目设置

1、定义设置哪些参数 UCLASS(configEngine, globaluserconfig) class ADVMOD_API UGlobalSettings : public UObject {GENERATED_BODY()public:UGlobalSettings();const FString& GetPythonExePath() const { return PythonExePath.FilePath; }private:UPROPERTY(config, E…

【SpringBoot零基础入门到项目实战①】解锁现代Java开发之门:深度探究Spring Boot的背景、目标及选择理由

文章目录 引言Spring Boot的背景和目标背景目标 为什么选择Spring Boot1. 简化配置2. 内嵌式容器3. 生态系统支持4. 大量的Starter5. 广泛的社区支持6. 适用于微服务架构7. 丰富的扩展机制 实例演示创建一个简单的Spring Boot应用 拓展与深入学习1. Spring Boot Actuator2. Spr…

力扣刷题-二叉树-路径总和

112 路径总和 给定一个二叉树和一个目标和&#xff0c;判断该树中是否存在根节点到叶子节点的路径&#xff0c;这条路径上所有节点值相加等于目标和。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树&#xff0c;以及目标和 sum 22&#xff0c; 返回 true, 因为…

记录 | Visual Studio报错:const char*类型的值不能用于初始化char*类型

Visual Studio 报错&#xff1a; const char *”类型的值不能用于初始化“char *”类型的实体错误 解决办法&#xff1a; 1&#xff0c;强制类型转换&#xff0c;例如&#xff1a; char * Singer::pv[] {(char*)"other", (char*)"alto", (char*)"c…

1848_emacs_org-mode代码块环境

Grey 全部学习内容汇总&#xff1a; https://github.com/greyzhang/g_org 1848_emacs_org-mode代码块环境 这一部分主要是涉及到一些代码的执行、引用以及输出处理等功能。从之前我看的资料来说&#xff0c;更加偏重于可重现研究但不一定是文学式编程的必要部分。 内容来源…

git 上传大文件操作 lfs 的使用

我们要先去下载 下载后安装 我最后还是下载到了D:\git\Git\bin这个目录下 如何检查是否下载成功呢&#xff0c;用 git lfs install 在命令行运行就可以查看 下面怎么上传文件呢 首先我们还是要初始化文件的 git init 下一步输入命令 git lfs install 下一步 git lfs tra…

【小程序】-【

swiper、swiper-item轮播图 swiper是滑块视图容器。其中只可放置swiper-item组件。部分常用属性如下&#xff0c;其余属性详见&#xff1a;官方文档 <view class"banner"><swiperprevious-margin"30rpx"circularautoplayinterval"3000&q…