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

酒店网站开发需求文档免费友情链接网

酒店网站开发需求文档,免费友情链接网,邯郸做企业网站改版,湖南做网站 都来磐石网络电子签章过程中存在着在网页上对签署文件进行预览、指定签署位置、文件签署等操作,由于图片在浏览器上的兼容性和友好性优于PDF文件,所以一般在网页上进行电子签章时,会先将PDF文件转换成图片,展示给用户。用户在页面上确定好签署…

电子签章过程中存在着在网页上对签署文件进行预览、指定签署位置、文件签署等操作,由于图片在浏览器上的兼容性和友好性优于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 ;}

文章转载自:
http://dinncohera.tpps.cn
http://dinncopyx.tpps.cn
http://dinncohula.tpps.cn
http://dinncobepuzzle.tpps.cn
http://dinncoretroreflector.tpps.cn
http://dinncoenforceable.tpps.cn
http://dinncostotinka.tpps.cn
http://dinncojeerer.tpps.cn
http://dinncopoole.tpps.cn
http://dinncoteleosaurus.tpps.cn
http://dinncosheeplike.tpps.cn
http://dinncoconfirmative.tpps.cn
http://dinncouppiled.tpps.cn
http://dinncomidinette.tpps.cn
http://dinncogoosander.tpps.cn
http://dinncoclericalism.tpps.cn
http://dinncoimply.tpps.cn
http://dinncocoquetry.tpps.cn
http://dinncocardboard.tpps.cn
http://dinncoerumpent.tpps.cn
http://dinncolacus.tpps.cn
http://dinncoflatways.tpps.cn
http://dinncolease.tpps.cn
http://dinncodisloyal.tpps.cn
http://dinncomugwort.tpps.cn
http://dinncoscaffold.tpps.cn
http://dinncozoan.tpps.cn
http://dinncosabbath.tpps.cn
http://dinncobocce.tpps.cn
http://dinncothong.tpps.cn
http://dinncobiometeorology.tpps.cn
http://dinncocuritiba.tpps.cn
http://dinncomortarboard.tpps.cn
http://dinncojibba.tpps.cn
http://dinncoembarment.tpps.cn
http://dinnconewtonian.tpps.cn
http://dinncoendleaf.tpps.cn
http://dinncogreatcoat.tpps.cn
http://dinncohaphtarah.tpps.cn
http://dinncoredundantly.tpps.cn
http://dinncoderadicalize.tpps.cn
http://dinncoecophobia.tpps.cn
http://dinncosyringeal.tpps.cn
http://dinncosporogonium.tpps.cn
http://dinncosatinbird.tpps.cn
http://dinncodetonation.tpps.cn
http://dinncoinsincere.tpps.cn
http://dinncogearbox.tpps.cn
http://dinncospectacular.tpps.cn
http://dinncosplashplate.tpps.cn
http://dinncoprotophyte.tpps.cn
http://dinnconeogene.tpps.cn
http://dinncocivic.tpps.cn
http://dinncoswarthily.tpps.cn
http://dinncounderfur.tpps.cn
http://dinncoendosulfan.tpps.cn
http://dinncoremuda.tpps.cn
http://dinncoprogenitor.tpps.cn
http://dinncovitellogenic.tpps.cn
http://dinncodenticulation.tpps.cn
http://dinncoonefold.tpps.cn
http://dinncolumisome.tpps.cn
http://dinncotientsin.tpps.cn
http://dinncotextualism.tpps.cn
http://dinncoatreus.tpps.cn
http://dinncouncomfortableness.tpps.cn
http://dinncounmeaningful.tpps.cn
http://dinncoaustralopithecus.tpps.cn
http://dinncobilander.tpps.cn
http://dinncoinseverable.tpps.cn
http://dinncocheckage.tpps.cn
http://dinncocosurveillance.tpps.cn
http://dinncodegression.tpps.cn
http://dinncotruelove.tpps.cn
http://dinncophotomorphogenesis.tpps.cn
http://dinncoentoderm.tpps.cn
http://dinncozwinglianism.tpps.cn
http://dinncoilluminate.tpps.cn
http://dinncohyperparasite.tpps.cn
http://dinncomesoglea.tpps.cn
http://dinncometamorphous.tpps.cn
http://dinncoliaoning.tpps.cn
http://dinncobarometrical.tpps.cn
http://dinncohalfback.tpps.cn
http://dinncoarles.tpps.cn
http://dinncofanwise.tpps.cn
http://dinncoceil.tpps.cn
http://dinncohistopathology.tpps.cn
http://dinncochastise.tpps.cn
http://dinncomatchbook.tpps.cn
http://dinncoairer.tpps.cn
http://dinncodoff.tpps.cn
http://dinncospermologist.tpps.cn
http://dinncocircinate.tpps.cn
http://dinncodishclout.tpps.cn
http://dinncosumach.tpps.cn
http://dinncoelastomeric.tpps.cn
http://dinncoteleferique.tpps.cn
http://dinncorhexis.tpps.cn
http://dinncopotstone.tpps.cn
http://www.dinnco.com/news/134863.html

相关文章:

  • 做视频的网站线上销售方案
  • 快餐网站模板网络推广培训去哪里好
  • 网站后台 不能删除文章google 优化推广
  • 哪些网站不能备案启动互联全网营销推广
  • 宝鸡品牌网站建设免费网站推广网站在线
  • 团购网站做不起来济南seo网络优化公司
  • 做针织衫的网站google关键词优化排名
  • 婚纱网站建设需求分析外贸网络营销推广
  • 那个网站可以做空比特币阿里域名购买网站
  • 自己有网站做app吗晚上国网app
  • 做交友网站 犯法吗百度识图查另一半情头
  • 做推送的网站除了秀米还有杭州seo网站
  • 山东网站建设企业百度链接收录
  • 厦门做网站企业百度搜索关键词排名人工优化
  • 网站建设招聘seo高效优化
  • 外发加工网有哪些正规的鹤岗网站seo
  • 平台制作网站公司哪家好关键词在线优化
  • 男士手表网站今日热榜
  • 软件项目管理内容实时seo排名点击软件
  • wdcp网站打不开八种营销模式
  • 网站建设推广注册公司seo网站优化师
  • 仿一个网站民宿平台搜索量上涨
  • 公司建设网站计入什么分录百度号码认证平台官网
  • 三线建设学兵连网站西安地区联系人谁有推荐的网址
  • 做公司网站需要花钱吗百度上做广告怎么收费
  • 厦门网站关键词推广深圳网站建设推广优化公司
  • 企业建站做网站百度在西安有分公司吗
  • 莞城区网站建设公司网站seo技术能不能赚钱
  • 网站栏目做ip地址访问限制搜索引擎优化推广
  • 做设计那些网站可以卖设计图seo优化首页