当前位置: 首页 > news >正文

电子签章Java后端与前端交互签名位置计算

电子签章过程中存在着在网页上对签署文件进行预览、指定签署位置、文件签署等操作,由于图片在浏览器上的兼容性和友好性优于PDF文件,所以一般在网页上进行电子签章时,会先将PDF文件转换成图片,展示给用户。用户在页面上确定好签署位置,并进行签署时,后端服务会通过对电子印章/手写签名位置、大小以及PDF文件的大小进行计算,在PDF文件的准确位置上完成文件签署。以下代码是Java后端与前端交互签名位置计算的源代码,希望对大家有帮助。

更多电子签章前后端交互体验,可访问开源网站获取电子签章/电子合同工具源码:

https://gitee.com/kaifangqian

https://github.com/kaifangqian

关联工具包:itext-pdf;

1、计算签署配置业务类;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfReader;
import com.resrun.service.pojo.RealPositionProperty;
import com.resrun.service.pojo.SelectKeywords;
import com.resrun.service.pojo.SourcePositionProperty;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** @Description: 计算签署位置业务* @Package: com.resrun.service.pdf* @ClassName: CalculatePositionService* @copyright 北京资源律动科技有限公司*/
@Service
public class CalculatePositionService {/*** @Description #批量计算真实签署位置* @Param [sourcePositionProperties]* @return java.util.List<com.resrun.modules.sign.service.tool.pojo.RealPositionProperty>**/public List<RealPositionProperty> calculatePositions(List<SourcePositionProperty> sourcePositionProperties, byte[] pdfFileByte){List<RealPositionProperty> realPositionProperties = new ArrayList<>();PdfReader reader = null ;try {//将pdf文件读入PdfReader工具类reader = new PdfReader(pdfFileByte);for(SourcePositionProperty sourcePositionProperty : sourcePositionProperties){RealPositionProperty realPositionProperty = calculatePosition(sourcePositionProperty,pdfFileByte);Document document = new Document(reader.getPageSize(sourcePositionProperty.getPage()));//获取真实pdf文件指定页的真实文档宽高float realPdfHeight = document.getPageSize().getHeight();float realPdfWidth = document.getPageSize().getWidth();//获取页面上文档的宽高float sourcePageWidth = sourcePositionProperty.getPageWidth();float sourcePageHeight = sourcePositionProperty.getPageHeight();//计算真实文档的宽高和页面文档的宽高的比率float rateHeight = realPdfHeight / sourcePageHeight;float rateWidth = realPdfWidth / sourcePageWidth;//计算页面上的横纵坐标,由于页面上给出的是左上角的坐标,所以需要再转换计算一下//左下角float pageStartX = sourcePositionProperty.getOffsetX();float pageStartY = sourcePositionProperty.getOffsetY() + sourcePositionProperty.getHeight() ;//右上角float pageEndX = sourcePositionProperty.getOffsetX() + sourcePositionProperty.getWidth();float pageEndY = sourcePositionProperty.getOffsetY();//根据比率去计算真实文档上的坐标位置float startX = pageStartX * rateWidth ;float startY = pageStartY * rateHeight;float endX = pageEndX * rateWidth ;float endY = pageEndY * rateHeight ;//由于页面的纵坐标和pdf的纵坐标是相反的,所以真实的pdf的纵坐标在计算的时候需要再反转一下startY = realPdfHeight - startY ;endY = realPdfHeight - endY ;//封装返回数据realPositionProperty.setStartx(startX);realPositionProperty.setStarty(startY);realPositionProperty.setEndx(endX);realPositionProperty.setEndy(endY);realPositionProperty.setPageNum(sourcePositionProperty.getPage());document.close();realPositionProperties.add(realPositionProperty);}reader.close();} catch (Exception e) {e.printStackTrace();}return realPositionProperties ;}/*** @Description #单独计算真实签署位置* @Param [sourcePositionProperty]* @return com.resrun.modules.sign.service.tool.pojo.RealPositionProperty**/public RealPositionProperty calculatePosition(SourcePositionProperty sourcePositionProperty, byte[] pdfFileByte){RealPositionProperty realPositionProperty = new RealPositionProperty();PdfReader reader = null ;Document document = null ;try {//将pdf文件读入PdfReader工具类reader = new PdfReader(pdfFileByte);document = new Document(reader.getPageSize(sourcePositionProperty.getPage()));//获取真实pdf文件指定页的真实文档宽高float realPdfHeight = document.getPageSize().getHeight();float realPdfWidth = document.getPageSize().getWidth();//获取页面上文档的宽高float sourcePageWidth = sourcePositionProperty.getPageWidth();float sourcePageHeight = sourcePositionProperty.getPageHeight();//计算真实文档的宽高和页面文档的宽高的比率float rateHeight = realPdfHeight / sourcePageHeight;float rateWidth = realPdfWidth / sourcePageWidth;//计算页面上的横纵坐标,由于页面上给出的是左上角的坐标,所以需要再转换计算一下//左下角float pageStartX = sourcePositionProperty.getOffsetX();float pageStartY = sourcePositionProperty.getOffsetY() + sourcePositionProperty.getHeight() ;//右上角float pageEndX = sourcePositionProperty.getOffsetX() + sourcePositionProperty.getWidth();float pageEndY = sourcePositionProperty.getOffsetY();//根据比率去计算真实文档上的坐标位置float startX = pageStartX * rateWidth ;float startY = pageStartY * rateHeight;float endX = pageEndX * rateWidth ;float endY = pageEndY * rateHeight ;//由于页面的纵坐标和pdf的纵坐标是相反的,所以真实的pdf的纵坐标在计算的时候需要再反转一下startY = realPdfHeight - startY ;endY = realPdfHeight - endY ;//封装返回数据realPositionProperty.setStartx(startX);realPositionProperty.setStarty(startY);realPositionProperty.setEndx(endX);realPositionProperty.setEndy(endY);realPositionProperty.setPageNum(sourcePositionProperty.getPage());document.close();reader.close();} catch (Exception e) {e.printStackTrace();}return realPositionProperty ;}public RealPositionProperty calculatePosition(SourcePositionProperty sourcePositionProperty){RealPositionProperty realPositionProperty = new RealPositionProperty();//获取真实pdf文件指定页的真实文档宽高float realPdfHeight = sourcePositionProperty.getRealHeight();float realPdfWidth = sourcePositionProperty.getRealWidth();//获取页面上文档的宽高float sourcePageWidth = sourcePositionProperty.getPageWidth();float sourcePageHeight = sourcePositionProperty.getPageHeight();//计算真实文档的宽高和页面文档的宽高的比率float rateHeight = realPdfHeight / sourcePageHeight;float rateWidth = realPdfWidth / sourcePageWidth;//计算页面上的横纵坐标,由于页面上给出的是左上角的坐标,所以需要再转换计算一下//左下角float pageStartX = sourcePositionProperty.getOffsetX();float pageStartY = sourcePositionProperty.getOffsetY() + sourcePositionProperty.getHeight() ;//右上角float pageEndX = sourcePositionProperty.getOffsetX() + sourcePositionProperty.getWidth();float pageEndY = sourcePositionProperty.getOffsetY();//根据比率去计算真实文档上的坐标位置float startX = pageStartX * rateWidth ;float startY = pageStartY * rateHeight;float endX = pageEndX * rateWidth ;float endY = pageEndY * rateHeight ;//由于页面的纵坐标和pdf的纵坐标是相反的,所以真实的pdf的纵坐标在计算的时候需要再反转一下startY = realPdfHeight - startY ;endY = realPdfHeight - endY ;//封装返回数据realPositionProperty.setStartx(startX);realPositionProperty.setStarty(startY);realPositionProperty.setEndx(endX);realPositionProperty.setEndy(endY);realPositionProperty.setPageNum(sourcePositionProperty.getPage());return realPositionProperty ;}/*** 通过查询关键字来获得签名位置信息* @param pdfFile 签署源文件* @param keyWords 关键字* @param width 签章宽度* @param height 签章高度* @return 签署位置信息* @throws IOException*/public RealPositionProperty getPositionByKeyWords(byte[] pdfFile, String keyWords, int width, int height) {RealPositionProperty positionProperty = new RealPositionProperty();//调用通过关键字查询位置的方法float[] result = new float[0];try {result = new SelectKeywords().selectKeyword(pdfFile,keyWords);} catch (Exception e) {e.printStackTrace();}if(result !=null){positionProperty.setStartx(result[0]);positionProperty.setStarty(result[1]+height/4);positionProperty.setPageNum((int)result[2]);positionProperty.setEndx(result[0]+width/2);positionProperty.setEndy(result[1]-height/4);}return positionProperty;}/*** 通过查询关键字来获得签名位置信息<br/>** 同一个关键字出现在多处会一次性全部找出** @param pdfFile 签署源文件* @param keyWords 关键字* @param width 签章宽度* @param height 签章高度* @return 签署位置信息* @throws IOException*/public List<RealPositionProperty> getAllPositionByKeyWords(byte[] pdfFile,String keyWords,int width,int height) {List<RealPositionProperty> positions = new ArrayList<RealPositionProperty>();//调用通过关键字查询位置的方法List<float[]> results = null;try {results = new SelectKeywords().selectAllKeyword(pdfFile, keyWords);} catch (Exception e) {e.printStackTrace();}if(results !=null && results.size()>0){for (float[] result : results) {RealPositionProperty positionProperty = new RealPositionProperty();positionProperty.setStartx(result[0]);positionProperty.setStarty(result[1]+height/4);positionProperty.setPageNum((int)result[2]);positionProperty.setEndx(result[0]+width/2);positionProperty.setEndy(result[1]-height/4);positions.add(positionProperty);}}return positions;}}

2、计算后的签名位置信息类;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;/*** @Description: 经过计算后的文件签署位置属性类* @Package: com.resrun.service.pojo* @ClassName: PositionProperty* @copyright 北京资源律动科技有限公司*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class RealPositionProperty implements Serializable {private static final long serialVersionUID = 8586984409612483553L;/** 签章左下角x坐标 */private  float startx;/** 签章左下角y坐标*/private  float starty;/** 签章右上角x坐标*/private  float endx;/** 签章右上角x坐标*/private  float endy;private  int pageNum;// 填写值,填写专用private String value ;//对齐方式private String align ;//字体private String fontFamily ;//文字大小private Integer fontSize ;
}

3、关键字位置计算类;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;/*** @Description: 关键字计算位置* @Package: com.resrun.service.pojo* @ClassName: SelectKeywords* @copyright 北京资源律动科技有限公司*/
public class SelectKeywords extends PDFTextStripper {private static ThreadLocal<KeyWorkPair> keyWorkPair = new ThreadLocal<KeyWorkPair>();private Log logger = LogFactory.getLog(SelectKeywords.class);public SelectKeywords() throws IOException {super.setSortByPosition(true);}//    public static void main(String[] args) throws Exception {
//        //selectKeyword
//        File file = new File("e:/test/948ad938bab14f4e8a2d843f6dd81d57.pdf");
//        float [] resus = new SelectKeywords().selectKeyword(IOUtils.toByteArray(file), "948ad938bab14f4e8a2d843f6dd81d57");//66   571
//        System.out.println(resus[0]+"--"+resus[1]+"---"+resus[2]);
//    }/*** 查出PDF里所有的关键字* @param pdfFile* @param KEY_WORD* @return*/public List<float[]> selectAllKeyword(byte [] pdfFile, String KEY_WORD) {keyWorkPair.set(new KeyWorkPair(KEY_WORD.split(",")));ByteArrayInputStream in = null;PDDocument document = null;try {in = new ByteArrayInputStream(pdfFile);document = PDDocument.load(in);//加载pdf文件this.getText(document);List<float[]> allResu = getAllResult();return allResu;} catch (Exception e) {e.printStackTrace();}finally{try {if(in!=null) in.close();if(document!=null) document.close();} catch (IOException e) {}}return null;}private List<float[]> getAllResult(){KeyWorkPair pair = keyWorkPair.get();if(pair!=null && pair.getResu()!=null){keyWorkPair.set(null);return pair.getAllResu();}else{keyWorkPair.set(null);return null;}}/*** 查出PDF里最后一个关键字* @param pdfFile* @param KEY_WORD* @return*/public float [] selectKeyword(byte [] pdfFile,String KEY_WORD) {keyWorkPair.set(new KeyWorkPair(KEY_WORD.split(",")));ByteArrayInputStream in = null;PDDocument document = null;try {in = new ByteArrayInputStream(pdfFile);document = PDDocument.load(in);//加载pdf文件this.getText(document);float[] resu = getResult();return resu;} catch (Exception e) {e.printStackTrace();}finally{try {if(in!=null) in.close();if(document!=null) document.close();} catch (IOException e) {}}return null;}private float[] getResult(){KeyWorkPair pair = keyWorkPair.get();if(pair!=null && pair.getResu()!=null){keyWorkPair.set(null);return pair.getResu();}else{keyWorkPair.set(null);return null;}}@Overrideprotected void writeString(String string, List<TextPosition> textPositions) throws IOException {for (TextPosition text : textPositions) {String tChar = text.toString();char c = tChar.charAt(0);String REGEX = "[,.\\[\\](:;!?)/]";lineMatch = matchCharLine(text);if ((!tChar.matches(REGEX)) && (!Character.isWhitespace(c))) {if ((!is1stChar) && (lineMatch == true)) {appendChar(tChar);} else if (is1stChar == true) {setWordCoord(text, tChar);}} else {endWord();}}endWord();}protected void appendChar(String tChar) {tWord.append(tChar);is1stChar = false;}/**** %拼接字符串%。*/protected void setWordCoord(TextPosition text, String tChar) {itext = text;tWord.append("(").append(pageNo).append(")[").append(roundVal(Float.valueOf(text.getXDirAdj()))).append(" : ").append(roundVal(Float.valueOf(text.getYDirAdj()))).append("] ").append(tChar);is1stChar = false;}protected boolean matchCharLine(TextPosition text) {Double yVal = roundVal(Float.valueOf(text.getYDirAdj()));if (yVal.doubleValue() == lastYVal) {return true;}lastYVal = yVal.doubleValue();endWord();return false;}protected Double roundVal(Float yVal) {DecimalFormat rounded = new DecimalFormat("0.0'0'");Double yValDub = new Double(rounded.format(yVal));return yValDub;}protected void endWord() {// String newWord = tWord.toString().replaceAll("[^\\x00-\\x7F]",// "");//为了检索速度 使用正则去掉中文String newWord = tWord.toString();// 去掉正则 可以检索中文KeyWorkPair pair = keyWorkPair.get();try {String[] seekA = pair.getSeekA();float[] resu = new float[3];String sWord = newWord.substring(newWord.lastIndexOf(' ') + 1);if (!"".equals(sWord)) {if (sWord.contains(seekA[0])) {resu[2] = getCurrentPageNo();// (595,842)resu[0] = (float) (roundVal(Float.valueOf(itext.getXDirAdj())) + 0.0F);resu[1] = 842.0F - (float) (roundVal(Float.valueOf(itext.getYDirAdj())) + 0.0F);logger.info("PDF关键字信息:[页数:" + resu[2] + "][X:" + resu[0] + "][Y:" + resu[1] + "]");pair.setResu(resu);pair.addResuList(resu);//把每一次找出的关键字放在一个集合里keyWorkPair.set(pair);}}} catch (Exception e) {e.printStackTrace();keyWorkPair.set(null);throw new RuntimeException();}tWord.delete(0, tWord.length());is1stChar = true;}private StringBuilder tWord = new StringBuilder();private boolean is1stChar = true;private boolean lineMatch;private int pageNo = 0;private double lastYVal;private TextPosition itext;/*** 关键字和返回的位置信息类*/class KeyWorkPair {public KeyWorkPair(String[] seekA) {super();this.seekA = seekA;}public KeyWorkPair(String[] seekA, float[] resu) {super();this.seekA = seekA;this.resu = resu;}public KeyWorkPair() {super();}public String[] getSeekA() {return seekA;}public void setSeekA(String[] seekA) {this.seekA = seekA;}public float[] getResu() {return resu;}public void setResu(float[] resu) {this.resu = resu;}public void addResuList(float[] resu) {resuAll.add(resu);}public List<float[]> getAllResu() {return resuAll;}private String[] seekA;private float[] resu;//所有的位置private List<float[]> resuAll = new ArrayList<>();}
}

4、原始文件签署位置信息类;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;/*** @Description: 原始文件签署位置属性* @Package: com.resrun.service.pojo* @ClassName: SourcePositionProperty* @copyright 北京资源律动科技有限公司*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SourcePositionProperty implements Serializable {private static final long serialVersionUID = 725976764583634367L;@ApiModelProperty("控件X坐标(左上角)")private Float offsetX ;@ApiModelProperty("控件Y坐标(左上角)")private Float offsetY ;@ApiModelProperty("控件宽度")private Float width ;@ApiModelProperty("控件高度")private Float height ;@ApiModelProperty("当前文件页面宽度")private Float pageWidth ;@ApiModelProperty("当前文件页面高度")private Float pageHeight ;@ApiModelProperty("控件所属页码")private Integer page ;@ApiModelProperty("当前文件页面宽度")private Float realWidth ;@ApiModelProperty("当前文件页面高度")private Float realHeight ;}

相关文章:

电子签章Java后端与前端交互签名位置计算

电子签章过程中存在着在网页上对签署文件进行预览、指定签署位置、文件签署等操作&#xff0c;由于图片在浏览器上的兼容性和友好性优于PDF文件&#xff0c;所以一般在网页上进行电子签章时&#xff0c;会先将PDF文件转换成图片&#xff0c;展示给用户。用户在页面上确定好签署…...

为什么选择嬴图?

图数据库、图计算、图中台都是用图论的方式去构造实体间的关联关系&#xff0c;实体用顶点来表达&#xff0c;而实体间的关系用边来表达。图数据库的这种简洁、自由、高维但100%还原世界的数据建模的方式让实体间的关联关系的计算比SQL类的数据库高效成千上万倍。 图&#xff1…...

Python学习之路-编码风格

Python学习之路-编码风格 设计哲学 Python的设计哲学是“优雅”、“明确”、“简单”。它的重要准则被称为“Python之禅”。Python之禅又名PEP 20&#xff0c;在Python解释器内运行import this可以获得完整的列表&#xff0c;下面是我的翻译与解读&#xff1a; 提姆彼得斯&a…...

权威认可!甄知科技猪齿鱼产品荣获信创产品评估证书

近日&#xff0c;依据《信息技术应用创新产品评估规范 第1部分&#xff1a;应用软件》&#xff08;T/SSIA 2001-2022&#xff09;&#xff0c;经过严格评估&#xff0c;甄知科技旗下自主研发的猪齿鱼数智化开发管理平台 V2.0.0&#xff0c;通过信创测试认证&#xff0c;获得上海…...

9. 回文数(Java)

题目描述&#xff1a; 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 …...

Python(30):非对称加密算法RSA的使用(openssl生成RSA公私钥对)

Python(30)&#xff1a;非对称加密算法RSA的使用(openssl生成RSA公私钥对) 1、openssl生成RSA公私钥对 1.1、生成RSA公私钥对命令 [rootloaclhost ~]# openssl OpenSSL> genrsa -out rsa_private_key.pem 1024 Generating RSA private key, 1024 bit long modulus .. ...…...

Java学习笔记-day04-NIO核心依赖多路复用小记

NIO允许一个线程同时处理多个连接&#xff0c;而不会因为一个连接的阻塞而导致其他连接被阻塞。核心是依赖操作系统的多路复用机制。 操作系统的多路复用机制 多路复用是一种操作系统的 I/O 处理机制&#xff0c;允许单个进程&#xff08;或线程&#xff09;同时监视多个输入…...

Java+springboot+vue智慧校园源码,数据云平台Web端+小程序教师端+小程序家长端

技术架构&#xff1a; Javaspringbootvue element-ui小程序电子班牌&#xff1a;Java Android演示自主版权。 智慧校园电子班牌人脸识别系统全套源码&#xff0c;包含&#xff1a;数据云平台Web端小程序教师端小程序家长端电子班牌 学生端。 电子班牌系统又称之为智慧班牌&am…...

算法日志的存在核心在于搭建自检系统

"相信每一个人执行与日志有关的任务都会遇到这样难题吧&#xff1f;长达几万行的日志&#xff0c;如果我们单纯用肉眼去一个个排查&#xff0c;那么恐怕所耗费的时间是以天为计量单位了。当然这是一种比较夸张的情况&#xff0c;根据我的项目经验&#xff0c;正常情况是十…...

【2023开发组一等奖】定位家乡味——北京市老乡探店寻味系统

作品介绍 1 需求分析 中国人的身上都系着两根线,一条线牵引着我们去远方,一条线牵引着我们归故乡。在当今社会,我们因为各种各样的原因背起行囊远离故乡去往千里之外的远方,而那暗涌在血脉的乡愁总会使我们在看到家乡菜的时候,心底溢出一种不可言说的温暖。那么,当你在异…...

37-数据类型,一元运算符typeof,字符串string,布尔Boolean,未定义undefined,空null,数组Array

<body><script>// 0.1加0.2不等于0.3&#xff0c;正确的运算方法如下console.log(0.10.2);var x 0.1;var y 0.2;console.log((x*10y*10)/10);</script> </body> 简单数据类型&#xff08;5种&#xff09;&#xff1a;数字number&#xff0c;字符串s…...

zabbix部署

zabbix部署 部署zabbix服务被监测主机部署zabbix-agent2 使用版本 组件版本centos7.9zabbix5.0php7.2.24MariaDB5.5.68 部署zabbix服务 关闭防火墙和selinux [rootnode ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemonLoaded: …...

深入理解Java源码:提升技术功底,深度掌握技术框架,快速定位线上问题

为什么要看源码&#xff1a; 1、提升技术功底&#xff1a; 学习源码里的优秀设计思想&#xff0c;比如一些疑难问题的解决思路&#xff0c;还有一些优秀的设计模式&#xff0c;整体提升自己的技术功底 2、深度掌握技术框架&#xff1a; 源码看多了&#xff0c;对于一个新技术…...

寒假前端第一次作业

1、用户注册&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用户注册</title> …...

【LabVIEW FPGA入门】创建第一个LabVIEW FPGA程序

本教程仅以compactRIO&#xff08;FPGA-RT&#xff09;举例 1.系统配置 1.1软件安装 FPGA-RT 1. LabVIEW Development System (Full or Professional) 2. LabVIEW Real-Time Module 3. LabVIEW FPGA Module 4. NI-RIO drivers 1.2硬件配置 1.使用线缆连接CompactRIO至主机…...

【STM32】STM32学习笔记-USART串口数据包(28)

00. 目录 文章目录 00. 目录01. 串口简介02. HEX数据包03. 文本数据包04. HEX数据包接收05. 文本数据包接收06. 预留07. 附录 01. 串口简介 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式&#xff0c;因为它简单便捷&#xff0c;因此大部分电子设备都支持…...

Java网络爬虫--HttpClient

目录标题 技术介绍有什么优点&#xff1f;怎么在项目中引入&#xff1f; 请求URLEntityUtils 类GET请求带参数的GET请求POST请求 总结 技术介绍 HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、功能丰富的、支持 HTTP 协议的客户端编程工具包。相…...

若依项目的table列表中对每一个字段增加排序按钮(单体版和前后端分离版)

一、目标:每一个字段都添加上下箭头用来排序 只需要更改前端代码,不需要更改后端代码,后面会讲解原理 二、单体版实现方式: 1.在options中添加sortable:true 2.在需要排序的字段中添加sortable:true 三、前后端分离版 1.el-table上添加@sort-change=“handleSortChange”…...

Linux自动化部署脚本

1:最近项目部署比较频繁终于熬不住了 就有下面的这东西 #!/bin/sh #报错停止运行 set -e # 获取tomcat的PID TOMCAT_PID$(ps -ef | grep tomcat | grep -v grep | awk {print $2}) # tomcat的启动文件位置 START_TOMCAT/mnt/tomcat/bin/startup.sh # 项目文件部署位置 PROJECT…...

lvgl修改图片大小上限

在lvgl中读取图片文件时&#xff0c;被读取的图片具有上限&#xff0c;也就是2048像素。这会造成两个非预期的结果&#xff1a; 超过2048像素的部分会被裁去。表示图片的结构体lv_img_t中的w和h变量值是图片像素被2048求余。例如&#xff0c;当一个图片高为2048像素时&#xf…...

阻止持久性攻击改善网络安全

MITRE ATT&CK框架是一个全球可访问的精选知识数据库&#xff0c;其中包含基于真实世界观察的已知网络攻击技术和策略。持久性是攻击者用来访问系统的众多网络攻击技术之一;在获得初始访问权限后&#xff0c;他们继续在很长一段时间内保持立足点&#xff0c;以窃取数据、修改…...

MFC与Qt多个控件响应统一响应消息处理

就目前使用C开发框架来说&#xff0c;今天来讲述下MFC框架下与Qt框架下&#xff0c;如何让多个控件响应统一消息处理方法。 功能&#xff1a;假设有5个按钮&#xff0c;需要响应同一个处理函数&#xff0c;该如何实现呢&#xff1f; Qt方式 开发环境&#xff1a;win10 VS201…...

Camunda rest api鉴权

对于rest api 不能没有限制的任何人随意调用&#xff0c;需要提供账号信息。 一&#xff1a;工作流引擎增加过滤器 /*** 对/engine-rest/*进行鉴权&#xff0c;防止非法攻击* 客户端调用需要配置用户凭证否则报错401* camunda.bpm.client.basic-auth.username* camunda.bpm.cl…...

【PostgreSQL】在DBeaver中实现序列、函数、视图、触发器设计

【PostgreSQL】在DBeaver中实现序列、函数、触发器、视图设计 基本配置一、序列1.1、序列使用1.1.1、设置字段为主键&#xff0c;数据类型默认整型1.1.2、自定义序列&#xff0c;数据类型自定义 1.2、序列延申1.2.1、理论1.2.2、测试1.2.3、小结 二、函数2.1、SQL直接创建2.1.1…...

PyQt5-小总结

之前学习PyQt5&#xff0c;然后那段时间想做一个桌面小程序&#xff0c;后来由于学习内容较多就做了一小部分&#xff0c;但是可以进行页面跳转。大家如果是初学者对Python感兴趣而且刚学数据库时可以看看代码&#xff0c;可能会有点启发。 效果&#xff1a; 登录进来是这&…...

vue父组件给子组件传值,子组件不渲染的原因及解决方法

父组件传递给子组件的数据&#xff0c;如果是一个复杂对象&#xff08;例如一个数组或对象&#xff09;&#xff0c;那么子组件只会监听对象的引用而不是对象的内容。这意味着当对象的内容发生变化时&#xff0c;子组件不会更新。 解决&#xff1a; 1、在子组件使用 watch 监听…...

【数据库】MySQL锁

一、锁的基本概念 1、锁的定义 锁是协调多个进程或线程并发访问数据库资源的一种机制。 MySQL中的锁是在服务器层或者存储引擎层实现的&#xff0c;保证了数据访问的一致性与有效性。但加锁是消耗资源的&#xff0c;锁的各种操作&#xff0c;包括获得锁、检测锁是否已解除、…...

mongodb学习篇

目录 前言基本概念数据库-database集合-collection文档-document 部署mongodblinux安装mongodbdocker安装mongodb MongoDB Shell (mongosh)命令行工具mongodb可视化-mongodb-compass、mongo-expressmongodb配置文件mongodb库、集合、文档库基本操作集合基本操作文档的增删改查C…...

kubernetes存储类迁移-备份恢复

背景介绍 kubernetes集群最开始使用了nfs作为存储&#xff0c;随着后续使用过程中数据量逐渐增加&#xff0c;nfs存储性能逐步出现不足&#xff0c;现增加了基于csi的分布式块存储后&#xff0c;需要对原有基于nfs存储类下的pv迁移到新的存储类下。 测试环境 k8s集群版本&am…...

python智能手机芯片

在未来&#xff0c;python智能手机芯片的发展方向可能包括以下几个方面&#xff1a; 强化处理能力&#xff1a;随着智能手机功能的不断扩展和用户需求的增加&#xff0c;处理器的性能需求也在不断提升。未来的python智能手机芯片可能会加强处理器的核心数量和频率&#xff0c;以…...

jsp做的网站站 图标是tomcat的 怎么换/广州抖音seo

ASP.NET MVC&#xff1a;通过 FileResult 向 浏览器 发送文件 2010-09-17 18:36 by 鹤冲天, 22905 阅读, 28 评论, 收藏, 编辑 在 Controller 中我们可以使用 FileResult 向客户端发送文件。 FileResult FileResult 是一个抽象类&#xff0c;继承自 ActionResult。在 System.We…...

wordpress如何添加注册按钮/南宁网站推广大全

python是支持多继承的&#xff0c;多继承一般就会考虑到继承的顺序问题&#xff0c;菱形继承的问题。class A(object):def __init__(self, name):self.name nameprint ("in A")class B(A):def __init__(self, name):self.name nameprint ("in B")class C…...

政府门户网站建设的误区/市场营销计划方案

线性表 基本概念 线性表&#xff08;linear list&#xff09;是数据结构的一种&#xff0c;一个线性表是n个具有相同特性的数据元素的有限序列。数据元素是一个抽象的符号&#xff0c;其具体含义在不同的情况下一般不同。 在稍复杂的线性表中&#xff0c;一个数据元素可由多个…...

动态网站开发毕业论文/求网址

给定一个 32 位有符号整数&#xff0c;将整数中的数字进行反转。 示例 1: 输入: 123 输出: 321 示例 2&#xff1a; 输入: -123 输出: -321 示例 3&#xff1a; 输入: 120 输出: 21 注意: 假设我们的环境只能存储 32 位有符号整数&#xff0c;其数值范围是 [−231, 231 − 1]。…...

天津单位网站建设/网站推广论坛

版本3问题&#xff1a; 不支持参数不同的构造函数。 版本4 设计&#xff1a; 通过可变参数模板来解决。可变参数模板可以支持不同参数的构造函数来创建对象。 #define LOG(info) \cout << __FILE__ << ":" << __LINE__ << " " \&l…...

在线培训网站怎么做/推广普通话的内容

文章目录1 Overview2 Deploy3 SummaryReference1 Overview Kubeflow 集成了机器学习的很多组件&#xff0c;比如训练、调参、模型部署&#xff0c;也包括了像 Tensorflow, Pytorch 等框架的支持。另外就是其还提供了 Pipeline 组件&#xff0c;用于用户定义机器学习的流程&…...