freemark+html+jbig生成pdf文件

2 篇文章 0 订阅

1.根据银行要求,现在pos机端在做交易之后,必须支持电子凭证打印。

2.本文涉及到银行的助农业务(水费,电费,社保,广电,取款,贷款,住建,签约) 等功能。

3.本文使用的技术有freemarker,银联压缩图片解压,springmvc 文件下载等,文件中没有写测试类,如果需要测试的可以直接使用service中方法,资源地址https://download.csdn.net/download/lxwfly/14122058,不需要下载积分,下载zip解压,导入idea,测试即可。

3.1测试代码 测试代码是经过提炼过的代码和实际应用中有些不同,比如临时文件存放路径,上传图片,下载图片都不涉及,还有代码穿插的业务逻辑修改等。

pom文件 需要添加的依赖

 <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>xmlworker</artifactId>
      <version>5.5.10</version>
    </dependency>
    <!-- <dependency>
         <groupId>org.pdf</groupId>
         <artifactId>core-renderer</artifactId>
         <version>1.0</version>
     </dependency>-->
    <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>com.lowagie.text</artifactId>
      <version>2.1.7</version>
    </dependency>
    <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>flying-saucer-pdf-itext5</artifactId>
      <version>9.1.5</version>
    </dependency>
    <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>flying-saucer-core</artifactId>
      <version>9.1.20</version>
    </dependency>
    <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>flying-saucer-pdf</artifactId>
      <version>9.0.9</version>
    </dependency>
    <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>jbigkit</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>org.pdf</groupId>
      <artifactId>jbigkit</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>

测试用到的文件

package pdfDemo.service;

import java.util.HashMap;
import java.util.Map;

public class Constants {
    
    public static Map<String, String> respCodeTransMap = new HashMap<String, String>();
	 
	 public interface PDF_CREATE_AND_SIGN{
         public static final String PDF_SIGN_CFG_PATH ="ifspconfigs/constant/netsignagent.properties";
         public static final String PDF_FILE_PATH="D:/soft/mvn/project/pdfDemo/";//"/data/files/mchts/eleBillTemplate/";
         public static final String PDF_CREATE_FILE_FONT="eleBillTemplate/simhei.ttf";
         public static final String PDF_FILE_HEAD_IMG ="eleBillTemplate/HeadLogo.jpg";
         public static final String URLSTR ="";//CommonConstants.getProperties("UPLOAD_FILE");// 上传地址
         public static final String REQUESTCHNLNO = "411";// 请求渠道号
         public static final String REAUESTFILETYPE ="04";// 文件类型-PDF
         public static final String REAUESTFILETYPE_IMG ="03";// 文件类型-图片
         public static final String REAUESTFILETYPE_TXT ="99";// 文件类型-文本-对应文件类型为其他
         public static final String DOWNLOAD_URL="";//CommonConstants.getProperties("DOWNLOAD_FILE");
         public static final String PDF_PAGESIZE="";//CommonConstants.getProperties("PDF_PAGESIZE");
         public static final String PDF_FILE_NAME_SUFFIX=".pdf";
         public static final String PDF_FILE_CREATE_STATUS_0="0";//成功
         public static final String PDF_FILE_CREATE_STATUS_1="1";//处理失败
         public static final String PDF_FILE_CREATE_STATUS_2="2";//
         public static final String PDF_FILE_CREATE_STATUS_01="01"; //预览
         public static final String PDF_FILE_CREATE_STATUS_02="02"; //下载

         public static final String PDF_FILE_FIELD_TOPLINE="topline";
         public static final String PDF_FILE_FIELD_BOTTOMLINE="bottomLine";
         public static final String PDF_FILE_FIELD_ID="id";
         public static final String PDF_FILE_FIELD_NAME="name";
         public static final String PDF_FILE_FIELD_VALUE="value";
         public static final String PDF_FILE_FIELD_INDEX="index";
         public static final String PDF_FILE_FIELD_DES="des";

         public static final String PDF_SIGN_IMAGE_JBIG=".jbig";
         public static final String PDF_SIGN_IMAGE_BMP=".bmp";
         public static final String PDF_SIGN_IMAGE_JPG=".jpg";
         public static final String PDF_SIGN_IMAGE_TXT=".txt";

         public static final String HTML_IMAGW_HEAD="data:image/jpeg;base64,";

     }
}

package pdfDemo.service;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pdfDemo.bean.PbsZnorderTicket;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @ClassName CreatePdfServiceImpl
 * @Description
 * @Author Administrator
 * @Date 2020/6/23 10:23
 **/
public class CreatePdfServiceImpl {

    private static Logger log = LoggerFactory.getLogger(CreatePdfServiceImpl.class);
    /**
     *@author lxw
     *@date 2020/6/30
     *@desc 解析二维码图片信息
     *@param imageData
     *@return byte[]
    **/
    public  byte[] getQrcImage(String imageData) throws Exception{
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes ;
        try {
            bytes = decoder.decodeBuffer(imageData);
        } catch (IOException e) {
            log.error("Base64解码图片信息失败,原因:{}",e.getMessage());
            throw new Exception("Base64解码图片信息失败!");
        }
        return bytes;
    }
    /**
     *@author lxw
     *@date 2020/6/30
     *@desc 解析签名图片数据
     *@param signImagData
     *@return byte[]
    **/
    public  byte[] getSignImage(String signImagData) throws Exception{
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes ;
        try {
            bytes = decoder.decodeBuffer(signImagData);
        } catch (IOException e) {
            log.error("Base64解析签名图片信息失败,原因是:{}",e.getMessage());
            System.out.println("Base64解析签名图片信息失败,原因是:"+e.getMessage());
            throw  new Exception("Base64解析签名图片信息失败!");
        }
        return bytes;
    }

    /**
     *@author lxw
     *@date 2020/6/23
     *@desc 检查文件是否存在,存在就删除掉
     *@param fileName, path
     *@return void
    **/
    public static void checkFIleExit(String fileName,String path){
        log.info("checkFIleExit方法入参:fileName:{},path:{}",fileName,path);
        File file = new File(path+fileName);
        if (file.exists()){
            file.delete();
        }
    }

    /**
     *@author lxw
     *@date 2020/6/30
     *@desc 生成文件名
     *@param
     *@return java.util.Map<java.lang.String,java.lang.String>
    **/
    public static String createFileName(String orderId){
        return orderId+Constants.PDF_CREATE_AND_SIGN.PDF_FILE_NAME_SUFFIX;
    }


    /**
     *@author lxw
     *@date 2020/6/24
     *@desc 获取文件输入流
     *@param fileName
     *@return byte[]
    **/
    public static byte[] readPdfFile(String fileName){
        InputStream in = null;
        byte[] bytesRel = null;
        File f = null;
        try {
            f = new File(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
            in = new FileInputStream(f);
            bytesRel = new byte[ in.available()];
            in.read(bytesRel);
            return bytesRel;
        } catch (IOException e) {
          log.error("读取文件{}失败!"+Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);

//          throw new Exception(IfspRespCode.RESP_ERROR,"读取pdf文件失败!");
        }finally {
            if (in != null){
                try {
                    in.close();
                   /* if (f.exists()){
                        f.delete();
                    }*/
                } catch (IOException e) {
                    log.error("输入流关闭失败!原因:{}",e.getMessage());
                }
            }
        }
        return  bytesRel;
    }

    /**
     *@author lxw
     *@date 2020/6/24
     *@desc 写文件
     *@param pdfByte, fileName
     *@return void
    **/
    public static void writePdfFile(byte[] pdfByte, String fileName) throws Exception{

        checkFIleExit(fileName,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
        OutputStream os = null;
        try {
            os = new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
            os.write( pdfByte ) ;
            os.flush() ;
        } catch (IOException e) {
            log.error("写入文件{}失败!"+Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
        }finally {
            try {
                //noinspection AliControlFlowStatementWithoutBraces
                if (os!=null) {
                    os.close();
                }
            } catch (IOException e) {
                log.error("输入流关闭失败!原因:{}",e.getMessage());
            }
        }
    }
    /**
     *@author lxw
     *@date 2020/7/1
     *@desc 二维码生成器
     *@param content
     *@return byte[]
    **/
    public static byte[] qrcImgCreate(String content) throws Exception {
        //中文乱码问题
        byte[] imgData;
        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            //中文乱码
            Hashtable hints = new Hashtable();
            hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
            hints.put(EncodeHintType.MARGIN,1);
            BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 40, 40,hints);
            ByteArrayOutputStream qrcImgByteStram = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(encode,"PNG",qrcImgByteStram);
            imgData = qrcImgByteStram.toByteArray();
        } catch (WriterException e) {
            log.error("生成二维码失败,原因是:{}",e.getMessage());
            throw  new Exception("生成二维码失败失败!");
        } catch (IOException e) {
            log.error("B生成二维码失败,原因是:{}",e.getMessage());
            throw  new Exception("生成二维码失败失败!");
        }
        return imgData;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc freemarker 生成文件路由器
     *@param
     *@return boolean
    **/
    public static boolean freeMarkCreateFile(PbsZnorderTicket pbsZnorderTicket) throws Exception {


        Map<String,Object> reqData = null;//(Map<String, Object>) IfspFastJsonUtil.jsonTOmap(pbsZnorderTicket.getEnvoiceInfo());
        switch (reqData.get("fileType").toString()){
            case "1": //pdf-生成
               return  PdfCreateHandler(pbsZnorderTicket);
            case "2": //word
//                return WordCreateHandler(pbsZnorderTicket);
            case "3": //图片
//                return WordCreateHandler(pbsZnorderTicket);
            default:
                throw new Exception("未知的文件生成类型{"+reqData.get("fileType").toString()+"}");
        }
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc freeMarker pdf文件生成
     *@param
     *@return boolean
    **/
    public static boolean  PdfCreateHandler(PbsZnorderTicket pbsZnorderTicket){
        try {
            //取出对象中小票信息
            Map<String,Object> reqData = getReqParams();//(Map<String, Object>) IfspFastJsonUtil.jsonTOmap(pbsZnorderTicket.getEnvoiceInfo());
            //处理模板信息
            ElecBillCreateUtils.txnCodeToTemplate((String) reqData.get("txnTypeCode"),reqData);
            //处理图片信息
            imageHandler(reqData);
            //处理金额
            handlerAmt(reqData);
            //将信息写进模板中 32
            String freeMarkerRender = ElecBillCreateUtils.freeMarkerRender(reqData, reqData.get("templateName").toString());
            //生成pdf文件
            ElecBillCreateUtils.createPdf(freeMarkerRender,createFileName((String) reqData.get("orderId")));
        } catch (Exception e) {
            //更新备注信息-将错误明细放到库中保存,以便排查信息
//            updateRemarkInfo(pbsZnorderTicket,e);
            log.error("生成pdf文件失败!",e.getMessage());
            return false;
        }
        return true;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc freeMarker 图片/ word 文件生成 目前没有使用
     *@param
     *@return boolean
    **/
    public boolean WordCreateHandler(PbsZnorderTicket pbsZnorderTicket) throws Exception{
        try {
            //取出对象中小票信息
            Map<String,Object> reqData = null;//(Map<String, Object>) IfspFastJsonUtil.jsonTOmap(pbsZnorderTicket.getEnvoiceInfo());
            //将信息写进模板中
            String freeMarkerRender = ElecBillCreateUtils.freeMarkerRenderForWord(reqData, reqData.get("templateName").toString(),createFileName(pbsZnorderTicket.getTxnOrderId()));
            if ("03".equals(reqData.get("fileType"))){
                //生成image文件
                ElecBillCreateUtils.createImage(freeMarkerRender,createFileName(pbsZnorderTicket.getTxnOrderId()));
            }
        } catch (Exception e) {
            //更新备注信息-将错误明细放到库中保存,以便排查信息
            updateRemarkInfo(pbsZnorderTicket,e);
            log.error("生成pdf文件失败!",e.getMessage());
            return false;
        }
        return true;
    }
    /**
     *@author lxw
     *@date 2020/11/6
     *@desc pdf生成 处理图片信息
     *@param reqData
     *@return void
    **/
    public  static void imageHandler(Map<String,Object> reqData) throws Exception{
        //转码器
        BASE64Encoder encoder = new BASE64Encoder();
        //头部图片
        String headImg = ElecBillCreateUtils.getImageData(ElecBillCreateUtils.getResouseAblovePath(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_HEAD_IMG));
        reqData.put("headImg",Constants.PDF_CREATE_AND_SIGN.HTML_IMAGW_HEAD+ElecBillCreateUtils.removeSpacilChar(headImg));
        //处理二维码信息
        if (null !=reqData.get("qrCode")){
            byte[] qrCodes = qrcImgCreate((String) reqData.get("qrCode"));
            String imageData = encoder.encode(qrCodes);
            reqData.put("qrCode",Constants.PDF_CREATE_AND_SIGN.HTML_IMAGW_HEAD+ElecBillCreateUtils.removeSpacilChar(imageData));
        }
        //处理签名图片
        if (null !=reqData.get("signBase64")){

            String signImagePath = (String) reqData.get("signBase64");
            //下载图片信息
//            byte[] bytes = null;//downloadImage(signImagePath);
            //解析转换图片数据
            byte[] imageBytes = ElecBillCreateUtils.hexToByte(signImagePath);
            //将jbig图片转换成bmp文件
            ElecBillCreateUtils.jbigTojpg(imageBytes,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,(String) reqData.get("orderId"));
            //将图片转换成jpg格式
            ElecBillCreateUtils.bpmCoverJpeg(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,(String) reqData.get("orderId"));
            //读文件
            byte[] imageFile = readPdfFile( (String) reqData.get("orderId") + Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG);

            String signImageData = encoder.encode(imageFile);
            reqData.put("signBase64",Constants.PDF_CREATE_AND_SIGN.HTML_IMAGW_HEAD+ElecBillCreateUtils.removeSpacilChar(signImageData));
        }

    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc  更新备注信息
     *@param pbsZnorderTicket, e
     *@return void
    **/
    public void updateRemarkInfo(PbsZnorderTicket pbsZnorderTicket,Exception e){
        PbsZnorderTicket t = new PbsZnorderTicket();
        t.setTxnOrderId(pbsZnorderTicket.getTxnOrderId());
        if(null!=e.getMessage()){
            if (e.getMessage().length()>=999){
                t.setRemark(e.getMessage().substring(0,999));
            }else {
                t.setRemark(e.getMessage());
            }
        }else {
            t.setRemark("订单:"+pbsZnorderTicket.getTxnOrderId()+"生成pdf文件失败");
        }
        t.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
//        pbsZnorderTicketDao.updateByPrimaryKeySelective(t);
    }
    /**
     *@author lxw
     *@date 2021/1/7
     *@desc 金额处理
     *@param reqData
     *@return void
    **/
   static void handlerAmt(Map<String,Object> reqData){
        if (null!=reqData.get("amount")){
            String amount = reqData.get("amount").toString();
            //金额处理
            reqData.put("amount","RMB "+ split3(amount.toString()));
        }else {
            reqData.put("amount","RMB "+ split3(reqData.get("amount")));
        }
    }
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(",##0.00");

    /**
     *@author lxw
     *@date 2021/1/7
     *@desc 金额添加 分号
     *@param o
     *@return java.lang.String
    **/
    private static String split3(Object o){
        if (null == o||"".equals((String) o)){
            return "0.00";
        }
        BigDecimal var0 = new BigDecimal(oTs(o));
        return DECIMAL_FORMAT.format(var0);
    }

    public static String oTs(Object o){
        if (null == o||"".equals((String) o)){
            return "0";
        }
        if (o instanceof String){
            return  new BigDecimal(o.toString()).toPlainString();
        }
        if (o instanceof Number){
            return o.toString();
        }
        return "0";
    }

    /**
     *@author lxw
     *@date 2021/1/6
     *@desc
     *@param
     *@return byte[]
    **/
    public byte[] uploadImageHandler(String imageData,String fileName){
//        //解析转换图片数据
//        byte[] bytes = ElecBillCreateUtils.hexToByte(imageData);
//        //将jbig图片转换成bmp文件
//        ElecBillCreateUtils.jbigTojpg(bytes,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,fileName);
//        //将图片转换成jpg格式
//        ElecBillCreateUtils.bpmCoverJpeg(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,fileName);
//        //读文件
//        byte[] imageFile = readPdfFile( fileName + Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG);
//        //删除图片
//        checkFIleExit( fileName + Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);

        return imageData.getBytes();
    }

    /**
     * 单元测试请求参数
     * @return
     */
    public static Map<String,Object> getReqParams(){
        Map<java.lang.String, java.lang.Object> reqMap = new HashMap<>();
        reqMap.put("orderId","22120210107000168221");
        reqMap.put("operatorNo","长城");
        reqMap.put("pkId","0");
        reqMap.put("merName","测试管理部部长");
        reqMap.put("acquirer","六盘水农村商业银行股份有限公司(总部)");
        reqMap.put("cardNo","621779*********3760");
        reqMap.put("referNo","000034264812");
        reqMap.put("issuer","贵州农信社");
        reqMap.put("datetime","2021-01-07 09:16:45");
        reqMap.put("merNo","806701782200001");
        reqMap.put("isDuplicated","00");
        reqMap.put("jsonBus","");
        reqMap.put("merPayNo","806701760510089");
        reqMap.put("amount",2400);
        reqMap.put("batchNo","000003");

        reqMap.put("authNo","");
        reqMap.put("receiptType","商户存根");
        reqMap.put("cardType","C");
        reqMap.put("txnTypeCode","200401");
        reqMap.put("jsonBody","");
        reqMap.put("signBase64","00020100000006560000018c000000020800031cff02ff02ff02e9efbf0bff021e70ff02557cf2ff027efaf810ff02862e30bcb067b0ff027d61f1c8e025e0ff02988553d2d6c1f518d53639c0ff0216f5a1fcebc641fc888655c42e6f3d0462e318ff02c49be605fcf8d45a66a918a4a1dfc837158a7f15a371f7880c5dbd5427e3c87813a0ff026309cb5f02953e10c9c4122f0c927321bb58656a12ed5fa56663a6f3a9fd174cff02ab302ee3a6dc3a9e76a241d76ec7a3fcc59f8e46b1906a7c004a35bbd55a58ef40ff0230b934208323d5d5a70303cc0a49cda96f5db775506b3ab7dd49376127076de5ff0264ecf0928ceb7672c5ae1441a9aa2c3bdff0aba3bb2882e73bef87d4492abb9c03d0ff025c367d3618505f9632e87fe6a16e631c8ca30d9b1b65b524147140ff0273b84ef9632c5ce6cbb4bd35890830a61510d2a205e5fcf1f4ff02511d28fc76b6190aa189c061557af17bde6c8941bbcbbf8aa255f7ff025a123662c71d9f10b037466092fd338fb73c93fdcd030b1d1be2ff02c1518d4627b724dc6b39638572f94fb5f9abd01b2ca17ccb80ff0246a48ea96bbb2b650f66d885f86e8458e602ae1ef82b2cedee8b005eeb449428ff024d2caea756b0c73417c1d1044773ef81e55aa3d8413fe14327552919e86dfb671eb4cc420a20ff024e16c891609a7b7625085a4960d03eef28ce019beac86613a119d81f6c86ff029094edbf3d8d1006b5d2f403c615f259884788c09c0e8e5d7fa7dc1ec80f28ff028391a866e99e941b3840be6134078e4b4508e35a09aaa39aa0ff02dbf3a6cc698f32ddfcde5db60a26737e3ce00da7174e495daf92b0ff0209bd9b8c2d6ab430f2f3b75802e5d444aca832b2d7130c00a347e41bb7fd5f28ff027c4ff793c4f301fd34dfded06402a822bf862500b72402d9038ba24758dea50810ff0204de4b7f19c4292fea31b891deb3c446df99c3d8322a4564ff027e8ed1e601c9fa53703b1c16e2a637b56be9dbf4059c01c3afc3fdeb84576e8da3ab40ff022a1749b944c3f6eeb409052c723a2c116aa6f0316c7bc06cf373aaff024b7d86eb64cde2c91f45585e6d4e2b0258291819e10dd38f5d6c80ff024b01e424b2ac1294112bd3eff120c77c44226202ce9f76b163678b9fa988ff025197fe5b6ba189ba1142092a0ac9fe8150c5eaed7afeff0259bc5bbfb24f34f1a79c402aaeff0210765cc5c0c9fb2e6679d75c02f0d5a180ff029cac460c496054641b6b6c7b8a51851cff02551d7ab98e46f269fac585e3e341ff02634cc8e13acb108fa10ff3b4ff02bd5a929e5067cd061c1ecddc56b8ff0222bc9a1e14ca3e985d72976080e0f8ff028f5b789afadd520cab890c7d68ff02cd4ae84089ff02937320ff02d7ff02ff02ff02ff02ff0280ff02ff02c3f2c168ff025d2097a0ff02598aa0ff02850439bdff02691d6c07cc12e7c0ff020beff58298cd73e99316ff025e9351a90d0920491922be2fc0ff029ca329dae08b19246890ad200b8c3aedbe3d5877a4ff025c409d2d18c6aac7574ec4e6181f0da7cc00e97063646f1a44977fe85a73cc590e9c72d319b2c94c98aac4ff026a91cb9f3d3c4577213e0d576533fa5a07ef222fef0c981943fc3c39cadab203e975e5b5457053d10040c64da910145b6ab9dd8f7605e9c937ff026091d1abcd0e085c7d8f08948d01866c8d6162f77b69009fcdcb7f4242259909aaa808600e73343bbe274ae330e58cb53ccd30895880ff022bb15980affb8a43f58ab7b007d535e462fdc2e55612a779687283ebb07491d2087045d8b0a798583832188f8b43d283bf23beea0344c7230cff02e1aa58cfdf1ed79d4f01c28c3ca43162fb596089e8122f46e9e3a8322feabc03509844f361d6b74eb16d520ad97cd4ae3f2971400f3b3713fc82f8ff024bee2a5cb707487f0888ac6cd2ef385975fe9d340bd790fe119a22f409cfde406e6049a9163e8f19acb6dd2299b78b973dff024afcc9137c2a95fd510bc7fca16e19a34af1889adb6cc2cfbc0e38643cf7b7119398100f2846c1aa7fb0ff024f1dd3564f7e238b55c7e01b696afb1958112a6a8d75e41daa9c634b55f666d8001f147ed016afe0ff02134521d2befe186841b4a6bc654d0df4a39cefab1bb3a50a3a722e0b7f25b99ca3ecf7ba5da8da669f6cccff02128f8779d49954ff0030e42104302c4be063c8ee115c1f13b205cafa4786169dbbf8fd53fb426cc86a6804ff02188411a9a962be09d6faf4b98d19b28557fe554969fb9dc1d15c74f4e6d583ec67772bd2efff020b3707a2f8a3aeab541dde39f8b54a047b5b9b1711ecc14f41b752de18cc8ace35d9eb4b81f83875e0db464ebe80ff0284244a1f6c3f5262369aaca88b8693122f7ea793e518d23e90656bfc76c68cde0bfb1f1edace177216f12a58e808a7e4ff02377c65a38b12a3ab4e19cc3134455c2d9f143ec6b99b454015311f5e56f9139e3a720387ef75fba607130f0ec1ba5eaf60eb84ff021f55495f6159e960cb337f44f707ef2b4b018e24db9699fac19eb329e8adbb452c44d081c05b9b8eac40ff023f2a8d38779f16099ef10cd015ba0f4abf7521f215a49ac305815f759d1e68c7cc33c776aa729cc3d7602ca6c5ba5778ff02cbfc9f609256c5fdeeded52c7fc4b92d8e18d45bf9c96d155d4efbea7be0553af0478dc04768a6dea21a5510ff0287378e076b01350bcd281acd93fe8a28a69ff7440cb7fc0f3bd2d43617bb2ee9e571fbdba7cb485ee579c73ced3c8fff02d92a2f890cdaa00afcb65c4419dc3c2d97d62b33a242718f48ff00a2c2487473e7990631326226c6747f274fa5d0b6a71f045b2be11c91f9cbc070ff0298c802325f04565324f020290476bb46e1a2d6bb9319536d4e41ba4d68ae54bc10f9252e5053998cca1b80ff024b539b9236f91fdd10627ad9f77b5f9dd74f44c2f9addb2578730f6e91c4ba8b6f9f1fc8c752d9687a122c2213b387a054c810425ae40250d140ff02198222e7ca3985da2e3d75e41af80fba430a529258a09021a01ba6fc37b3d73fac47056d524cf7d48af9b927f69320ff020963a54a9ae6de723eeb2aff00e93421c1c3e599ca131ea5d9c0b4582e13d60d4b48723a03cfdda6aae79aff022655f7e751a19acd4f4917695f6b2ba77417c7e0f0b0c7a40dcb74f326363c5f6c39396d49cbc695adefb70f6be0ff020f65ab7da7134b8570508dd008c5ac366396393370c2a807c051d651608156ff027544721b6933621d8e8fbd3be55d97d056c2a833eb8c380a80ff022aa031305736d65d6b64eb10c569c8d4452768299d59a431e930ff026f67d3e8c63980aa22a9baa7b6ae8f4f84d8b1810581f868ff02275d4bec8a3edf5724010c9f40c321a811a2cb03ff024d176c5fcbf4523912c2db88586fed8d51c9e219ff028d449599be56448438c0de592d2545feec692a2481cae32f09813b2a38ff020fb0dbc9a9b94b0956406da5cd8d595e06670263fd663463b09aa0ff0206c99c509803b59bd548c5b7d0fefcad714f14ff0276243b6033a658ff024a3cff02ff02ff02ff02ff02ff0280ff02ff0218d9ff026e1e617460a126ff02012106e1a680ff02112af812576a80ff021b9ce5f1b786f2ac2d50f63a60ff02017de51471fc7dbd118083e4946506ff027ff276578a2021f895cb1bff0033a49b9cd6ff02cdfb940495c6927368e03f471eb7a0743524d39658f1e4e9584cfc27caa0b5ff021d7d4cdcf1edcaa115a0e2cecf15d67c6df51836c9e78e7617ce6ad6ebda759c792668237b6f9aebb37b856d3ba8f766c2ac5e5cf75ac683dc4ae21c0a8c4a4d31e54fe5476ee8845560ff02eccfa8cddd3b970267c5a98b02d5a8f13f24f6d85d2e393f060a80d79b66a9d996b710c3d90a694f81a8862c132cd0c085d31f77599a4a2694ad37c9a5ec9d51f8f620282ff45af919ee6b77793e4072e1f0d3901ed692f91a80ff022870616804302838aa8d10d388eca464da8e269350dff10458ece1347cc785540b2da891756b36aee0a02e7b1ade2a00f3e81632c780f266e0cf64ca5b02913c15b069f9875a79513ff0dd37e166bd5e7b67d543a0ff02c4cadd00dc62de31a2444a611b705253973796ee5cd1d61cb0e19be24b18fe068656717aa0370bc90f9deb2b4bc187b4eb3aac6166199d3ad6531a82ef1ff0114f551afafd1d00a831ab4c806f0e64bf6a824ec18a924f40ff020361446a02ce87b456e2ae57cba22c64a38c27730dbefdca6ce39c4b2d4728f000572e09e2bb1d876b35b40637902f24bf0f4d34a2288c191bef4d264f7d9497fdd1c946e2e749de3b8c9edc1613ef8eff00808f88600f0b2d786af71d90ff026cc1d1aa7ae3cd863efefb11d53264f128975141d5dfa4aec3bac15d48f638b14d952707821e856ce2df9fd909238d5c4661a401269f193f74afe628217dd59401f3ca73c8045f8735060aa96050ff02f7b1ad5e7ecbea3d3266e0ae897fbd8ff34d1edc37440eb29a8251068d803f43b7f6b7eae5cf8c0b1d7069517c757ec110ae02effb9929e5aba315f198317c21958543cc2dc9c0ff0226a02904faa9d80ca2454c9e9e97212c7e8e422d6ca7c537c347641d3b81bc38e811bde4392f8b90ef8c4bc204bbd1885243d8931801e270b0a5100288839db102f9a878f304726dae8580ff02531529bf160b7f6dda8b087a1ea80e82a2ed1c3566804c0343ca68052d31ff00b33c6fedf379b2b5df9f1bacfda414288eba0850798b592c8ec49c20ac4fdfafa798497d56d3f01f349a488d07b8c54fecadd0ff02174a6e5d7b8e82be88819f25e944b20fd7fc47a5e67a5d1ed6f9056c86c46146826c26964f42c25b13df0ee600950ebd45056ed959bf8136811065227193b3becd501cae3a8b50246366c1ebf0332d004d7664ff02898023aacc48928c885f76d0d1a89bf9d0cfc2eddaa55c03ead06f7a406293cb78e014f4577da9ccacc13e12a1e7fb0f0fa64da1c917df9cdd122a2c87c8a62b80ff0229782d208855baf90d7efd377af4e9b17fe4fed608d6ac8566830026c551dbcaaaecafc85e9f25e63b9ea37ff4a8de4ff09d7482d668a1e3a049f1f0aaee5fc3bca31a9b5697ff026b60f5bad5dbd868e35c8c478301026e6601d9eff8a2f8bb3afc60f874d3cf714f8c0829e94e3815e62150db7b6072cd7f9a0aa4c294281d53dadc1c7d3875fe48ff026e74886871516ff7b28cb2fb8a20c03504c03882e83d0eb1f53880ce7aa76c92fd45edcd3090075b3b111a8b8fa5d26249a4e6a02b724dec5b693d4fa72217230893966f29c94b2b1071daeaac973efa0daa20ff0291b44b9307ca5d3a023a2fca1d798f113a15746532e14eaf7c517abacdfbc8af0a5b9e235e79cfe33eef116db3d384b62bd88d9f861eb01f813fcb60e7e2e550810e9f16c4df1836a18b21be80ff02b3ccac6aa3fcbf9f86c72a68f94dba09e10a2c9b71bf534b83c44e7933e8c9b50494cab89567f7d42b92f0b51dcc16b524946420d283fca79415057744b8ff024a6b416164eeb4fd2e4e6f008e2806f45734c3d910ab6124a72036cca9ec0664bcb33825830b565a3ccd8b928665a6db37d5dbed47296d4fbcdfa5156ca19c25ff0251522cde186e8b3fc7053d005cc64c7edcc8369342e01e76b115f7b3d0547f1df3cdc1974f8d48a3cc65fc9b830ad99a8cf0ff00770bdc6f7b14efd756b4a21df0afe0a2ff027a1f7832d269a5c5749e71edb043429be7441908f6303481658314e23a7d0b51b89f4d4895bf13d99e5bd47fdde8aed51333c0f8c5d25e6748227da25306ef460a5728744957a5ef3364ad0376965516f13193fe036ead84f06b2e1e96b1ff02e9f4604cc796d47608b08013fde2b7cc8239b237b7de42669b2be932ec8047809bfc0eaca0c7d0f8f4dee86a53e9167e824124fe080bb77d396eeccbd32fdacd407f3779ff0226724fb9aab527f63b0d376010206126e4dbe07657f11f094474ae59dd8b3dc34fb710e97a968205e60efe54b719624b4ba69a504bcd0c1889a2b658252f92aeccd72087a0ca7deae35f12f435f7186a5294b01f6b1220f9bd1cb0d53f4c1506ecce36a41f9520ff0273b42eff0067a67d6fdf37381905505e6e1aa43daa90552a5e744e17a5b453edbf7d581faa2d9efe9e68fa054b4ae52091b411182994c40950fc0c8b0f51fdf763290b49bb65245cc337eacc82ff021b1c180c13e7dc9323fb4330610c0348b48a09821e02db6ea33c48085249f39f6c4039551e298c4950800e4c09b247bcde05b58513c418cdd70436c8dfd42882125f39b3485210715ee69b50182fff022a3b97842fa40b5cb9471e7deaa32671f5cbdee74314d83cfb9af7ae4c5839c634c217daa12ec57e185bb58937f9d5099ce0de1e5a46556f8bb0911e47cef6d69f33bd979d8ac0ff0205779cb46d589e6a9c57252aa7140f1dfd968e3ab49be4a7b58699e7941f47feb1f2b329e919e9f5c9bbd04edd4b2507b450ff0270e9a0204e241835a54f3b2874fabb7fd713c34e77723a95ac4366749b1edd6e847426310c3dcc6bc16c96bf68ff025dc13b5e3efefac68f835463d53e8c12b07c01323f40c57f2d47ec7d45c7772be2686330d231d916a420ff0277dcf1c6069528a66ed2e1d3040bc7449b11e7afbb7d0205dbbfd37922b72670598c8799c6961132cc40ff02b1aaa2ea28500cb24089199b6757c196ee0e1faf6d1d5cb9b3c0031d91bdbefee7f0a980ff024db7732ddfbe7320849d0e20bf930a60837af776cebff6e9780888ca818f5e419300feff02c0d511f2343e1d14cbcd86b2655699b937943b9c8be640000491c19fb7dcd5762978ff0002634eacdba4ff00bda577890e261d8780ff02195526190f0fbb0831a804bb79ff005a3171b77d75e18703a553c39aa4eb0c4f50aeb69356fbc905db0360bef48e193a1accd243c86154ff025a5962cba0a0244fe9281241915c2b8f8f5ad0812ced0f0c342bd2d26efcff028f79e7ef0e32b33db83c874648ff023baaff02ff02ff02ff02ff02ff02");
        reqMap.put("voucherNo","000048");
        reqMap.put("transType","助农取款");
        reqMap.put("printID","111");
        reqMap.put("termNo","82879906");
        reqMap.put("fileType","1");
        reqMap.put("signRequest","00");
        return reqMap;
    }

}
package pdfDemo.service;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.itextpdf.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import sun.misc.BASE64Encoder;
import uk.ac.cam.cl.mgk25.jbigkit.JBIG;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName ElecBillCreateUtils
 * @Description
 * @Author 电子票据生成工具类
 * @Date 2020/11/5 14:53
 **/
public class ElecBillCreateUtils {

    private static Logger log = LoggerFactory.getLogger(ElecBillCreateUtils.class);

    private static Configuration freemarkerCfg = null;
    private static Pattern PATTERN_REGX = Pattern.compile("\\s*|\t|\r|\n");
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(",##0.00");
    static {
        freemarkerCfg =new Configuration();
        try {

            freemarkerCfg.setClassForTemplateLoading(ElecBillCreateUtils.class,"/eleBillTemplate");
            freemarkerCfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *@author lxw
     *@date 2020/11/5
     *@desc 获取图片文件的base64转码数据
     *@param imagePath
     *@return java.lang.String
    **/
    public static String getImageData(String imagePath) throws Exception{
        log.info("getImageData 获取图片数据,图片路径"+imagePath);
        String imgData = null;
        byte[] var1 = null;
        InputStream in = new FileInputStream(imagePath);
        var1 = new byte[in.available()];
        in.read(var1);
        BASE64Encoder encoder = new BASE64Encoder();
        imgData = encoder.encode(var1);
        return imgData;
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc 去除文件中存在的回车,换行 符(c)
     *@return java.lang.String
    **/
    public static String removeSpacilChar(String str){
        String spacilChar = null;
        if (StringUtils.isNotBlank(str)){
//            Pattern pattern = Pattern.compile("\\s*|\t|\r|\n");
            Matcher matcher = PATTERN_REGX.matcher(str);
            spacilChar = matcher.replaceAll("");
        }
        return spacilChar;
    }

    /**
     *@author lxw
     *@date 2020/11/5
     *@desc  freemarker数据填充适用于pdf
     *@param data, htmlTmp WEB-INF/eleBillTemplate
     *@return java.lang.String
    **/
    public static String freeMarkerRender(Map<String, Object> data, String templateFile) throws Exception{
        Writer out =new StringWriter();
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate(templateFile,"UTF-8");
            // 合并数据模型与模板,将合并后的数据和模板写入到流中,这里使用的字符流
            template.process(data, out);
            out.flush();
            return out.toString();
        } catch (Exception e) {
            log.error("模板"+templateFile+"填充数据失败,原因是:"+e.getMessage());
            throw e;
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                log.error("模板"+templateFile+"填充数据失败,原因是:"+ex.getMessage());
                throw ex;
            }
        }
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc  freemarker数据填充,这一步可直接生成doc,image文件
     *@param data, htmlTmp
     *@return java.lang.String
     **/
    public static String freeMarkerRenderForWord(Map<String, Object> data, String templateFile,String name) {
        Writer out = null;
        File file = new File(name);
        try {
            out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate(templateFile,"UTF-8");
            // 合并数据模型与模板
            template.process(data, out); //将合并后的数据和模板写入到流中,这里使用的字符流
            out.flush();
            return out.toString();
        } catch (Exception e) {
            log.error("模板"+templateFile+"填充数据失败,原因是:"+e.getMessage());
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                log.error("模板"+templateFile+"填充数据失败,原因是:"+ex.getMessage());
            }
        }
        return null;
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc  pdf 生成工具类
     *@param content, dest
     *@return void
    **/
    public static void createPdf(String content,String fileName) throws Exception {
        ITextRenderer renderer = new ITextRenderer();
        ITextFontResolver fontResolver = renderer.getFontResolver();
        fontResolver.addFont(getResouseAblovePath(Constants.PDF_CREATE_AND_SIGN.PDF_CREATE_FILE_FONT),BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
        renderer.setDocumentFromString(content);

        renderer.layout();
        renderer.createPDF(new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName));
        renderer.finishPDF();
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc image图片文件生成
     *@param content, dest
     *@return void
    **/
    public static void createImage(String content,String tempFilePath) throws Exception{
        File f = new File(tempFilePath);
        Java2DRenderer renderer = new Java2DRenderer(f,1000,1200);
        BufferedImage image = renderer.getImage();
        FSImageWriter imageWriter = new FSImageWriter();
        imageWriter.setWriteCompressionQuality(0.9f);
        imageWriter.write(image,tempFilePath);
    }
    /**
     *@author lxw
     *@date 2020/7/1
     *@desc 二维码生成器
     *@param content
     *@return byte[]
     **/
    public static byte[] qrcImgCreate(String content) throws Exception {
        //中文乱码问题
        byte[] imgData;
        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            //中文乱码
            Hashtable hints = new Hashtable();
            hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
            hints.put(EncodeHintType.MARGIN,1);
            BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 40, 40,hints);
            ByteArrayOutputStream qrcImgByteStram = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(encode,"PNG",qrcImgByteStram);
            imgData = qrcImgByteStram.toByteArray();
        } catch (WriterException e) {
            log.error("生成二维码失败,原因是:{}",e.getMessage());
            throw  new RuntimeException("生成二维码失败失败!");
        } catch (IOException e) {
            log.error("生成二维码失败,原因是:{}",e.getMessage());
            throw  new RuntimeException("生成二维码失败失败!");
        }
        return imgData;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc 交易码路由模板文件
     *@param txnTypeCode, reqData
     *@return void
    **/
    public static void txnCodeToTemplate(String txnTypeCode,Map<String,Object> reqData) throws Exception{
        switch (txnTypeCode){
            case "2001805"://城乡居民-养老
//                req2001805Hander(reqData);
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "2001823"://城乡居民-医疗
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "2001824"://灵活就业-养老
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "2001825"://灵活就业-医疗
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "201401"://预售基金
                reqData.put("templateName","ZNZJJFTemplate.html");
                break;
            case "201303"://维修基金
                reqData.put("templateName","ZNZJJFTemplate.html");
                break;
            case "201503"://水费缴费
//                req201503Hander(reqData);
                reqData.put("templateName","ZNSFJFTemplate.html");
                break;
            case "200907": //广电缴费
//                req200907Hander(reqData);
                reqData.put("templateName","ZNGDJFTemplate.html");
                break;
            case "200707": //电费缴费(兴义)
                reqData.put("templateName","ZNDFJFTemplate.html");
                break;
            case "200702": //电费缴费(全省-兴义)包含 撤销
                reqData.put("templateName","ZNDFJFTemplate.html");
                break;
            case "2006041": //欠款还款
//                req2006041Hander(reqData);
                reqData.put("templateName","DKHKTemplate.html");
                break;
            case "2006042": //提前还本
                reqData.put("templateName","XDTQHBTemplate.html");
                break;
            case "2006044": //结清贷款
//                req22006044Hander(reqData);
                reqData.put("templateName","XDTQHBTemplate.html");
                break;
            case "200504": //短信签约变更(签约、解约、变更)
//                req200504Hander(reqData);
                reqData.put("templateName","ZNDXQYTemplate.html");
                break;
            case "200401": //助农取款
                reqData.put("templateName","ZNWDMTemplate.html");
                break;
            case "200402": //助农转账
//                req200402Hander(reqData);
                reqData.put("templateName","ZNTRANTemplate.html");
                break;
            case "200705": //电费预缴费(全省)
                reqData.put("templateName","ZNDFJFTemplate.html");
                break;
            case "200703": //电费缴费撤销(全省)
                reqData.put("templateName","ZNDFJFCXTemplate.html");
                break;
            case "200708": //电费缴费撤销(兴义)
                reqData.put("templateName","ZNDFJFCXTemplate.html");
                break;
            case "201603": //定期转出
//                req2016031Hander(reqData);
                reqData.put("templateName","CCTDQZCTemplate.html");
                break;
            case "201602": //活期转存
                reqData.put("templateName","CCTHQZCTemplate.html");
                break;
            default:
                throw new Exception("未找到对应的小票模板信息");
        }
    }
    private static String split3(Object o){
        if (StringUtils.isBlank((String) o)){
            return "0.00";
        }
        BigDecimal var0 = new BigDecimal(oTs(o));
        return DECIMAL_FORMAT.format(var0);
    }

    public static String oTs(Object o){
        if (StringUtils.isBlank((String)o)){
            return "0";
        }
        if (o instanceof String){
            return  new BigDecimal(o.toString()).toPlainString();
        }
        if (o instanceof Number){
            return o.toString();
        }
        return "0";
    }

    /**
     *@author lxw
     *@date 2020/11/23
     *@desc  判断金额是否为全数字(包含小数)
     *@param amt
     *@return boolean
    **/
    public static boolean numberHandler(String amt){
        Pattern pattern = Pattern.compile("([0-9]\\d*\\.?\\d*)|(0\\.\\d*[0-9])");
        Matcher matcher = pattern.matcher(amt);
        return matcher.matches();

    }

   /* public static void main(String[] args) {
//        String s = "384.09六";
//        BigDecimal bqyeAmt = AmountUtils.divideCentToYuan("0");
        boolean b = numberHandler("0");
        System.out.println( b);
    }*/

  public static String getResouseAblovePath(String relatePath) {
      //本地代码调试需要截取-服务器上需要去掉
//      return ElecBillCreateUtils.class.getClassLoader().getResource(relatePath).getPath().substring(1);
      return ElecBillCreateUtils.class.getClassLoader().getResource(relatePath).getPath();
  }

  public static void jbigTojpg(byte[] imageData,String path,String fileName) throws Exception{
      File file = new File(path+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JBIG);
      FileOutputStream fos= null;
      try {
          fos = new FileOutputStream(file);
          fos.write(imageData);
          fos.flush();
          JBIG.jbg2bmp(path+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JBIG,path+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_BMP);
      }catch (Exception e){
          log.error("图片解析处理异常=====>{}",e.getMessage());
          throw new Exception(e);
      }finally {
          try {
              fos.close();
              if (file.exists()){
                  file.delete();
              }
          } catch (IOException e) {
              log.error("处理异常=====>{}",e.getMessage());
              throw new Exception(e);
          }
      }
  }
  /**
   *@author lxw
   *@date 2021/1/6
   *@desc 十六进制字符串转字节
   *@param hexString
   *@return byte[]
  **/
    public static byte[] hexToByte(String hexString){

      int m,n =0;
      int byteLen = hexString.length()/2;
      byte[]  ret = new byte[byteLen];
      for (int i =0;i<byteLen;i++){
          m = i*2+1;
          n=m+1;
          int intVal = Integer.decode("0x"+hexString.substring(i*2,m)+hexString.substring(m,n));
          ret[i] = Byte.valueOf((byte)intVal);
      }
      return ret;
    }
    /**
     *@author lxw
     *@date 2021/1/6
     *@desc 图片转换
     *@return void
     **/
    public static void bpmCoverJpeg(String path,String fileName) throws Exception{
        File  file = new File(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_BMP);
        try {
            Image img = ImageIO.read(file);
            BufferedImage tag = new BufferedImage(((BufferedImage) img).getWidth(null),((BufferedImage) img).getHeight(null),BufferedImage.TYPE_INT_RGB);
            tag.getGraphics().drawImage(img.getScaledInstance(((BufferedImage) img).getWidth(null),((BufferedImage) img).getHeight(null),Image.SCALE_SMOOTH),0,0,null);
            FileOutputStream out = new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG);
            /*JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(tag);*/
            ImageIO.write(tag,"jpg",out);
            out.close();
        } catch (IOException e) {
           log.error("图片转换异常======>{}",e.getMessage());
           throw new RuntimeException(e);
        } finally {
            if (file.exists()){
                file.delete();
            }
        }
    }
}

测试类

package pdfDemo;

import static org.junit.Assert.assertTrue;


import org.junit.Test;
import pdfDemo.bean.PdfDto;
import pdfDemo.bean.SFJFPdfDto;
import pdfDemo.bean.pdfValue;
import pdfDemo.service.Constants;
import pdfDemo.service.CreatePdfServiceImpl;
import pdfDemo.service.ElecBillCreateUtils;

import java.lang.reflect.Field;
import java.util.Arrays;

/**
 * Unit test for simple App.
 */
public class AppTest 
{
    /**
     * Rigorous Test :-)
     */
    @Test
    public void shouldAnswerWithTrue()
    {
        assertTrue( true );
    }

    /**
     * 测试图片数据生成jpg图片
     * @throws Exception
     */
    @Test
    public void imgCreateOrViewTest() throws Exception{
        //测试图片数据转换成图片
        String imageData ="00020100000006560000018c000000020800031cff02ff02ff02e9efbf0bff021e70ff02557cf2ff027efaf810ff02862e30bcb067b0ff027d61f1c8e025e0ff02988553d2d6c1f518d53639c0ff0216f5a1fcebc641fc888655c42e6f3d0462e318ff02c49be605fcf8d45a66a918a4a1dfc837158a7f15a371f7880c5dbd5427e3c87813a0ff026309cb5f02953e10c9c4122f0c927321bb58656a12ed5fa56663a6f3a9fd174cff02ab302ee3a6dc3a9e76a241d76ec7a3fcc59f8e46b1906a7c004a35bbd55a58ef40ff0230b934208323d5d5a70303cc0a49cda96f5db775506b3ab7dd49376127076de5ff0264ecf0928ceb7672c5ae1441a9aa2c3bdff0aba3bb2882e73bef87d4492abb9c03d0ff025c367d3618505f9632e87fe6a16e631c8ca30d9b1b65b524147140ff0273b84ef9632c5ce6cbb4bd35890830a61510d2a205e5fcf1f4ff02511d28fc76b6190aa189c061557af17bde6c8941bbcbbf8aa255f7ff025a123662c71d9f10b037466092fd338fb73c93fdcd030b1d1be2ff02c1518d4627b724dc6b39638572f94fb5f9abd01b2ca17ccb80ff0246a48ea96bbb2b650f66d885f86e8458e602ae1ef82b2cedee8b005eeb449428ff024d2caea756b0c73417c1d1044773ef81e55aa3d8413fe14327552919e86dfb671eb4cc420a20ff024e16c891609a7b7625085a4960d03eef28ce019beac86613a119d81f6c86ff029094edbf3d8d1006b5d2f403c615f259884788c09c0e8e5d7fa7dc1ec80f28ff028391a866e99e941b3840be6134078e4b4508e35a09aaa39aa0ff02dbf3a6cc698f32ddfcde5db60a26737e3ce00da7174e495daf92b0ff0209bd9b8c2d6ab430f2f3b75802e5d444aca832b2d7130c00a347e41bb7fd5f28ff027c4ff793c4f301fd34dfded06402a822bf862500b72402d9038ba24758dea50810ff0204de4b7f19c4292fea31b891deb3c446df99c3d8322a4564ff027e8ed1e601c9fa53703b1c16e2a637b56be9dbf4059c01c3afc3fdeb84576e8da3ab40ff022a1749b944c3f6eeb409052c723a2c116aa6f0316c7bc06cf373aaff024b7d86eb64cde2c91f45585e6d4e2b0258291819e10dd38f5d6c80ff024b01e424b2ac1294112bd3eff120c77c44226202ce9f76b163678b9fa988ff025197fe5b6ba189ba1142092a0ac9fe8150c5eaed7afeff0259bc5bbfb24f34f1a79c402aaeff0210765cc5c0c9fb2e6679d75c02f0d5a180ff029cac460c496054641b6b6c7b8a51851cff02551d7ab98e46f269fac585e3e341ff02634cc8e13acb108fa10ff3b4ff02bd5a929e5067cd061c1ecddc56b8ff0222bc9a1e14ca3e985d72976080e0f8ff028f5b789afadd520cab890c7d68ff02cd4ae84089ff02937320ff02d7ff02ff02ff02ff02ff0280ff02ff02c3f2c168ff025d2097a0ff02598aa0ff02850439bdff02691d6c07cc12e7c0ff020beff58298cd73e99316ff025e9351a90d0920491922be2fc0ff029ca329dae08b19246890ad200b8c3aedbe3d5877a4ff025c409d2d18c6aac7574ec4e6181f0da7cc00e97063646f1a44977fe85a73cc590e9c72d319b2c94c98aac4ff026a91cb9f3d3c4577213e0d576533fa5a07ef222fef0c981943fc3c39cadab203e975e5b5457053d10040c64da910145b6ab9dd8f7605e9c937ff026091d1abcd0e085c7d8f08948d01866c8d6162f77b69009fcdcb7f4242259909aaa808600e73343bbe274ae330e58cb53ccd30895880ff022bb15980affb8a43f58ab7b007d535e462fdc2e55612a779687283ebb07491d2087045d8b0a798583832188f8b43d283bf23beea0344c7230cff02e1aa58cfdf1ed79d4f01c28c3ca43162fb596089e8122f46e9e3a8322feabc03509844f361d6b74eb16d520ad97cd4ae3f2971400f3b3713fc82f8ff024bee2a5cb707487f0888ac6cd2ef385975fe9d340bd790fe119a22f409cfde406e6049a9163e8f19acb6dd2299b78b973dff024afcc9137c2a95fd510bc7fca16e19a34af1889adb6cc2cfbc0e38643cf7b7119398100f2846c1aa7fb0ff024f1dd3564f7e238b55c7e01b696afb1958112a6a8d75e41daa9c634b55f666d8001f147ed016afe0ff02134521d2befe186841b4a6bc654d0df4a39cefab1bb3a50a3a722e0b7f25b99ca3ecf7ba5da8da669f6cccff02128f8779d49954ff0030e42104302c4be063c8ee115c1f13b205cafa4786169dbbf8fd53fb426cc86a6804ff02188411a9a962be09d6faf4b98d19b28557fe554969fb9dc1d15c74f4e6d583ec67772bd2efff020b3707a2f8a3aeab541dde39f8b54a047b5b9b1711ecc14f41b752de18cc8ace35d9eb4b81f83875e0db464ebe80ff0284244a1f6c3f5262369aaca88b8693122f7ea793e518d23e90656bfc76c68cde0bfb1f1edace177216f12a58e808a7e4ff02377c65a38b12a3ab4e19cc3134455c2d9f143ec6b99b454015311f5e56f9139e3a720387ef75fba607130f0ec1ba5eaf60eb84ff021f55495f6159e960cb337f44f707ef2b4b018e24db9699fac19eb329e8adbb452c44d081c05b9b8eac40ff023f2a8d38779f16099ef10cd015ba0f4abf7521f215a49ac305815f759d1e68c7cc33c776aa729cc3d7602ca6c5ba5778ff02cbfc9f609256c5fdeeded52c7fc4b92d8e18d45bf9c96d155d4efbea7be0553af0478dc04768a6dea21a5510ff0287378e076b01350bcd281acd93fe8a28a69ff7440cb7fc0f3bd2d43617bb2ee9e571fbdba7cb485ee579c73ced3c8fff02d92a2f890cdaa00afcb65c4419dc3c2d97d62b33a242718f48ff00a2c2487473e7990631326226c6747f274fa5d0b6a71f045b2be11c91f9cbc070ff0298c802325f04565324f020290476bb46e1a2d6bb9319536d4e41ba4d68ae54bc10f9252e5053998cca1b80ff024b539b9236f91fdd10627ad9f77b5f9dd74f44c2f9addb2578730f6e91c4ba8b6f9f1fc8c752d9687a122c2213b387a054c810425ae40250d140ff02198222e7ca3985da2e3d75e41af80fba430a529258a09021a01ba6fc37b3d73fac47056d524cf7d48af9b927f69320ff020963a54a9ae6de723eeb2aff00e93421c1c3e599ca131ea5d9c0b4582e13d60d4b48723a03cfdda6aae79aff022655f7e751a19acd4f4917695f6b2ba77417c7e0f0b0c7a40dcb74f326363c5f6c39396d49cbc695adefb70f6be0ff020f65ab7da7134b8570508dd008c5ac366396393370c2a807c051d651608156ff027544721b6933621d8e8fbd3be55d97d056c2a833eb8c380a80ff022aa031305736d65d6b64eb10c569c8d4452768299d59a431e930ff026f67d3e8c63980aa22a9baa7b6ae8f4f84d8b1810581f868ff02275d4bec8a3edf5724010c9f40c321a811a2cb03ff024d176c5fcbf4523912c2db88586fed8d51c9e219ff028d449599be56448438c0de592d2545feec692a2481cae32f09813b2a38ff020fb0dbc9a9b94b0956406da5cd8d595e06670263fd663463b09aa0ff0206c99c509803b59bd548c5b7d0fefcad714f14ff0276243b6033a658ff024a3cff02ff02ff02ff02ff02ff0280ff02ff0218d9ff026e1e617460a126ff02012106e1a680ff02112af812576a80ff021b9ce5f1b786f2ac2d50f63a60ff02017de51471fc7dbd118083e4946506ff027ff276578a2021f895cb1bff0033a49b9cd6ff02cdfb940495c6927368e03f471eb7a0743524d39658f1e4e9584cfc27caa0b5ff021d7d4cdcf1edcaa115a0e2cecf15d67c6df51836c9e78e7617ce6ad6ebda759c792668237b6f9aebb37b856d3ba8f766c2ac5e5cf75ac683dc4ae21c0a8c4a4d31e54fe5476ee8845560ff02eccfa8cddd3b970267c5a98b02d5a8f13f24f6d85d2e393f060a80d79b66a9d996b710c3d90a694f81a8862c132cd0c085d31f77599a4a2694ad37c9a5ec9d51f8f620282ff45af919ee6b77793e4072e1f0d3901ed692f91a80ff022870616804302838aa8d10d388eca464da8e269350dff10458ece1347cc785540b2da891756b36aee0a02e7b1ade2a00f3e81632c780f266e0cf64ca5b02913c15b069f9875a79513ff0dd37e166bd5e7b67d543a0ff02c4cadd00dc62de31a2444a611b705253973796ee5cd1d61cb0e19be24b18fe068656717aa0370bc90f9deb2b4bc187b4eb3aac6166199d3ad6531a82ef1ff0114f551afafd1d00a831ab4c806f0e64bf6a824ec18a924f40ff020361446a02ce87b456e2ae57cba22c64a38c27730dbefdca6ce39c4b2d4728f000572e09e2bb1d876b35b40637902f24bf0f4d34a2288c191bef4d264f7d9497fdd1c946e2e749de3b8c9edc1613ef8eff00808f88600f0b2d786af71d90ff026cc1d1aa7ae3cd863efefb11d53264f128975141d5dfa4aec3bac15d48f638b14d952707821e856ce2df9fd909238d5c4661a401269f193f74afe628217dd59401f3ca73c8045f8735060aa96050ff02f7b1ad5e7ecbea3d3266e0ae897fbd8ff34d1edc37440eb29a8251068d803f43b7f6b7eae5cf8c0b1d7069517c757ec110ae02effb9929e5aba315f198317c21958543cc2dc9c0ff0226a02904faa9d80ca2454c9e9e97212c7e8e422d6ca7c537c347641d3b81bc38e811bde4392f8b90ef8c4bc204bbd1885243d8931801e270b0a5100288839db102f9a878f304726dae8580ff02531529bf160b7f6dda8b087a1ea80e82a2ed1c3566804c0343ca68052d31ff00b33c6fedf379b2b5df9f1bacfda414288eba0850798b592c8ec49c20ac4fdfafa798497d56d3f01f349a488d07b8c54fecadd0ff02174a6e5d7b8e82be88819f25e944b20fd7fc47a5e67a5d1ed6f9056c86c46146826c26964f42c25b13df0ee600950ebd45056ed959bf8136811065227193b3becd501cae3a8b50246366c1ebf0332d004d7664ff02898023aacc48928c885f76d0d1a89bf9d0cfc2eddaa55c03ead06f7a406293cb78e014f4577da9ccacc13e12a1e7fb0f0fa64da1c917df9cdd122a2c87c8a62b80ff0229782d208855baf90d7efd377af4e9b17fe4fed608d6ac8566830026c551dbcaaaecafc85e9f25e63b9ea37ff4a8de4ff09d7482d668a1e3a049f1f0aaee5fc3bca31a9b5697ff026b60f5bad5dbd868e35c8c478301026e6601d9eff8a2f8bb3afc60f874d3cf714f8c0829e94e3815e62150db7b6072cd7f9a0aa4c294281d53dadc1c7d3875fe48ff026e74886871516ff7b28cb2fb8a20c03504c03882e83d0eb1f53880ce7aa76c92fd45edcd3090075b3b111a8b8fa5d26249a4e6a02b724dec5b693d4fa72217230893966f29c94b2b1071daeaac973efa0daa20ff0291b44b9307ca5d3a023a2fca1d798f113a15746532e14eaf7c517abacdfbc8af0a5b9e235e79cfe33eef116db3d384b62bd88d9f861eb01f813fcb60e7e2e550810e9f16c4df1836a18b21be80ff02b3ccac6aa3fcbf9f86c72a68f94dba09e10a2c9b71bf534b83c44e7933e8c9b50494cab89567f7d42b92f0b51dcc16b524946420d283fca79415057744b8ff024a6b416164eeb4fd2e4e6f008e2806f45734c3d910ab6124a72036cca9ec0664bcb33825830b565a3ccd8b928665a6db37d5dbed47296d4fbcdfa5156ca19c25ff0251522cde186e8b3fc7053d005cc64c7edcc8369342e01e76b115f7b3d0547f1df3cdc1974f8d48a3cc65fc9b830ad99a8cf0ff00770bdc6f7b14efd756b4a21df0afe0a2ff027a1f7832d269a5c5749e71edb043429be7441908f6303481658314e23a7d0b51b89f4d4895bf13d99e5bd47fdde8aed51333c0f8c5d25e6748227da25306ef460a5728744957a5ef3364ad0376965516f13193fe036ead84f06b2e1e96b1ff02e9f4604cc796d47608b08013fde2b7cc8239b237b7de42669b2be932ec8047809bfc0eaca0c7d0f8f4dee86a53e9167e824124fe080bb77d396eeccbd32fdacd407f3779ff0226724fb9aab527f63b0d376010206126e4dbe07657f11f094474ae59dd8b3dc34fb710e97a968205e60efe54b719624b4ba69a504bcd0c1889a2b658252f92aeccd72087a0ca7deae35f12f435f7186a5294b01f6b1220f9bd1cb0d53f4c1506ecce36a41f9520ff0273b42eff0067a67d6fdf37381905505e6e1aa43daa90552a5e744e17a5b453edbf7d581faa2d9efe9e68fa054b4ae52091b411182994c40950fc0c8b0f51fdf763290b49bb65245cc337eacc82ff021b1c180c13e7dc9323fb4330610c0348b48a09821e02db6ea33c48085249f39f6c4039551e298c4950800e4c09b247bcde05b58513c418cdd70436c8dfd42882125f39b3485210715ee69b50182fff022a3b97842fa40b5cb9471e7deaa32671f5cbdee74314d83cfb9af7ae4c5839c634c217daa12ec57e185bb58937f9d5099ce0de1e5a46556f8bb0911e47cef6d69f33bd979d8ac0ff0205779cb46d589e6a9c57252aa7140f1dfd968e3ab49be4a7b58699e7941f47feb1f2b329e919e9f5c9bbd04edd4b2507b450ff0270e9a0204e241835a54f3b2874fabb7fd713c34e77723a95ac4366749b1edd6e847426310c3dcc6bc16c96bf68ff025dc13b5e3efefac68f835463d53e8c12b07c01323f40c57f2d47ec7d45c7772be2686330d231d916a420ff0277dcf1c6069528a66ed2e1d3040bc7449b11e7afbb7d0205dbbfd37922b72670598c8799c6961132cc40ff02b1aaa2ea28500cb24089199b6757c196ee0e1faf6d1d5cb9b3c0031d91bdbefee7f0a980ff024db7732ddfbe7320849d0e20bf930a60837af776cebff6e9780888ca818f5e419300feff02c0d511f2343e1d14cbcd86b2655699b937943b9c8be640000491c19fb7dcd5762978ff0002634eacdba4ff00bda577890e261d8780ff02195526190f0fbb0831a804bb79ff005a3171b77d75e18703a553c39aa4eb0c4f50aeb69356fbc905db0360bef48e193a1accd243c86154ff025a5962cba0a0244fe9281241915c2b8f8f5ad0812ced0f0c342bd2d26efcff028f79e7ef0e32b33db83c874648ff023baaff02ff02ff02ff02ff02ff02";
        //将十六进制的图片信息转换成字节数组
        byte[] hexToByte = ElecBillCreateUtils.hexToByte(imageData);
        //将字节数据转换成bmp图片
        ElecBillCreateUtils.jbigTojpg(hexToByte,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,"jpegImage");
        //将bmp 文件转换成jpg文件
        ElecBillCreateUtils.bpmCoverJpeg(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,"jpegImage");
    }

    /**
     * 测试 pdf 文件生成
     * @throws Exception
     */
    @Test
    public void pdfCreateOrViewTest() throws Exception{
        CreatePdfServiceImpl.PdfCreateHandler(null);
    }


}

测试结果:

生成图片

生成pdf信息

4.本文是在已经搭建好的项目中进行开发,本文内容不涉及springmvc工程搭建内容。本文主要工作是使用freemarker技术生成电子小票,重点是生成小票和对生成小票中图片处理。生成的小票格式pdf.

 因为用户使用pos机和村村通设备进行电子手写签名(用户在屏幕签名,设备保存签名为一个图片),村村通设备和pos机生成的签名分辨率比较高,图片大小比较大(一般200-300k),每个月的交易量大概400-500万笔。所以占用的空间特别大(每个月大概在800G左右),特别的浪费空间。现在对这个图片进行处理,前端对签名的图片进行压缩,使用的是jbig压缩算法进行压缩(不知道的可以百度查询下这个算法,压缩图片画面失真率很小),然后将压缩后的数据传给后端,压缩后的文件大小只有2-4k大小左右(压缩率在100-130倍),后端接受到压缩后的土图片信息,直接写成一个txt文件保存图片信息,然后上传到服务器。这样就可以大大节省了服务器的资源。ps:压缩后的图片信息,其实可以通过对图片信息的压缩还可以存储到库中,这个有兴趣的可以试下,是否可行(具体方法就是,将图片信息读成字符串,然后对字符串进行压缩处理减少字符串的长度,然后保存到库中)。

4.1 本业务代码调用流程

5.代码片段

5.1 入口

package com.ruim.ifsp.merser.controller;

import com.ruim.ifsp.dubbo.annotation.SOA;
import com.ruim.ifsp.log.LogLevel;
import com.ruim.ifsp.log.annotation.Explain;
import com.ruim.ifsp.merser.bean.request.MchtPdfViewRequest;
import com.ruim.ifsp.merser.bean.request.MchtPfdOprRequest;
import com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse;
import com.ruim.ifsp.merser.common.Constants;
import com.ruim.ifsp.merser.service.CreatePdfService;
import com.ruim.ifsp.valid.annotation.IfspValid;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @ClassName MchtPdfCreateController
 * @Description pdf生成,加签和上传
 * @Author lxw
 * @Date 2020/6/30 10:19
 **/
@Controller
public class MchtPdfCreateController {

    @Resource
    private CreatePdfService createPdfService;

    @SOA(Constants.SYS_NO_LOCAL + Constants.CONT_POINT + Constants.TXN_CODE.MCHT_PDF_INFO_SAVE)
    @Explain(name = "PDF文件信息存储", logLv = LogLevel.INFO)
    public MchtPfdOprResponse savePdfInfoCtrl(@IfspValid MchtPfdOprRequest request) throws Exception{
        MchtPfdOprResponse response = new MchtPfdOprResponse();
        response =createPdfService.savePdfInfo(request);
        return response;

    }
    @SOA(Constants.SYS_NO_LOCAL + Constants.CONT_POINT + Constants.TXN_CODE.MCHT_PDF_OPR)
    @Explain(name = "PDF文件预览和下载", logLv = LogLevel.INFO)
    public MchtPfdOprResponse createPdfCtrl(MchtPdfViewRequest request) throws Exception{
        MchtPfdOprResponse response = new MchtPfdOprResponse();
        response =createPdfService.createOrViewPdf(request);
        return response;
    }
    //文件下载和预览。实际调用这个接口
    @ResponseBody
    @RequestMapping("/viewOrCreted")
    public void viewAndCreatePdf(HttpServletRequest request,HttpServletResponse response){
        createPdfService.viewOrCreated(response,request);

    }
}

5.2service和dao,mapper.xml,DTO 等文件信息

package com.ruim.ifsp.merser.service;

import cn.com.infosec.netsign.agent.NetSignResult;
import com.ruim.ifsp.merser.bean.request.MchtPdfViewRequest;
import com.ruim.ifsp.merser.bean.request.MchtPfdOprRequest;
import com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @ClassName CreatePdfService
 * @Description
 * @Author Administrator
 * @Date 2020/6/23 10:21
 **/
public interface CreatePdfService {

//    public void pdfHandler(PbsEleInvoiceInfo pbsEleInvoiceInfo) throws Exception;
    /**
     *@author lxw
     *@date 2020/6/24
     *@desc 签名
     *@param []
     *@return void
    **/
    public NetSignResult pafFileSign(String fileName) throws Exception;

//    public void getOpPbsEleInvoiceInfo(PbsEleInvoiceInfo info) throws Exception;
    public MchtPfdOprResponse savePdfInfo(MchtPfdOprRequest request) throws Exception;

//    public MchtPfdOprResponse createPdfHandler(MchtPdfViewRequest request) throws Exception;

    public MchtPfdOprResponse createOrViewPdf(MchtPdfViewRequest request) throws Exception;

    public void viewOrCreated(HttpServletResponse response, HttpServletRequest request);
}
package com.ruim.ifsp.merser.service.impl;

import cn.com.infosec.netsign.agent.NetSignAgent;
import cn.com.infosec.netsign.agent.NetSignResult;
import cn.com.infosec.netsign.agent.exception.NetSignAgentException;
import cn.com.infosec.netsign.agent.exception.ServerProcessException;
import cn.com.infosec.netsign.base.PDFParameters;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.Style;
import com.itextpdf.layout.border.Border;
import com.itextpdf.layout.border.DashedBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.TextAlignment;
import com.ruim.ifsp.exception.BizException;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.bean.dto.*;
import com.ruim.ifsp.merser.bean.request.MchtPdfViewRequest;
import com.ruim.ifsp.merser.bean.request.MchtPfdOprRequest;
import com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse;
import com.ruim.ifsp.merser.common.AmountUtils;
import com.ruim.ifsp.merser.common.Constants;
import com.ruim.ifsp.merser.common.ElecBillCreateUtils;
import com.ruim.ifsp.merser.dao.PbsEleInvoiceInfoDao;
import com.ruim.ifsp.merser.dao.PbsZnorderTicketDao;
import com.ruim.ifsp.merser.service.CreatePdfService;
import com.ruim.ifsp.merser.util.PDFUploadUti;
import com.ruim.ifsp.paysupport.message.pay.resp.IfspRespCode;
import com.ruim.ifsp.utils.datetime.IfspDateTime;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import com.ruim.ifsp.utils.verify.IfspDataVerifyUtil;
import org.slf4j.Logger;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @ClassName CreatePdfServiceImpl
 * @Description
 * @Author Administrator
 * @Date 2020/6/23 10:23
 **/
@Service("createPdfService")
public class CreatePdfServiceImpl implements CreatePdfService {
    @Resource
    private PbsEleInvoiceInfoDao pbsEleInvoiceInfoDao;
    @Resource
    private PbsZnorderTicketDao pbsZnorderTicketDao;
    @Resource
    private CreatePdfService createPdfService;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    private static Logger log = IfspLoggerFactory.getLogger(CreatePdfServiceImpl.class);

//    @Override
//    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = {Exception.class})
//    public void pdfHandler(PbsEleInvoiceInfo pbsEleInvoiceInfo) throws Exception{
        Map<String, Map<String, Object>> stringMap = reqDataConvet(pbsEleInvoiceInfo.getEnvoiceInfo());
        Map<String,String> reqMap = (Map<String, String>) IfspFastJsonUtil.jsonTOmap(pbsEleInvoiceInfo.getEnvoiceInfo());
//        pbsEleInvoiceInfo.setUpdateTime(IfspDateTime.getYYYYMMDDHHMMSS());
        String name = createFileName(pbsEleInvoiceInfo.getTxnOrderId());
//        try {
//            //判断生成pdf是否成功
//            if (freeMarkCreateFile(pbsEleInvoiceInfo)){
//               //判断pdf签名是否成功 -否
//                NetSignResult netSignResult = pafFileSign(createFileName(pbsEleInvoiceInfo.getTxnOrderId()));
//                if (IfspDataVerifyUtil.isBlank(netSignResult)){
//                    pbsEleInvoiceInfo.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
//                    pbsEleInvoiceInfo.setRemark("文件签名失败");
//               }else {//成功
//                   //上传pdf文件
//                   String fileName = PDFUploadUti.sendImage(netSignResult.getByteArrayResult(NetSignResult.SIGN_TEXT), createFileName(pbsEleInvoiceInfo.getTxnOrderId()));
//                   if (IfspDataVerifyUtil.isNotBlank(fileName)){
//                       pbsEleInvoiceInfo.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0);
//                       pbsEleInvoiceInfo.setDownloadUri(fileName);
//                   }else {
//                       pbsEleInvoiceInfo.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
//                       pbsEleInvoiceInfo.setRemark("文件上传失败!");
//                   }
//               }
//           }else {//pdf生成失败
//                pbsEleInvoiceInfo.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
//           }
//        } catch (Exception e) {
//            log.error("电子发票生成失败!原因:{}",e.getMessage());
//            pbsEleInvoiceInfo.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
//            if(IfspDataVerifyUtil.isNotBlank(e.getMessage())){
//                if (e.getMessage().length()>=999){
//                    pbsEleInvoiceInfo.setRemark(e.getMessage().substring(0,999));
//                }else {
//                    pbsEleInvoiceInfo.setRemark(e.getMessage());
//                }
//            }else {
//                pbsEleInvoiceInfo.setRemark("订单:"+pbsEleInvoiceInfo.getTxnOrderId()+"电子发票生成失败");
//            }
//        }finally {
//            checkFIleExit(createFileName(pbsEleInvoiceInfo.getTxnOrderId()),Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
//           if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0.equals(pbsEleInvoiceInfo.getPdfStatus())){
//               pbsEleInvoiceInfoDao.deleteByPrimaryKey(pbsEleInvoiceInfo.getTxnOrderId());
//               PbsZnorderTicket pbsZnorderTicket = new PbsZnorderTicket();
//               BeanUtils.copyProperties(pbsEleInvoiceInfo,pbsZnorderTicket);
//               if (IfspDataVerifyUtil.isNotBlank(pbsZnorderTicketDao.selectByPrimaryKey(pbsZnorderTicket.getTxnOrderId()))){
//                   pbsZnorderTicketDao.updateByPrimaryKey(pbsZnorderTicket);
//               }else{
//                   pbsZnorderTicketDao.insertSelectiveTmp(pbsZnorderTicket);
//               }
//           }else {
//               Integer valueOf = Integer.valueOf(pbsEleInvoiceInfo.getPrintNum());
//               valueOf++;
//               pbsEleInvoiceInfo.setPrintNum(valueOf.toString());
//               log.info("更新数据。。。{}",IfspFastJsonUtil.objectTomap(pbsEleInvoiceInfo));
//               pbsEleInvoiceInfoDao.updateByPrimaryKeySelective(pbsEleInvoiceInfo);
//           }
//        }
//    }
    /**
     *@author lxw
     *@date 2020/6/24
     *@desc pdf文件生成方法-支持不同的模板
     *@param maps, calzz
     *@return boolean
    **/
    public <T> boolean createPdfFile( Map<String, Map<String, Object>> maps,String fileName){
        PdfWriter pdfWriter;
        PdfDocument pdfDocument;
        Document document;
        PdfFont font;
        try{
            pdfWriter = new PdfWriter(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
            pdfDocument = new PdfDocument(pdfWriter);
            font = getChineseFont();
            document = new Document(pdfDocument).setFont(font);
            Table table = createTable();
            table=orderFiles(maps,font,table);
            document.add(table);
            document.close();
            return true;
        }catch(Exception e){
            log.error("pdf文件生成失败,原因是:{}",e.getMessage());
            return false;
        }
    }
    /**
     * 获取父类中的字段
     * @return
     */
    public static Field[] getFatherClassField(){
        return PdfComHeadDto.class.getDeclaredFields();
    }

    /**
     * 获取子类中的字段
     * @param Clazz
     * @return
     */
    public <T> Field[] getChildClassField(Class<T> Clazz){
        return Clazz.getDeclaredFields();
    }

    /**
     * 合并字段
     * @param a
     * @param b
     * @return
     */
    public static Field[] getAllFields(Field[] a,Field[] b){
        //将a中的值复制到fields中,并指定长度为 a,b相加的长度
        Field[] fields = Arrays.copyOf(a, a.length + b.length);
        //将b中的数据复制到fields中--从b数组中的第一个开始复制,fields 从a长度的地方接着复制,复制b的长度结束
        System.arraycopy(b,0,fields,a.length,b.length);
        return fields;
    }

    /**
     * 设置字体
     * @return
     *
     */
    public PdfFont getChineseFont() throws Exception{
        PdfFont font;
        try {
            font = PdfFontFactory.createFont(Constants.PDF_CREATE_AND_SIGN.PDF_CREATE_FILE_FONT, PdfEncodings.IDENTITY_H, false);
            return font;
        } catch (IOException e) {
          log.error("字体创建失败!原因是:{}",e.getMessage());
          throw new BizException(IfspRespCode.RESP_ERROR,"pdf文件生成-初始化字体失败!");
        }
    }
    /**
     * 设置上边框样式
     * @return
     */
    public static Style getTopStyle(){
        Border border = new DashedBorder(1);
        Style style = new Style();
        style.setBorderTop(border);
        return style;
    }
    /**
     * 设置下边框样式
     * @return
     */
    public static Style getBottomStyle(){
        Border border = new DashedBorder(1);
        Style style = new Style();
        style.setBorderBottom(border);
        return style;
    }

    /**
     * 创建没有边框的Cell
     * 没有内边距,字体大小8
     * @return
     */
    public Cell getCellNoBorder(){
        return new Cell().setFontSize(8).setPaddings(0,0,0,0).setBorder(Border.NO_BORDER);
    }

    /**
     * 获取上边框为虚线的cell
     * @return
     */
    public  Cell getCellDashedTopBorder(){
        return new Cell().addStyle(getTopStyle()).setPaddings(0,0,0,0).setBorder(Border.NO_BORDER).setFontSize(8);
    }
    /**
     * 获取下边框为虚线的cell
     * @return
     */
    public  Cell getCellDashedBottomBorder(){
        return new Cell().addStyle(getBottomStyle()).setPaddings(0,0,0,0).setBorder(Border.NO_BORDER).setFontSize(8);
    }
    /**
     *@author lxw
     *@date 2020/6/23
     *@desc 获取两个单元格合并的cell
     *@param
     *@return com.itextpdf.layout.element.Cell
    **/
    public Cell getTowMergeCells(){
        return new Cell(1,2).setFontSize(8).setPaddings(1,0,1,0).setBorder(Border.NO_BORDER);
    }
    /**
     *@author lxw
     *@date 2020/6/23
     *@desc 获取两个单元格合并并且上边框border 是虚线
     *@param
     *@return com.itextpdf.layout.element.Cell
    **/
    public Cell getTowTopDashedMergeCells(){
        return new Cell(1,2).addStyle(getTopStyle()).setPaddings(0,0,0,0).setFontSize(8).setBorder(Border.NO_BORDER);
    }
    /**
     *@author lxw
     *@date 2020/6/23
     *@desc 获取两个单元格合并并且上边框border 是虚线
     *@param
     *@return com.itextpdf.layout.element.Cell
     **/
    public Cell getTowBottomDashedMergeCells(){
        return new Cell(1,2).addStyle(getBottomStyle()).setPaddings(0,0,0,0).setFontSize(8).setBorder(Border.NO_BORDER);
    }
    /**
     *@author lxw
     *@date 2020/6/23
     *@desc 初始化图片信息
     *@param
     *@return com.itextpdf.layout.element.Image
    **/
    public Image initImage() throws Exception{
        try {
            return  new Image(ImageDataFactory.create(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_HEAD_IMG));
        } catch (MalformedURLException e) {
           log.error("初始化图片信息失败!原因:{}",e.getMessage());
           throw new BizException(IfspRespCode.RESP_ERROR,"pdf文件生成-初始化图片信息失败!");
        }
    }
    /**
     * 创建两列的表格
     * 设置宽度百分比100,设置四周外边距,添加头部图片,小票头部提示
     * @return
     */
    public  Table createTable() throws Exception{
        return new Table(2).
                setWidthPercent(100).
                setMargins(20,180,20,180).
                addCell(getTowMergeCells().add(initImage().setAutoScale(true)));
    }

    /**
     * 排序并生成指定样式的表格
     * @param
     * @param map
     * @param font
     * @param table
     */
    public  Table orderFiles(Map<String, Map<String, Object>> map, PdfFont font, Table table) throws Exception{

//        int count = 1;//计算索引使用
        //添加小票头部提示
//        table.addCell(getCellNoBorder().add("持卡人存根").setTextAlignment(TextAlignment.LEFT).setFont(font));
//        table.addCell(getCellNoBorder().add("请妥善保管").setTextAlignment(TextAlignment.RIGHT).setFont(font));
//        for (Field field : a) {
//            //如果map中不包含field字段,进行处理下个字段
//            if (!map.containsKey(field.getName())){
//                continue;
//            }
//            pdfValue annotation = field.getDeclaredAnnotation(pdfValue.class);
//            //保证数据顺序
//            if (annotation.order()>count){
//                count=count+(annotation.order()-count);
//            }
//            if (count==annotation.order()){
//                if (0==annotation.typeFile()){//常规
//                    table.addCell(getCellNoBorder().add(FieldRefName.getDesc(field.getName())).setFont(font));
//                    table.addCell(getCellNoBorder().add(IfspDataVerifyUtil.isBlank(map.get(field.getName()))?"":map.get(field.getName())).setFont(font).setTextAlignment(TextAlignment.RIGHT));
//                }else if (1==annotation.typeFile()){//虚线
//                    table.addCell(getCellDashedBorder().add(FieldRefName.getDesc(field.getName())).setFont(font));
//                    table.addCell(getCellDashedBorder().add(IfspDataVerifyUtil.isBlank(map.get(field.getName()))?"":map.get(field.getName())).setFont(font).setTextAlignment(TextAlignment.RIGHT));
//                }else if (2==annotation.typeFile()){//二维码图片
//                    Image img =null;
//                    if (IfspDataVerifyUtil.isNotBlank(map.get("imageData"))){
//                        img = new Image(ImageDataFactory.create(qrcImgCreate(map.get("imageData")))).setAutoScale(true).setMargins(0,40,0,40);
//                        table.addCell(getTowDashedMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
//                        table.addCell(getTowMergeCells().add("(商户可扫描此二维码进行交易查询和后续操作)").setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
//                    }
//                }else if (3==annotation.typeFile()){//签名图片
//                    Image img =null;
//                    table.addCell(getTowDashedMergeCells().add(FieldRefName.getDesc(field.getName())).setFont(font));
//                    if (IfspDataVerifyUtil.isNotBlank(map.get("signName"))){
//                        img = new Image(ImageDataFactory.create(downloadImage(map.get("signName")))).setAutoScale(true).setWidth(100).setHeight(30);
//                        table.addCell(getTowMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
//                    }
//                }else if (4==annotation.typeFile()){//换行
//                    table.addCell(getTowMergeCells().add(FieldRefName.getDesc(field.getName())).setFont(font));
//                    if(IfspDataVerifyUtil.isNotBlank(map.get(field.getName())))
//                    table.addCell(getTowMergeCells().add(IfspDataVerifyUtil.isBlank(map.get(field.getName()))?"":map.get(field.getName())).setFont(font));
//                }else if (5==annotation.typeFile()){//虚线换行
//                    table.addCell(getTowDashedMergeCells().add(FieldRefName.getDesc(field.getName())).setFont(font));
//                    if(IfspDataVerifyUtil.isNotBlank(map.get(field.getName())))
//                    table.addCell(getTowMergeCells().add(IfspDataVerifyUtil.isBlank(map.get(field.getName()))?"":map.get(field.getName())).setFont(font));
//                }else {
//                    throw new BizException(IfspRespCode.RESP_ERROR,"未知的单元格格式!");
//                }
//                count++;
//            }else {
//              throw new BizException(IfspRespCode.RESP_ERROR,"打印小票数据缺失,请检查数据中是否包含:"+field.getName()+"字段!");
//            }
//        }

//        table.addCell(getTowMergeCells().add("本人确认以上交易,同意将其记入本行卡账户").setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        for (int i = 1; i <= map.size(); i++) {
            Map<String, Object> reqMap = map.get(String.valueOf(i));
            if ("stub".equals(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_ID))){
                table = getHeadTable(font, table, reqMap);
            }else if ("mchtName".equals(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_ID))||"receiveBankName".equals(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_ID))||"cardNo".equals(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_ID))){
                table= getLineFeedTable(font,table,reqMap);
            }else if ("qrCode".equals(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_ID))){
                table = getQrcTable(font,table,reqMap);
            }else if ("signature".equals(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_ID))){
                table = getSignImgTable(font,table,reqMap);
            }else {
                table = getNormTable(font,table,reqMap);
            }
        }
        return table;
    }
    /**
     *@author lxw
     *@date 2020/7/9
     *@desc 顶部cell格式
     *@param font, table, reqMap
     *@return com.itextpdf.layout.element.Table
    **/
    Table getHeadTable(PdfFont font,Table table,Map<String,Object> reqMap){
        if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_TOPLINE)){
            table.addCell(getCellDashedTopBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setTextAlignment(TextAlignment.LEFT).setFont(font));
            table.addCell(getCellDashedTopBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setTextAlignment(TextAlignment.RIGHT).setFont(font));
        }else if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_BOTTOMLINE)){
            table.addCell(getCellDashedBottomBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setTextAlignment(TextAlignment.LEFT).setFont(font));
            table.addCell(getCellDashedBottomBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setTextAlignment(TextAlignment.RIGHT).setFont(font));
        }else {
            table.addCell(getCellNoBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setTextAlignment(TextAlignment.LEFT).setFont(font));
            table.addCell(getCellNoBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setTextAlignment(TextAlignment.RIGHT).setFont(font));
        }
        return table;
    }
    /**
     *@author lxw
     *@date 2020/7/9
     *@desc 普通Cell格式
     *@param font, table, reqMap
     *@return com.itextpdf.layout.element.Table
    **/
    Table getNormTable(PdfFont font,Table table,Map<String,Object> reqMap){
        if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_TOPLINE)){
            table.addCell(getCellDashedTopBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            table.addCell(getCellDashedTopBorder().add(IfspDataVerifyUtil.isBlank((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))?"":(String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setFont(font).setTextAlignment(TextAlignment.RIGHT));
        }else if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_BOTTOMLINE)){
            table.addCell(getCellDashedBottomBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            table.addCell(getCellDashedBottomBorder().add(IfspDataVerifyUtil.isBlank((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))?"":(String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setFont(font).setTextAlignment(TextAlignment.RIGHT));
        }else {
            table.addCell(getCellNoBorder().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            table.addCell(getCellNoBorder().add(IfspDataVerifyUtil.isBlank((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))?"":(String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setFont(font).setTextAlignment(TextAlignment.RIGHT));
        }
        return table;
    }
    /**
     *@author lxw
     *@date 2020/7/9
     *@desc 换行Cell 把一行中两个Cell合并成一个
     *@param font, table, reqMap
     *@return com.itextpdf.layout.element.Table
    **/
    @SuppressWarnings("AliControlFlowStatementWithoutBraces")
    Table getLineFeedTable(PdfFont font,Table table,Map<String,Object> reqMap){
        if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_TOPLINE)){
            table.addCell(getTowTopDashedMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            //noinspection AliControlFlowStatementWithoutBraces
            if(IfspDataVerifyUtil.isNotBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))) {
                table.addCell(getTowMergeCells().add(IfspDataVerifyUtil.isBlank((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))?"":(String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setFont(font));
            }
        }else if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_BOTTOMLINE)){
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            //noinspection AliControlFlowStatementWithoutBraces
            if(IfspDataVerifyUtil.isNotBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))) {
                table.addCell(getTowBottomDashedMergeCells().add(IfspDataVerifyUtil.isBlank((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))?"":(String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setFont(font));
            }
        }else {
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            //noinspection AliControlFlowStatementWithoutBraces
            if(IfspDataVerifyUtil.isNotBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))) {
                table.addCell(getTowMergeCells().add(IfspDataVerifyUtil.isBlank((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))?"":(String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)).setFont(font));
            }
        }
        return table;
    }
    /**
     *@author lxw
     *@date 2020/7/9
     *@desc 二维码cell格式
     *@param font, table, reqMap
     *@return com.itextpdf.layout.element.Table
    **/
    Table getQrcTable(PdfFont font,Table table,Map<String,Object> reqMap) throws Exception{
        if (IfspDataVerifyUtil.isBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))){
            return table;
        }
        Image img = new Image(ImageDataFactory.create(qrcImgCreate((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)))).setAutoScale(true).setMargins(2,40,0,40);
        if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_TOPLINE)){
            table.addCell(getTowTopDashedMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_DES)).setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        }else if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_BOTTOMLINE)){
            table.addCell(getTowMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
            table.addCell(getTowBottomDashedMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_DES)).setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        }else {
            table.addCell(getTowMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_DES)).setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        }
        return table;
    }
    /**
     *@author lxw
     *@date 2020/7/9
     *@desc 签名图片cell格式
     *@param font, table, reqMap
     *@return com.itextpdf.layout.element.Table
    **/
    Table getSignImgTable(PdfFont font,Table table,Map<String,Object> reqMap) throws Exception{
        Image img =null;
        if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_TOPLINE)){
            table.addCell(getTowTopDashedMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            if (IfspDataVerifyUtil.isNotBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))){
                img = new Image(ImageDataFactory.create(downloadImage((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)))).setAutoScale(true).setWidth(100).setHeight(30);
                table.addCell(getTowMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
            }
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_DES)).setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        }else if ((boolean)reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_BOTTOMLINE)){
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            if (IfspDataVerifyUtil.isNotBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))){
                img = new Image(ImageDataFactory.create(downloadImage((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)))).setAutoScale(true).setWidth(100).setHeight(30);
                table.addCell(getTowBottomDashedMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
            }
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_DES)).setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        }else {
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_NAME)).setFont(font));
            if (IfspDataVerifyUtil.isNotBlank(reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE))){
                img = new Image(ImageDataFactory.create(downloadImage((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_VALUE)))).setAutoScale(true).setWidth(100).setHeight(30);
                table.addCell(getTowMergeCells().add(img).setTextAlignment(TextAlignment.CENTER));
            }
            table.addCell(getTowMergeCells().add((String) reqMap.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_DES)).setFontSize(6).setTextAlignment(TextAlignment.CENTER).setFont(font));
        }
        return table;
    }
    /**
     *@author lxw
     *@date 2020/6/30
     *@desc 解析二维码图片信息
     *@param imageData
     *@return byte[]
    **/
    public  byte[] getQrcImage(String imageData) throws Exception{
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes ;
        try {
            bytes = decoder.decodeBuffer(imageData);
        } catch (IOException e) {
            log.error("Base64解码图片信息失败,原因:{}",e.getMessage());
            throw new BizException(IfspRespCode.RESP_ERROR,"Base64解码图片信息失败!");
        }
        return bytes;
    }
    /**
     *@author lxw
     *@date 2020/6/30
     *@desc 解析签名图片数据
     *@param signImagData
     *@return byte[]
    **/
    public  byte[] getSignImage(String signImagData) throws Exception{
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes ;
        try {
            bytes = decoder.decodeBuffer(signImagData);
        } catch (IOException e) {
            log.error("Base64解析签名图片信息失败,原因是:{}",e.getMessage());
            throw  new BizException(IfspRespCode.RESP_ERROR,"Base64解析签名图片信息失败!");
        }
        log.info("解析出签名图片:"+bytes.length);
        return bytes;
    }

    /**
     *@author lxw
     *@date 2020/6/23
     *@desc 检查文件是否存在,存在就删除掉
     *@param fileName, path
     *@return void
    **/
    public static void checkFIleExit(String fileName,String path){
        log.info("checkFIleExit方法入参:fileName:{},path:{}",fileName,path);
        File file = new File(path+fileName);
        if (file.exists()){
            file.delete();
        }
    }

    /**
     *@author lxw
     *@date 2020/6/30
     *@desc 生成文件名
     *@param
     *@return java.util.Map<java.lang.String,java.lang.String>
    **/
    public String createFileName(String orderId){
        return orderId+Constants.PDF_CREATE_AND_SIGN.PDF_FILE_NAME_SUFFIX;
    }

    /**
     * @return void
     * @author lxw
     * @date 2020/6/24
     * @desc 签名
     **/
    @Override
    public NetSignResult pafFileSign(String  fileName) {
        try {
            //初始化服务
            NetSignAgent.initialize(ElecBillCreateUtils.getResouseAblovePath(Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_CFG_PATH));
            PDFParameters param = new PDFParameters();
            param.setPdf(readPdfFile(fileName));
            param.setOwnerPassword(null);
            //设置加签位置
            param.addRectangle2Sign(0,0,595,842,1,null,null,null);
            NetSignResult result = NetSignAgent.pdfSignature( param );
            return result;
        } catch (NetSignAgentException e) {
            log.error("pdf签名失败-pdfSignature()||getByteArrayResult()调用异常,原因:{}",e.getMessage());
            return null;
        }  catch (ServerProcessException e) {
            log.error("pdf签名失败-pdfSignature()调用异常,原因:{}",e.getMessage());
            return null;
        } catch (Exception e){
            log.error("签名异常,原因:{}",e.getMessage());
            return null;
        }
    }
    /**
     *@author lxw
     *@date 2020/6/24
     *@desc 获取文件输入流
     *@param fileName
     *@return byte[]
    **/
    public static byte[] readPdfFile(String fileName){
        InputStream in = null;
        byte[] bytesRel;
        File f = null;
        try {
            f = new File(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
            in = new FileInputStream(f);
            bytesRel = new byte[ in.available()];
            in.read(bytesRel);
        } catch (IOException e) {
          log.error("读取文件{}失败!"+Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
          throw new BizException(IfspRespCode.RESP_ERROR,"读取pdf文件失败!");
        }finally {
            if (in != null){
                try {
                    in.close();
                    if (f.exists()){
                        f.delete();
                    }
                } catch (IOException e) {
                    log.error("输入流关闭失败!原因:{}",e.getMessage());
                }
            }
        }
        return  bytesRel;
    }

    /**
     *@author lxw
     *@date 2020/6/24
     *@desc 写文件
     *@param pdfByte, fileName
     *@return void
    **/
    @SuppressWarnings("AliControlFlowStatementWithoutBraces")
    public static void writePdfFile(byte[] pdfByte, String fileName) throws Exception{

        checkFIleExit(fileName,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
        OutputStream os = null;
        try {
            os = new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
            os.write( pdfByte ) ;
            os.flush() ;
        } catch (IOException e) {
            log.error("写入文件{}失败!"+Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName);
        }finally {
            try {
                //noinspection AliControlFlowStatementWithoutBraces
                if (os!=null) {
                    os.close();
                }
            } catch (IOException e) {
                log.error("输入流关闭失败!原因:{}",e.getMessage());
            }
        }
    }

    /**
     *@author lxw
     *@date 2020/6/30
     *@desc  初始化PbsEleInvoiceInfo对象
     *@param maps
     *@return com.ruim.ifsp.merser.bean.dto.PbsEleInvoiceInfo
    **/
    public PbsZnorderTicket getPbsEleInvoiceInfo(Map<String,String> maps) throws Exception{
        //入库时间取时间保持统一
        String localDate = IfspDateTime.getYYYYMMDDHHMMSS();
        PbsZnorderTicket pbsZnorderTicket = new PbsZnorderTicket();
        pbsZnorderTicket.setTxnOrderId(maps.get("orderId"));
        pbsZnorderTicket.setPrintNum(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0);
        //上传图片信息
//        Map<String, Object> signData = IfspFastJsonUtil.objectTomap(maps.get("signature"));
        if (maps.containsKey("signBase64")&&IfspDataVerifyUtil.isNotBlank(maps.get("signBase64"))){
            maps.put("signBase64",PDFUploadUti.sendImage(uploadImageHandler(maps.get("signBase64"),maps.get("orderId")),  maps.get("orderId")+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_TXT));
        }
        pbsZnorderTicket.setEnvoiceInfo(IfspFastJsonUtil.mapTOjson(maps));
        pbsZnorderTicket.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0);
        pbsZnorderTicket.setUpdateTime(localDate);
        pbsZnorderTicket.setCreateTime(localDate);
        return pbsZnorderTicket;
    }

    /**
     *@author lxw
     *@date 2020/7/1
     *@desc pdf信息保存
     *@param request
     *@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse
    **/
    @Override
    public MchtPfdOprResponse savePdfInfo(MchtPfdOprRequest request) throws Exception {

        MchtPfdOprResponse response = new MchtPfdOprResponse();
        try {
            List<Map<String,String>> reqMap = IfspFastJsonUtil.jsonTOlist(request.getReceipts());
            List<PbsZnorderTicket> var2 = new ArrayList<>();
            List<Map<String, String>> mapList = saveAllInfos(reqMap, var2);
            //为了便于查找日志,将日志的会话id传到子线程中
//            String sessionId = MDC.get("traceId");
            //开启线程生成pdf 线程执行不需要结果
//            PdfCreateSynThread pdfCreateSynThread = new PdfCreateSynThread(var2,sessionId);
//            threadPoolTaskExecutor.execute(pdfCreateSynThread);

            response.setHandlerList(mapList);
            response.setRespCode(IfspRespCode.RESP_SUCCESS);
            response.setRespMsg("交易成功!");
        } catch (DuplicateKeyException e){
            log.error("保存信息失败!原因:{}",e.getMessage());
            response.setRespCode(IfspRespCode.RESP_ERROR);
            response.setRespMsg("请检查该笔交易电子凭证打印状态!");
        }catch (Exception e) {
            log.error("保存信息失败!原因:{}",e.getMessage());
            response.setRespCode(IfspRespCode.RESP_ERROR);
            response.setRespMsg("交易失败!");
        }
        return response;
    }
    /**
     *@author lxw
     *@date 2020/7/3
     *@desc pdf文件生成处理
     *@param
     *@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse
    **/
  /*  @Override
    public MchtPfdOprResponse createPdfHandler(MchtPdfViewRequest request) throws Exception{
        //查询所有没有处理数据
        long startTime = System.currentTimeMillis();
        log.info("开始时间:{}",startTime);
        MchtPfdOprResponse response = new MchtPfdOprResponse();
        int pageNo = 1;
        int pageSize = Integer.valueOf(Constants.PDF_CREATE_AND_SIGN.PDF_PAGESIZE);

        while (true){
            List<PbsEleInvoiceInfo> pbsEleInvoiceInfoTmps = pbsEleInvoiceInfoDao.queryInfoList(pageNo,pageSize);
            if (IfspDataVerifyUtil.isBlank(pbsEleInvoiceInfoTmps)||pbsEleInvoiceInfoTmps.size()==0){
                response.setRespMsg("电子发票生成完成!");
                break;
            }
            for (PbsEleInvoiceInfo pbsEleInvoiceInfoTmp : pbsEleInvoiceInfoTmps) {

                if (pbsEleInvoiceInfoTmp.getPrintNum().contains("10")){
                    continue;
                }
                try {
                    //为了使事务生效,必须通过sping代理调用方法后,事务才会生效
                    createPdfService.pdfHandler(pbsEleInvoiceInfoTmp);
                } catch (Exception e) {
                    log.error("电子发票生成异常:{}",e.getMessage());
                    continue;
                }
            }
            if (pbsEleInvoiceInfoTmps.size()!=0){
                pageNo = pageSize+1;
                pageSize = pageNo+Integer.valueOf(Constants.PDF_CREATE_AND_SIGN.PDF_PAGESIZE)-1;
            }
        }
        log.info("结束时间:{},共耗时:{}ms",System.currentTimeMillis(),System.currentTimeMillis()-startTime);
        return response;

    }*/
    /**
     *@author lxw
     *@date 2020/7/1
     *@desc 二维码生成器
     *@param content
     *@return byte[]
    **/
    public byte[] qrcImgCreate(String content) throws Exception {
        //中文乱码问题
        byte[] imgData;
        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            //中文乱码
            Hashtable hints = new Hashtable();
            hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
            hints.put(EncodeHintType.MARGIN,1);
            BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 40, 40,hints);
            ByteArrayOutputStream qrcImgByteStram = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(encode,"PNG",qrcImgByteStram);
            imgData = qrcImgByteStram.toByteArray();
        } catch (WriterException e) {
            log.error("生成二维码失败,原因是:{}",e.getMessage());
            throw  new BizException(IfspRespCode.RESP_ERROR,"生成二维码失败失败!");
        } catch (IOException e) {
            log.error("B生成二维码失败,原因是:{}",e.getMessage());
            throw  new BizException(IfspRespCode.RESP_ERROR,"生成二维码失败失败!");
        }
        return imgData;
    }
    /**
     *@author lxw
     *@date 2020/7/3
     *@desc 图片信息下载
     *@param imageInfo
     *@return java.lang.String
    **/
    public static byte[] downloadImage(String imageInfo) throws Exception {

        byte[] bytes = null;
//        OutputStream write=null;
        try {
            String url =Constants.PDF_CREATE_AND_SIGN.DOWNLOAD_URL+imageInfo;
            HttpURLConnection connection = PDFUploadUti.bulidConnect(url);
            PDFUploadUti.sendMsg(connection,null);
            bytes = PDFUploadUti.receiveMsg(connection);
//            write = new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+"min.jpg");
//            write.write(bytes);
//            write.flush();
        } catch (Exception e) {
           log.error("下载图片失败!原因:{}",e.getMessage());
           throw new Exception(e);
        }
        return  bytes;
    }

    /**
     *@author lxw
     *@date 2020/7/9
     *@desc 将map中的key值转换成索引值
     *@param
     *@return java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.String>>
    **/
    public Map<String,Map<String,Object>> reqDataConvet(String info){
        Map<String,Map<String,Object>> revtMap = new HashMap<>();
        Map<String,String> maps = (Map<String, String>) IfspFastJsonUtil.jsonTOmap(info);
        for (String s : maps.keySet()) {
            if ("signature".equals(s)){
                Map<String,Object> allMaps = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(maps.get(s));
                revtMap.put( allMaps.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_INDEX).toString(),allMaps);
                continue;
            }
            Map<String,Object> values = IfspFastJsonUtil.objectTomap(maps.get(s));
            revtMap.put(values.get(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_FIELD_INDEX).toString(),values);
        }
        return revtMap;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc 小票信息入库
     *@param val1, val2
     *@return void
    **/
    public List<Map<String,String>> saveAllInfos(List<Map<String,String>> val1,List<PbsZnorderTicket> val2){

        log.info("++++++++++++++++++电子凭证入库处理开始+++++++++++++++++");
        PbsZnorderTicket pbsZnorderTicketTmp = new PbsZnorderTicket();
        //循环处理入库
        List<Map<String,String>> handlerList = new ArrayList<>();
        for (Map<String, String> map : val1) {
            try {
                int i = 0;
                pbsZnorderTicketTmp = getPbsEleInvoiceInfo(map);
                //确认临时表中的数据是否存在这笔订单数据 存在了进行更新以确保库中数据签名是最新的。(批量还没进行处理的时候,进行补打或者该笔生成电子凭证失败了)
                if (IfspDataVerifyUtil.isNotBlank(pbsZnorderTicketDao.selectByPrimaryKey(pbsZnorderTicketTmp.getTxnOrderId()))){
                   i = pbsZnorderTicketDao.updateByPrimaryKeySelective(pbsZnorderTicketTmp);
                }else {
                   i = pbsZnorderTicketDao.insertSelective(pbsZnorderTicketTmp);
                }
                if (i<1){
                    Map<String,String> maps = new HashMap<>();
                    maps.put("orderId",pbsZnorderTicketTmp.getTxnOrderId());
                    maps.put("stat","N");
                    handlerList.add(maps);
                }else {
                    val2.add(pbsZnorderTicketTmp);
                    Map<String,String> mapy = new HashMap<>();
                    mapy.put("orderId",pbsZnorderTicketTmp.getTxnOrderId());
                    mapy.put("stat","Y");
                    handlerList.add(mapy);
                }
            } catch (Exception e) {
                Map<String,String> maps = new HashMap<>();
                maps.put("orderId",map.get("orderId"));
                maps.put("stat","N");
                handlerList.add(maps);
               log.error(map.get("orderId")+"插入失败!原因:"+e.getMessage());
            }
        }
        log.info("++++++++++++++++++电子凭证入库处理结束+++++++++++++++++");
        return handlerList;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc freemarker 生成文件路由器
     *@param
     *@return boolean
    **/
    public boolean freeMarkCreateFile(PbsZnorderTicket pbsZnorderTicket) throws Exception {

        Map<String,Object> reqData = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(pbsZnorderTicket.getEnvoiceInfo());
        switch (reqData.get("fileType").toString()){
            case "1": //pdf-生成
               return  PdfCreateHandler(pbsZnorderTicket);
            case "2": //word
                return WordCreateHandler(pbsZnorderTicket);
            case "3": //图片
                return WordCreateHandler(pbsZnorderTicket);
            default:
                throw new Exception("未知的文件生成类型{"+reqData.get("fileType").toString()+"}");
        }
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc freeMarker pdf文件生成
     *@param
     *@return boolean
    **/
    public boolean  PdfCreateHandler(PbsZnorderTicket pbsZnorderTicket){
        try {
            //取出对象中小票信息
            Map<String,Object> reqData = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(pbsZnorderTicket.getEnvoiceInfo());
            //处理模板信息
            ElecBillCreateUtils.txnCodeToTemplate((String) reqData.get("txnTypeCode"),reqData);
            //处理图片信息
            imageHandler(reqData);
            //处理金额
            handlerAmt(reqData);
            //将信息写进模板中 32
            String freeMarkerRender = ElecBillCreateUtils.freeMarkerRender(reqData, reqData.get("templateName").toString());
            //生成pdf文件
            ElecBillCreateUtils.createPdf(freeMarkerRender,createFileName(pbsZnorderTicket.getTxnOrderId()));
        } catch (Exception e) {
            //更新备注信息-将错误明细放到库中保存,以便排查信息
            updateRemarkInfo(pbsZnorderTicket,e);
            log.error("生成pdf文件失败!",e.getMessage());
            return false;
        }
        return true;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc freeMarker 图片+ word 文件生成 目前没有使用
     *@param
     *@return boolean
    **/
    public boolean WordCreateHandler(PbsZnorderTicket pbsZnorderTicket) throws Exception{
        try {
            //取出对象中小票信息
            Map<String,Object> reqData = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(pbsZnorderTicket.getEnvoiceInfo());
            //将信息写进模板中
            String freeMarkerRender = ElecBillCreateUtils.freeMarkerRenderForWord(reqData, reqData.get("templateName").toString(),createFileName(pbsZnorderTicket.getTxnOrderId()));
            if ("03".equals(reqData.get("fileType"))){
                //生成image文件
                ElecBillCreateUtils.createImage(freeMarkerRender,createFileName(pbsZnorderTicket.getTxnOrderId()));
            }
        } catch (Exception e) {
            //更新备注信息-将错误明细放到库中保存,以便排查信息
            updateRemarkInfo(pbsZnorderTicket,e);
            log.error("生成pdf文件失败!",e.getMessage());
            return false;
        }
        return true;
    }
    /**
     *@author lxw
     *@date 2020/11/6
     *@desc pdf生成 处理图片信息
     *@param reqData
     *@return void
    **/
    public void imageHandler(Map<String,Object> reqData) throws Exception{
        //转码器
        BASE64Encoder encoder = new BASE64Encoder();
        //头部图片
        String headImg = ElecBillCreateUtils.getImageData(ElecBillCreateUtils.getResouseAblovePath(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_HEAD_IMG));
        reqData.put("headImg",Constants.PDF_CREATE_AND_SIGN.HTML_IMAGW_HEAD+ElecBillCreateUtils.removeSpacilChar(headImg));
        //处理二维码信息
        if (IfspDataVerifyUtil.isNotBlank(reqData.get("qrCode"))){
            byte[] qrCodes = qrcImgCreate((String) reqData.get("qrCode"));
            String imageData = encoder.encode(qrCodes);
            reqData.put("qrCode",Constants.PDF_CREATE_AND_SIGN.HTML_IMAGW_HEAD+ElecBillCreateUtils.removeSpacilChar(imageData));
        }
        //处理签名图片
        if (IfspDataVerifyUtil.isNotBlank(reqData.get("signBase64"))){

            String signImagePath = (String) reqData.get("signBase64");
            //下载图片信息
            byte[] bytes = downloadImage(signImagePath);
            //解析转换图片数据
            byte[] imageBytes = ElecBillCreateUtils.hexToByte(new String(bytes));
            //将jbig图片转换成bmp文件
            ElecBillCreateUtils.jbigTojpg(imageBytes,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,(String) reqData.get("orderId"));
            //将图片转换成jpg格式
            ElecBillCreateUtils.bpmCoverJpeg(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,(String) reqData.get("orderId"));
            //读文件
            byte[] imageFile = readPdfFile( (String) reqData.get("orderId") + Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG);

            String signImageData = encoder.encode(imageFile);
            reqData.put("signBase64",Constants.PDF_CREATE_AND_SIGN.HTML_IMAGW_HEAD+ElecBillCreateUtils.removeSpacilChar(signImageData));
        }

    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc  更新备注信息
     *@param pbsZnorderTicket, e
     *@return void
    **/
    public void updateRemarkInfo(PbsZnorderTicket pbsZnorderTicket,Exception e){
        PbsZnorderTicket t = new PbsZnorderTicket();
        t.setTxnOrderId(pbsZnorderTicket.getTxnOrderId());
        if(IfspDataVerifyUtil.isNotBlank(e.getMessage())){
            if (e.getMessage().length()>=999){
                t.setRemark(e.getMessage().substring(0,999));
            }else {
                t.setRemark(e.getMessage());
            }
        }else {
            t.setRemark("订单:"+pbsZnorderTicket.getTxnOrderId()+"生成pdf文件失败");
        }
        t.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
        pbsZnorderTicketDao.updateByPrimaryKeySelective(t);
    }
    /**
     *@author lxw
     *@date 2021/1/7
     *@desc 金额处理
     *@param reqData
     *@return void
    **/
    void handlerAmt(Map<String,Object> reqData){
        if (IfspDataVerifyUtil.isNotBlank(reqData.get("amount"))){
            BigDecimal amount = AmountUtils.divideCentToYuan(reqData.get("amount").toString());
            //金额处理
            reqData.put("amount","RMB "+ split3(amount.toString()));
        }else {
            reqData.put("amount","RMB "+ split3(reqData.get("amount")));
        }
    }
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(",##0.00");

    /**
     *@author lxw
     *@date 2021/1/7
     *@desc 金额添加 分号
     *@param o
     *@return java.lang.String
    **/
    private static String split3(Object o){
        if (IfspDataVerifyUtil.isBlank(o)){
            return "0.00";
        }
        BigDecimal var0 = new BigDecimal(oTs(o));
        return DECIMAL_FORMAT.format(var0);
    }

    public static String oTs(Object o){
        if (IfspDataVerifyUtil.isBlank(o)){
            return "0";
        }
        if (o instanceof String){
            return  new BigDecimal(o.toString()).toPlainString();
        }
        if (o instanceof Number){
            return o.toString();
        }
        return "0";
    }

    /**
     *@author lxw
     *@date 2021/1/5
     *@desc pdf文件生成和预览
     *@param request
     *@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse
    **/
    @Override
    public MchtPfdOprResponse createOrViewPdf(MchtPdfViewRequest request) throws Exception {

        long startTime = System.currentTimeMillis();
        log.info("开始时间:{}",startTime);
        MchtPfdOprResponse response = new MchtPfdOprResponse();
        //查询助农小票流水是否存在
        PbsZnorderTicket pbsZnorderTicket = pbsZnorderTicketDao.selectByPrimaryKey(request.getTxnOrderId());
        if (IfspDataVerifyUtil.isBlank(pbsZnorderTicket)){
            response.setRespCode(IfspRespCode.RESP_ERROR);
            response.setRespMsg("签名信息不存在");
            return response;
        }
        if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_01.equals(request.getOprflag())){//预览
            //检查文件是否存在,存在即删除(文件的签名有可能做重新签名,所以每次生成都要从新生成新的预览文件)
            checkFIleExit(createFileName(request.getTxnOrderId()),Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
            //生成pdf文件
            freeMarkCreateFile(pbsZnorderTicket);
            //文件放入内存中返回给前端,预览不用去签名
            byte[] pdfViewFile = readPdfFile(createFileName(request.getTxnOrderId()));
            response.setPdfFileByte(pdfViewFile);
            //文件写入内存后,删除本地文件中生成的文件
            checkFIleExit(createFileName(request.getTxnOrderId()),Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
        }else if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_02.equals(request.getOprflag())){ //下载
            byte[] pdfViewFile = readPdfFile(createFileName(request.getTxnOrderId()));
            if (IfspDataVerifyUtil.isBlank(pdfViewFile)){
                response.setRespCode(IfspRespCode.RESP_ERROR);
                response.setRespMsg("文件生成失败");
            }else {
                response.setPdfFileByte(pdfViewFile);
            }
        }else { //未知操作
            response.setRespCode(IfspRespCode.RESP_ERROR);
            response.setRespMsg("未知的操作类型");
        }
        return response;
    }
    /**
     *@author lxw
     *@date 2021/1/5
     *@desc 生成pfd文件,并加签
     *@param pbsZnorderTicket
     *@return byte[]
    **/
    public byte[] pdfDownLoad(PbsZnorderTicket pbsZnorderTicket) throws Exception{
        pbsZnorderTicket.setUpdateTime(IfspDateTime.getYYYYMMDDHHMMSS());
        byte[] byteArrayResult = null;
        try {
            //判断生成pdf是否成功
            if (freeMarkCreateFile(pbsZnorderTicket)){
                //判断pdf签名是否成功 -否
                NetSignResult netSignResult = pafFileSign(createFileName(pbsZnorderTicket.getTxnOrderId()));
                if (IfspDataVerifyUtil.isBlank(netSignResult)){
                    pbsZnorderTicket.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
                    pbsZnorderTicket.setRemark("文件签名失败");
                }else {//成功
                    pbsZnorderTicket.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0);
                    pbsZnorderTicket.setRemark("文件生成成功");
                    pbsZnorderTicket.setDownloadUri("");
                    //写入临时文件夹
//                    writePdfFile(netSignResult.getByteArrayResult(NetSignResult.SIGN_TEXT),createFileName(pbsZnorderTicket.getTxnOrderId()));
                    byteArrayResult = netSignResult.getByteArrayResult(NetSignResult.SIGN_TEXT);
                }
            }else {//pdf生成失败
                pbsZnorderTicket.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
            }
        } catch (Exception e) {
            log.error("电子发票生成失败!原因:{}",e.getMessage());
            pbsZnorderTicket.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
            if(IfspDataVerifyUtil.isNotBlank(e.getMessage())){
                if (e.getMessage().length()>=999){
                    pbsZnorderTicket.setRemark(e.getMessage().substring(0,999));
                }else {
                    pbsZnorderTicket.setRemark(e.getMessage());
                }
            }else {
                pbsZnorderTicket.setRemark("订单:"+pbsZnorderTicket.getTxnOrderId()+"电子发票生成失败");
            }
        }finally {
            //删除已经签名的pdf文件
//            checkFIleExit(createFileName(pbsZnorderTicket.getTxnOrderId()),Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
            //更新电子小票信息表中该笔数据状态和打印次数
            if (IfspDataVerifyUtil.isNotBlank(pbsZnorderTicketDao.selectByPrimaryKey(pbsZnorderTicket.getTxnOrderId()))){
                Integer valueOf = Integer.valueOf(pbsZnorderTicket.getPrintNum());
                valueOf++;
                pbsZnorderTicket.setPrintNum(valueOf.toString());
                pbsZnorderTicketDao.updateByPrimaryKeySelective(pbsZnorderTicket);
            }
        }
        return byteArrayResult;
    }

    @Override
    public void viewOrCreated(HttpServletResponse response, HttpServletRequest request){

        long startTime = System.currentTimeMillis();
        log.info("开始时间:{}",startTime);
        OutputStream os = null;
        try {
            String txnOrderId = request.getParameter("txnOrderId");
            if(IfspDataVerifyUtil.isBlank(txnOrderId)){
                response.sendError(HttpServletResponse.SC_NO_CONTENT,"订单号不能为空");
            }
            String oprFlag = request.getParameter("oprFlag");
            if(IfspDataVerifyUtil.isBlank(oprFlag)){
                response.sendError(HttpServletResponse.SC_NO_CONTENT,"操作类型不能为空");
            }

            os = response.getOutputStream();
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition","attachment;fileName="+txnOrderId+ ".pdf");
            //查询助农小票流水是否存在
            PbsZnorderTicket pbsZnorderTicket = pbsZnorderTicketDao.selectByPrimaryKey(txnOrderId);
            if (IfspDataVerifyUtil.isBlank(pbsZnorderTicket)){
                response.sendError(HttpServletResponse.SC_NO_CONTENT,"签名信息不存在");
            }
            if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_01.equals(oprFlag)){//预览
                //检查文件是否存在,存在即删除(文件的签名有可能做重新签名,所以每次生成都要从新生成新的预览文件)
                checkFIleExit(createFileName(txnOrderId),Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
                //生成pdf文件
                freeMarkCreateFile(pbsZnorderTicket);
                //文件放入内存中返回给前端,预览不用去签名
                byte[] pdfViewFile = readPdfFile(createFileName(txnOrderId));
                os.write(pdfViewFile);
                pbsZnorderTicket.setRemark("文件生成成功");
                pbsZnorderTicketDao.updateByPrimaryKeySelective(pbsZnorderTicket);
                //文件写入内存后,删除本地文件中生成的文件
                checkFIleExit(txnOrderId+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
            }else if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_02.equals(oprFlag)){ //下载
//                pdfDownLoad(pbsZnorderTicket);
//                byte[] pdfViewFile = readPdfFile(createFileName(txnOrderId));
                byte[] pdfDownLoad = pdfDownLoad(pbsZnorderTicket);
                if (IfspDataVerifyUtil.isBlank(pdfDownLoad)){
                    log.info("操作类型{},订单号{},生成电子凭证数据失败",oprFlag,txnOrderId);
                    response.sendError(HttpServletResponse.SC_NO_CONTENT,"凭证生成失败");
                }else {
                    //写文件
                    os.write(pdfDownLoad);
                }
            }else { //未知操作
                log.info("操作类型未知===========>{}",oprFlag);
                response.sendError(HttpServletResponse.SC_NO_CONTENT,"操作类型未知");
            }
            os.flush();
        } catch (Exception e) {
            log.error("====================>error:"+e.getMessage());
        } finally {
            try {
                os.close();
            } catch (IOException e) {
                log.error("====================>error:"+e.getMessage());
            }
            log.info("结束时间:{},共耗时:{}ms",System.currentTimeMillis(),System.currentTimeMillis()-startTime);
        }
    }
    /**
     *@author lxw
     *@date 2021/1/6
     *@desc
     *@param
     *@return byte[]
    **/
    public byte[] uploadImageHandler(String imageData,String fileName){
//        //解析转换图片数据
//        byte[] bytes = ElecBillCreateUtils.hexToByte(imageData);
//        //将jbig图片转换成bmp文件
//        ElecBillCreateUtils.jbigTojpg(bytes,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,fileName);
//        //将图片转换成jpg格式
//        ElecBillCreateUtils.bpmCoverJpeg(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,fileName);
//        //读文件
//        byte[] imageFile = readPdfFile( fileName + Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG);
//        //删除图片
//        checkFIleExit( fileName + Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);

        return imageData.getBytes();
    }
//    public static void main(String[] args) {
//        try {
//            BASE64Decoder decoder = new BASE64Decoder();
//            byte[] readPdfFile = readPdfFile("20201005.txt");
//            byte[] decodeBuffer = decoder.decodeBuffer(new String(readPdfFile, "utf-8"));
//            writePdfFile(decodeBuffer,"viewOrWrite.pdf");
//            String data = "00020100000006560000018c000000020800031cff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02c54c39ef32ca3fa493ad111780ff0207398b6c6042f72b00e1ef2f8e294b2c30ff022c8b150897ac0beae2ae3fcc3ab3e2f4fe6e18ff02312a6df1bcd7215dabfc728543bb756d878ce0ff0212f83ef15d2f92708ea16a8c94a772ff020d63981e4397ec395acfc6dacb5cacf0ff024223c38f60592804793b9f3ff7a888ff025a0a20900d551bada7307d4780ff02758ffd32ff027c599fff02918edcff021128ff028cff029eff0250ff02fdff027c4ea5b16bc0ff027242df4373d134ff02299fbcd4ae10ff02163cff02ff02ff02ff02ff02ff02ff02ff02ff02ff0280ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff023bcec56000d983141658ff022e60ff00b682cc3f0827ea6e90b628305ef67e031f65f9ca28c1418980ff020343af8e64217a32e28668c58aae257f59b1241decd180ff020cd923bc5b2e2297e9121e9f7b8724c19baabe3949e3f8ff005402d08428ff023090d3cfec56f3673d36ae4bc2a14dfcd826f37b859db0ff02155ee06c93332d1715db031778f28a7b07f0e5b8ff0220a62663bb4cdcdab61d4fe4309d5cef61721a80ff0205d62d6b04f8c2fa893aea44c47ec0ec80ff024bf532f09ba890ff028b714f11413cff027e04251180ff0267fd13e360ff0266f0ff02d85fc0ff023b20ff02c572ff02b9f4388b5b5bb2307cff028f84c6bd739dcd25ead604ff020750ae5a15f1d2f9afb24738ec4bab80ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff0280ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02188dc331ac13ad5c437cf6168ec1b48450c5d6c13ca8ff0206d6e2b0f15e2ccc86ac5515585fe3a4e064aad6f823ccb041c3d7bc839c0db17ed446e2cac0ff027da3264b50beafbd5c4a2191203375adf168703c5ece20f9705b3f2c79a12671594e5a7cd3ff0293353a05631b91865a2b5e998df5d48e77cd1d0fd3c0676edbb2ccc3e72c0a0b26056d97537ee609bb0eb3f5e5eaff0219c8e3666873570e8fb7b43341233ae92bce5f7cc54722fe3f31e6094c83160c9fe0b970edff0207f632b91f754ad24969b6ae8f1f6e7f9716056ee42bda4b8a14dc0ff6e0ff02a1782428ece89fac648bc64f32d9dfbe7c91bc9dc52f25c7276c202cda43ff02580b4f942093714c1b95add04f58bd327b6d7e445f2dba24ff029546d1f500b245ff02769f0a406045a440ff0289da7df52936ff0251d0ec93c7ff020222ff026b7cff025929b8ff0239e7ff0229402c557c342c8bf9235af6f0ff027bd6952f471f1b94e488d4048e72d7ff02b847a3109eecc1e5d9c53b1264f827399865d0ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02";
//            byte[] fileByte = data.getBytes();
//            writePdfFile(fileByte,"fileUpload.txt");
//            byte[] textFile = readPdfFile("fileUpload.txt");
//            String fileURl = PDFUploadUti.sendImage(textFile, "fileUpload.txt");
            byte[] dataByte = ElecBillCreateUtils.hexToByte(data);
//            byte[] bytes = downloadImage(fileURl);
//            FileOutputStream out = new FileOutputStream(new File(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+"downloadText.txt"));
//            out.write(bytes);
//            out.flush();
//            out.close();
//            ElecBillCreateUtils.jbigTojpg(dataByte,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);

//            byte[] readPdfFile = readPdfFile("downloadText.txt");
//            ElecBillCreateUtils.jbigTojpg(readPdfFile,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH,"wewwwwwwwwwwwwwwwww");
            writePdfFile(readPdfFile,"ceshi.txt");
//            String result  = new String(readPdfFile);
//            System.out.println(result);
//        } catch (Exception e) {
            e.printStackTrace();
//        }
//    }


}
package com.ruim.ifsp.merser.dao;

import com.ruim.ifsp.merser.bean.dto.PbsEleInvoiceInfo;
import com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket;

import java.util.List;

public interface PbsZnorderTicketDao {

    int deleteByPrimaryKey(String txnOrderId);

    int insert(PbsZnorderTicket record);

    int insertSelective(PbsZnorderTicket record) throws Exception;

    PbsZnorderTicket selectByPrimaryKey(String txnOrderId);

    int updateByPrimaryKeySelective(PbsZnorderTicket record);

    int updateByPrimaryKey(PbsZnorderTicket record);
    int insertSelectiveTmp(PbsZnorderTicket record);

}
package com.ruim.ifsp.merser.dao.imp;
import com.ruim.ifsp.common.dao.BaseBatisDao;
import com.ruim.ifsp.merser.bean.dto.PbsEleInvoiceInfo;
import com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket;
import com.ruim.ifsp.merser.bean.mapper.PbsZnorderTicketMapper;
import com.ruim.ifsp.merser.dao.PbsZnorderTicketDao;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @ClassName PbsEleInvoiceInfoDaoImpl
 * @Description pdf 文件保存
 * @Author lxw
 * @Date 2020/6/29 11:04
 **/
@Repository("pbsZnorderTicketDao")
public class PbsZnorderTicketDaoImpl extends BaseBatisDao implements PbsZnorderTicketDao {

    Class<PbsZnorderTicketMapper> pbsZnorderTicketMapper  = PbsZnorderTicketMapper.class;

    @Override
    public int deleteByPrimaryKey(String txnOrderId) {
        return getSqlSession().getMapper(pbsZnorderTicketMapper).deleteByPrimaryKey(txnOrderId);
    }

    @Override
    public int insert(PbsZnorderTicket record) {
        return getSqlSession().getMapper(pbsZnorderTicketMapper).insert(record);
    }

    @Override
    public int insertSelective(PbsZnorderTicket record) throws Exception{
        return getSqlSession().getMapper(pbsZnorderTicketMapper).insertSelective(record);
    }

    @Override
    public PbsZnorderTicket selectByPrimaryKey(String txnOrderId) {
        return getSqlSession().getMapper(pbsZnorderTicketMapper).selectByPrimaryKey(txnOrderId);
    }

    @Override
    public int updateByPrimaryKeySelective(PbsZnorderTicket record) {
        return getSqlSession().getMapper(pbsZnorderTicketMapper).updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(PbsZnorderTicket record) {
        return getSqlSession().getMapper(pbsZnorderTicketMapper).updateByPrimaryKey(record);
    }

    @Override
    public int insertSelectiveTmp(PbsZnorderTicket record) {
        return getSqlSession().getMapper(pbsZnorderTicketMapper).insertSelective(record);
    }
}

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ruim.ifsp.merser.bean.mapper.PbsZnorderTicketMapper" >
  <resultMap id="BaseResultMap" type="com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket" >
    <id column="TXN_ORDER_ID" property="txnOrderId" jdbcType="VARCHAR" />
    <result column="PDF_STATUS" property="pdfStatus" jdbcType="CHAR" />
    <result column="ENVOICE_INFO" property="envoiceInfo" jdbcType="VARCHAR" />
    <result column="PRINT_NUM" property="printNum" jdbcType="CHAR" />
    <result column="DOWNLOAD_URI" property="downloadUri" jdbcType="VARCHAR" />
    <result column="CREATE_TIME" property="createTime" jdbcType="VARCHAR" />
    <result column="UPDATE_TIME" property="updateTime" jdbcType="VARCHAR" />
    <result column="REMARK" property="remark" jdbcType="VARCHAR" />
  </resultMap>
  <sql id="Base_Column_List" >
    TXN_ORDER_ID, PDF_STATUS, ENVOICE_INFO, PRINT_NUM, DOWNLOAD_URI, CREATE_TIME, UPDATE_TIME, REMARK
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
    select 
    <include refid="Base_Column_List" />
    from PBS_ZNORDER_TICKET
    where TXN_ORDER_ID = #{txnOrderId,jdbcType=VARCHAR}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.String" >
    delete from PBS_ZNORDER_TICKET
    where TXN_ORDER_ID = #{txnOrderId,jdbcType=VARCHAR}
  </delete>
  <insert id="insert" parameterType="com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket" >
    insert into PBS_ZNORDER_TICKET (TXN_ORDER_ID, PDF_STATUS, ENVOICE_INFO, 
      PRINT_NUM, DOWNLOAD_URI, CREATE_TIME, 
      UPDATE_TIME)
    values (#{txnOrderId,jdbcType=VARCHAR}, #{pdfStatus,jdbcType=CHAR}, #{envoiceInfo,jdbcType=VARCHAR}, 
      #{printNum,jdbcType=CHAR}, #{downloadUri,jdbcType=VARCHAR}, #{createTime,jdbcType=VARCHAR}, 
      #{updateTime,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket" >
    insert into PBS_ZNORDER_TICKET
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="txnOrderId != null" >
        TXN_ORDER_ID,
      </if>
      <if test="pdfStatus != null" >
        PDF_STATUS,
      </if>
      <if test="envoiceInfo != null" >
        ENVOICE_INFO,
      </if>
      <if test="printNum != null" >
        PRINT_NUM,
      </if>
      <if test="downloadUri != null" >
        DOWNLOAD_URI,
      </if>
      <if test="createTime != null" >
        CREATE_TIME,
      </if>
      <if test="updateTime != null" >
        UPDATE_TIME,
      </if>
      <if test="remark != null" >
        REMARK,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="txnOrderId != null" >
        #{txnOrderId,jdbcType=VARCHAR},
      </if>
      <if test="pdfStatus != null" >
        #{pdfStatus,jdbcType=CHAR},
      </if>
      <if test="envoiceInfo != null" >
        #{envoiceInfo,jdbcType=VARCHAR},
      </if>
      <if test="printNum != null" >
        #{printNum,jdbcType=CHAR},
      </if>
      <if test="downloadUri != null" >
        #{downloadUri,jdbcType=VARCHAR},
      </if>
      <if test="createTime != null" >
        #{createTime,jdbcType=VARCHAR},
      </if>
      <if test="updateTime != null" >
        #{updateTime,jdbcType=VARCHAR},
      </if>
      <if test="remark != null" >
        #{remark,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket" >
    update PBS_ZNORDER_TICKET
    <set >
      <if test="pdfStatus != null" >
        PDF_STATUS = #{pdfStatus,jdbcType=CHAR},
      </if>
      <if test="envoiceInfo != null" >
        ENVOICE_INFO = #{envoiceInfo,jdbcType=VARCHAR},
      </if>
      <if test="printNum != null" >
        PRINT_NUM = #{printNum,jdbcType=CHAR},
      </if>
      <if test="downloadUri != null" >
        DOWNLOAD_URI = #{downloadUri,jdbcType=VARCHAR},
      </if>
      <if test="createTime != null" >
        CREATE_TIME = #{createTime,jdbcType=VARCHAR},
      </if>
      <if test="updateTime != null" >
        UPDATE_TIME = #{updateTime,jdbcType=VARCHAR},
      </if>
      <if test="remark != null" >
        REMARK = #{remark,jdbcType=VARCHAR},
      </if>
    </set>
    where TXN_ORDER_ID = #{txnOrderId,jdbcType=VARCHAR}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.ruim.ifsp.merser.bean.dto.PbsZnorderTicket" >
    update PBS_ZNORDER_TICKET
    set PDF_STATUS = #{pdfStatus,jdbcType=CHAR},
      ENVOICE_INFO = #{envoiceInfo,jdbcType=VARCHAR},
      PRINT_NUM = #{printNum,jdbcType=CHAR},
      DOWNLOAD_URI = #{downloadUri,jdbcType=VARCHAR},
      CREATE_TIME = #{createTime,jdbcType=VARCHAR},
      UPDATE_TIME = #{updateTime,jdbcType=VARCHAR}
    where TXN_ORDER_ID = #{txnOrderId,jdbcType=VARCHAR}
  </update>
</mapper>
package com.ruim.ifsp.merser.bean.dto;

import com.ruim.ifsp.common.beans.CommonDTO;

public class PbsZnorderTicket extends CommonDTO {
    private String txnOrderId;

    private String pdfStatus;

    private String envoiceInfo;

    private String printNum;

    private String downloadUri;

    private String createTime;

    private String updateTime;

    private String remark;

    public String getTxnOrderId() {
        return txnOrderId;
    }

    public void setTxnOrderId(String txnOrderId) {
        this.txnOrderId = txnOrderId == null ? null : txnOrderId.trim();
    }

    public String getPdfStatus() {
        return pdfStatus;
    }

    public void setPdfStatus(String pdfStatus) {
        this.pdfStatus = pdfStatus == null ? null : pdfStatus.trim();
    }

    public String getEnvoiceInfo() {
        return envoiceInfo;
    }

    public void setEnvoiceInfo(String envoiceInfo) {
        this.envoiceInfo = envoiceInfo == null ? null : envoiceInfo.trim();
    }

    public String getPrintNum() {
        return printNum;
    }

    public void setPrintNum(String printNum) {
        this.printNum = printNum == null ? null : printNum.trim();
    }

    public String getDownloadUri() {
        return downloadUri;
    }

    public void setDownloadUri(String downloadUri) {
        this.downloadUri = downloadUri == null ? null : downloadUri.trim();
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime == null ? null : createTime.trim();
    }

    public String getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(String updateTime) {
        this.updateTime = updateTime == null ? null : updateTime.trim();
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
}

5.3pom文件配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.ruim.ifsp.pay</groupId>
        <artifactId>ifsp-paymaster</artifactId>
        <version>1.0.0</version>
    </parent>
    <artifactId>ifsp-mchts</artifactId>
    <packaging>war</packaging>
    <description>睿民互联网支付平台-商户服务后台系统</description>
    <properties>
        <jaxen.version>1.1.6</jaxen.version>
        <pageHelper.version>4.1.6</pageHelper.version>
        <!-- poi -->
        <poi.version>3.9</poi.version>
    </properties>
    <dependencies>
        //使用的jar包
        <dependency>
            <groupId>com.pdfSign</groupId>
            <artifactId>ISFJ_v2_0_139_16_BAISC_JDK15</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.pdfSign</groupId>
            <artifactId>netsignapi</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.pdfSign</groupId>
            <artifactId>upload</artifactId>
            <version>1.0.0</version>
        </dependency>

        <dependency>
            <groupId>org</groupId>
            <artifactId>pdf</artifactId>
            <version>5.5.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>itextAsian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>

        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.10</version>
        </dependency>
       <!-- <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>core-renderer</artifactId>
            <version>1.0</version>
        </dependency>-->
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>com.lowagie.text</artifactId>
            <version>2.1.7</version>
        </dependency>
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>flying-saucer-pdf-itext5</artifactId>
            <version>9.1.5</version>
        </dependency>
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>flying-saucer-core</artifactId>
            <version>9.1.20</version>
        </dependency>
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>flying-saucer-pdf</artifactId>
            <version>9.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.pdf</groupId>
            <artifactId>jbigkit</artifactId>
            <version>2.1</version>
        </dependency>
    </dependencies>
</project>

5.4公共类

package com.ruim.ifsp.merser.common;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.itextpdf.text.pdf.BaseFont;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import com.ruim.ifsp.utils.verify.IfspDataVerifyUtil;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.slf4j.Logger;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import sun.misc.BASE64Encoder;
import uk.ac.cam.cl.mgk25.jbigkit.JBIG;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName ElecBillCreateUtils
 * @Description
 * @Author 电子票据生成工具类
 * @Date 2020/11/5 14:53
 **/
public class ElecBillCreateUtils {

    private static Logger log = IfspLoggerFactory.getLogger(ElecBillCreateUtils.class);

    private static Configuration freemarkerCfg = null;

    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(",##0.00");
    static {
        freemarkerCfg =new Configuration();
        try {

            freemarkerCfg.setClassForTemplateLoading(ElecBillCreateUtils.class,"/eleBillTemplate");
//            freemarkerCfg.setObjectWrapper(new DefaultObjectWrapper());eleBillTemplate/CCTDQZCTemplate.html
            freemarkerCfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *@author lxw
     *@date 2020/11/5
     *@desc 获取图片文件的base64转码数据
     *@param imagePath
     *@return java.lang.String
    **/
    public static String getImageData(String imagePath) throws Exception{
        log.info("getImageData 获取图片数据,图片路径"+imagePath);
        String imgData = null;
        byte[] var1 = null;
        InputStream in = new FileInputStream(imagePath);
        var1 = new byte[in.available()];
        in.read(var1);
        BASE64Encoder encoder = new BASE64Encoder();
        imgData = encoder.encode(var1);
        return imgData;
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc 去除文件中存在的回车,换行 符(c)
     *@return java.lang.String
    **/
    public static String removeSpacilChar(String str){
        String spacilChar = null;
        if (IfspDataVerifyUtil.isNotBlank(str)){
            Pattern pattern = Pattern.compile("\\s*|\t|\r|\n");
            Matcher matcher = pattern.matcher(str);
            spacilChar = matcher.replaceAll("");
        }
        return spacilChar;
    }

    /**
     *@author lxw
     *@date 2020/11/5
     *@desc  freemarker数据填充适用于pdf
     *@param data, htmlTmp WEB-INF/eleBillTemplate
     *@return java.lang.String
    **/
    public static String freeMarkerRender(Map<String, Object> data, String templateFile) throws Exception{
        Writer out =new StringWriter();
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate(templateFile,"UTF-8");
            // 合并数据模型与模板,将合并后的数据和模板写入到流中,这里使用的字符流
            template.process(data, out);
            out.flush();
            return out.toString();
        } catch (Exception e) {
            log.error("模板"+templateFile+"填充数据失败,原因是:"+e.getMessage());
            throw e;
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                log.error("模板"+templateFile+"填充数据失败,原因是:"+ex.getMessage());
                throw ex;
            }
        }
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc  freemarker数据填充,这一步可直接生成doc,image文件
     *@param data, htmlTmp
     *@return java.lang.String
     **/
    public static String freeMarkerRenderForWord(Map<String, Object> data, String templateFile,String name) {
        Writer out = null;
        File file = new File(name);
        try {
            out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate(templateFile,"UTF-8");
            // 合并数据模型与模板
            template.process(data, out); //将合并后的数据和模板写入到流中,这里使用的字符流
            out.flush();
            return out.toString();
        } catch (Exception e) {
            log.error("模板"+templateFile+"填充数据失败,原因是:"+e.getMessage());
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                log.error("模板"+templateFile+"填充数据失败,原因是:"+ex.getMessage());
            }
        }
        return null;
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc  pdf 生成工具类
     *@param content, dest
     *@return void
    **/
    public static void createPdf(String content,String fileName) throws Exception {
        ITextRenderer renderer = new ITextRenderer();
        ITextFontResolver fontResolver = renderer.getFontResolver();
        fontResolver.addFont(getResouseAblovePath(Constants.PDF_CREATE_AND_SIGN.PDF_CREATE_FILE_FONT),BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
        renderer.setDocumentFromString(content);

        renderer.layout();
        renderer.createPDF(new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName));
        renderer.finishPDF();
    }
    /**
     *@author lxw
     *@date 2020/11/5
     *@desc image图片文件生成
     *@param content, dest
     *@return void
    **/
    public static void createImage(String content,String tempFilePath) throws Exception{
        File f = new File(tempFilePath);
        Java2DRenderer renderer = new Java2DRenderer(f,1000,1200);
        BufferedImage image = renderer.getImage();
        FSImageWriter imageWriter = new FSImageWriter();
        imageWriter.setWriteCompressionQuality(0.9f);
        imageWriter.write(image,tempFilePath);
    }
    /**
     *@author lxw
     *@date 2020/7/1
     *@desc 二维码生成器
     *@param content
     *@return byte[]
     **/
    public static byte[] qrcImgCreate(String content) throws Exception {
        //中文乱码问题
        byte[] imgData;
        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            //中文乱码
            Hashtable hints = new Hashtable();
            hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
            hints.put(EncodeHintType.MARGIN,1);
            BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 40, 40,hints);
            ByteArrayOutputStream qrcImgByteStram = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(encode,"PNG",qrcImgByteStram);
            imgData = qrcImgByteStram.toByteArray();
        } catch (WriterException e) {
            log.error("生成二维码失败,原因是:{}",e.getMessage());
            throw  new RuntimeException("生成二维码失败失败!");
        } catch (IOException e) {
            log.error("生成二维码失败,原因是:{}",e.getMessage());
            throw  new RuntimeException("生成二维码失败失败!");
        }
        return imgData;
    }
    /**
     *@author lxw
     *@date 2020/11/10
     *@desc 交易码路由模板文件
     *@param txnTypeCode, reqData
     *@return void
    **/
    public static void txnCodeToTemplate(String txnTypeCode,Map<String,Object> reqData) throws Exception{
        switch (txnTypeCode){
            case "2001805"://城乡居民-养老
                req2001805Hander(reqData);
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "2001823"://城乡居民-医疗
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "2001824"://灵活就业-养老
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "2001825"://灵活就业-医疗
                reqData.put("templateName","ZNSBJFTemplate.html");
                break;
            case "201401"://预售基金
                reqData.put("templateName","ZNZJJFTemplate.html");
                break;
            case "201303"://维修基金
                reqData.put("templateName","ZNZJJFTemplate.html");
                break;
            case "201503"://水费缴费
                req201503Hander(reqData);
                reqData.put("templateName","ZNSFJFTemplate.html");
                break;
            case "200907": //广电缴费
                req200907Hander(reqData);
                reqData.put("templateName","ZNGDJFTemplate.html");
                break;
            case "200707": //电费缴费(兴义)
                reqData.put("templateName","ZNDFJFTemplate.html");
                break;
            case "200702": //电费缴费(全省-兴义)包含 撤销
                reqData.put("templateName","ZNDFJFTemplate.html");
                break;
            case "2006041": //欠款还款
                req2006041Hander(reqData);
                reqData.put("templateName","DKHKTemplate.html");
                break;
            case "2006042": //提前还本
                reqData.put("templateName","XDTQHBTemplate.html");
                break;
            case "2006044": //结清贷款
                req22006044Hander(reqData);
                reqData.put("templateName","XDTQHBTemplate.html");
                break;
            case "200504": //短信签约变更(签约、解约、变更)
                req200504Hander(reqData);
                reqData.put("templateName","ZNDXQYTemplate.html");
                break;
            case "200401": //助农取款
                reqData.put("templateName","ZNWDMTemplate.html");
                break;
            case "200402": //助农转账
                req200402Hander(reqData);
                reqData.put("templateName","ZNTRANTemplate.html");
                break;
            case "200705": //电费预缴费(全省)
                reqData.put("templateName","ZNDFJFTemplate.html");
                break;
            case "200703": //电费缴费撤销(全省)
                reqData.put("templateName","ZNDFJFCXTemplate.html");
                break;
            case "200708": //电费缴费撤销(兴义)
                reqData.put("templateName","ZNDFJFCXTemplate.html");
                break;
            case "201603": //定期转出
                req2016031Hander(reqData);
                reqData.put("templateName","CCTDQZCTemplate.html");
                break;
            case "201602": //活期转存
                reqData.put("templateName","CCTHQZCTemplate.html");
                break;
            default:
                throw new Exception("未找到对应的小票模板信息");
        }
    }
    /**
     *@author lxw
     *@date 2020/11/23
     *@desc 短信签约 业务报文处理
     *@param reqData
     *@return void
    **/
    public static void req200504Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,String> jsonString = (Map<String, String>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        String businessType = jsonString.get("businessType");
        if (IfspDataVerifyUtil.equals("01",businessType)){
            jsonString.put("smsNameTitle","签约姓名");
        }else {
            jsonString.put("smsNameTitle","解约姓名");
        }
        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    public static void req200907Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        //分转元
        BigDecimal bqyeAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("bqye"))?"0":jsonString.get("bqye").toString());
        //账户余额
        String bqye = split3(bqyeAmt);

        jsonString.put("bqye",bqye);

        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    public static void req200402Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);

      if (IfspDataVerifyUtil.isBlank(jsonString.get("transferFree"))){
          jsonString.put("transferFree","0");
      }
        if (numberHandler(jsonString.get("transferFree").toString())){
            //分转元
            BigDecimal transferFreeAmt = AmountUtils.divideCentToYuan(jsonString.get("transferFree").toString());
            String transferFree = split3(transferFreeAmt);
            jsonString.put("transferFree",transferFree);
            reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        }
        reqData.putAll(jsonString);
    }
    public static void req201503Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        //分转元
        BigDecimal wyjAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("wyj"))?"0":jsonString.get("wyj").toString());
        //账户余额
        String wyj = split3(wyjAmt);
        jsonString.put("wyj",wyj);
        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    public static void req2001805Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        //分转元
        BigDecimal payFeeAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("payFee"))?"0":jsonString.get("payFee").toString());
        //账户余额
        String payFee = split3(payFeeAmt);
        jsonString.put("payFee",payFee);
        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    public static void req2006041Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        //分转元
        BigDecimal totalArrearsDueAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("totalArrearsDue"))?"0":jsonString.get("totalArrearsDue").toString());
        BigDecimal principalArrearsDueAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("principalArrearsDue"))?"0":jsonString.get("principalArrearsDue").toString());
        BigDecimal regularInterestArrearsDueAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("regularInterestArrearsDue"))?"0":jsonString.get("regularInterestArrearsDue").toString());
        BigDecimal penaltyInterestArrearsDueAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("penaltyInterestArrearsDue"))?"0":jsonString.get("penaltyInterestArrearsDue").toString());
        BigDecimal compoundInterestArrearsDueAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("compoundInterestArrearsDue"))?"0":jsonString.get("compoundInterestArrearsDue").toString());
        BigDecimal subsidyTotalDueAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("subsidyTotalDue"))?"0":jsonString.get("subsidyTotalDue").toString());
        BigDecimal totalUnbilledInterestAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("totalUnbilledInterest"))?"0":jsonString.get("totalUnbilledInterest").toString());
        BigDecimal unbilledInterestAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("unbilledInterest"))?"0":jsonString.get("unbilledInterest").toString());
        BigDecimal unbilledPenaltyInterestAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("unbilledPenaltyInterest"))?"0":jsonString.get("unbilledPenaltyInterest").toString());
        BigDecimal unbilledCompoundPenaltyInterestAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("unbilledCompoundPenaltyInterest"))?"0":jsonString.get("unbilledCompoundPenaltyInterest").toString());
        BigDecimal unbilledSubsidyInterestAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("unbilledSubsidyInterest"))?"0":jsonString.get("unbilledSubsidyInterest").toString());

        jsonString.put("totalArrearsDue",split3(totalArrearsDueAmt));
        jsonString.put("principalArrearsDue",split3(principalArrearsDueAmt));
        jsonString.put("regularInterestArrearsDue",split3(regularInterestArrearsDueAmt));
        jsonString.put("penaltyInterestArrearsDue",split3(penaltyInterestArrearsDueAmt));
        jsonString.put("compoundInterestArrearsDue",split3(compoundInterestArrearsDueAmt));
        jsonString.put("subsidyTotalDue",split3(subsidyTotalDueAmt));
        jsonString.put("totalUnbilledInterest",split3(totalUnbilledInterestAmt));
        jsonString.put("unbilledInterest",split3(unbilledInterestAmt));
        jsonString.put("unbilledPenaltyInterest",split3(unbilledPenaltyInterestAmt));
        jsonString.put("unbilledCompoundPenaltyInterest",split3(unbilledCompoundPenaltyInterestAmt));
        jsonString.put("unbilledSubsidyInterest",split3(unbilledSubsidyInterestAmt));

        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    public static void req22006044Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        //分转元
        BigDecimal amtPrincPaidAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("amtPrincPaid"))?"0":jsonString.get("amtPrincPaid").toString());
        BigDecimal amtUnbilledIntAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("amtUnbilledInt"))?"0":jsonString.get("amtUnbilledInt").toString());
        BigDecimal totalUnbilledInterestAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("totalUnbilledInterest"))?"0":jsonString.get("totalUnbilledInterest").toString());

        jsonString.put("amtPrincPaid",split3(amtPrincPaidAmt));
        jsonString.put("amtUnbilledInt",split3(amtUnbilledIntAmt));
        jsonString.put("totalUnbilledInterest",split3(totalUnbilledInterestAmt));

        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    public static void req2016031Hander(Map<String,Object> reqData){
        String jsonBody = (String) reqData.get("jsonBody");
        Map<String,Object> jsonString = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(jsonBody);
        //分转元
        BigDecimal intAmtAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("intAmt"))?"0":jsonString.get("intAmt").toString());
        BigDecimal printIntAmtCasaAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("printIntAmtCasa"))?"0":jsonString.get("printIntAmtCasa").toString());
        BigDecimal printIntTaxAmtAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("printIntTaxAmt"))?"0":jsonString.get("printIntTaxAmt").toString());
        BigDecimal origPayAmountAmt = AmountUtils.divideCentToYuan(IfspDataVerifyUtil.isBlank(jsonString.get("origPayAmount"))?"0":jsonString.get("origPayAmount").toString());

        jsonString.put("intAmt",split3(intAmtAmt));
        jsonString.put("printIntAmtCasa",split3(printIntAmtCasaAmt));
        jsonString.put("printIntTaxAmt",split3(printIntTaxAmtAmt));
        jsonString.put("origPayAmount",split3(origPayAmountAmt));

        reqData.put("jsonBody",IfspFastJsonUtil.mapTOjson(jsonString));
        reqData.putAll(jsonString);
    }
    private static String split3(Object o){
        if (IfspDataVerifyUtil.isBlank(o)){
            return "0.00";
        }
        BigDecimal var0 = new BigDecimal(oTs(o));
        return DECIMAL_FORMAT.format(var0);
    }

    public static String oTs(Object o){
        if (IfspDataVerifyUtil.isBlank(o)){
            return "0";
        }
        if (o instanceof String){
            return  new BigDecimal(o.toString()).toPlainString();
        }
        if (o instanceof Number){
            return o.toString();
        }
        return "0";
    }

    /**
     *@author lxw
     *@date 2020/11/23
     *@desc  判断金额是否为全数字(包含小数)
     *@param amt
     *@return boolean
    **/
    public static boolean numberHandler(String amt){
        Pattern pattern = Pattern.compile("([0-9]\\d*\\.?\\d*)|(0\\.\\d*[0-9])");
        Matcher matcher = pattern.matcher(amt);
        return matcher.matches();

    }

   /* public static void main(String[] args) {
//        String s = "384.09六";
//        BigDecimal bqyeAmt = AmountUtils.divideCentToYuan("0");
        boolean b = numberHandler("0");
        System.out.println( b);
    }*/

  public static String getResouseAblovePath(String relatePath) {
      //本地代码调试需要截取-服务器上需要去掉
//      return ElecBillCreateUtils.class.getClassLoader().getResource(relatePath).getPath().substring(1);
      return ElecBillCreateUtils.class.getClassLoader().getResource(relatePath).getPath();
  }

  public static void jbigTojpg(byte[] imageData,String path,String fileName) throws Exception{
      File file = new File(path+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JBIG);
      FileOutputStream fos= null;
      try {
          fos = new FileOutputStream(file);
          fos.write(imageData);
          fos.flush();
          JBIG.jbg2bmp(path+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JBIG,path+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_BMP);
      }catch (Exception e){
          log.error("图片解析处理异常=====>{}",e.getMessage());
          throw new Exception(e);
      }finally {
          try {
              fos.close();
              if (file.exists()){
                  file.delete();
              }
          } catch (IOException e) {
              log.error("处理异常=====>{}",e.getMessage());
              throw new Exception(e);
          }
      }
  }
  /**
   *@author lxw
   *@date 2021/1/6
   *@desc 十六进制字符串转字节
   *@param hexString
   *@return byte[]
  **/
    public static byte[] hexToByte(String hexString){

      int m,n =0;
      int byteLen = hexString.length()/2;
      byte[]  ret = new byte[byteLen];
      for (int i =0;i<byteLen;i++){
          m = i*2+1;
          n=m+1;
          int intVal = Integer.decode("0x"+hexString.substring(i*2,m)+hexString.substring(m,n));
          ret[i] = Byte.valueOf((byte)intVal);
      }
      return ret;
    }
    /**
     *@author lxw
     *@date 2021/1/6
     *@desc 图片转换
     *@return void
     **/
    public static void bpmCoverJpeg(String path,String fileName) throws Exception{
        File  file = new File(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_BMP);
        try {
            Image img = ImageIO.read(file);
            BufferedImage tag = new BufferedImage(((BufferedImage) img).getWidth(null),((BufferedImage) img).getHeight(null),BufferedImage.TYPE_INT_RGB);
            tag.getGraphics().drawImage(img.getScaledInstance(((BufferedImage) img).getWidth(null),((BufferedImage) img).getHeight(null),Image.SCALE_SMOOTH),0,0,null);
            FileOutputStream out = new FileOutputStream(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH+fileName+Constants.PDF_CREATE_AND_SIGN.PDF_SIGN_IMAGE_JPG);
            //下面这种方式生成jpg文件再工程打包的时候需要再打包的时候,从新重载rt.jar,jce.jar包,不太友好,不建议使用这种方式。
            //JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //encoder.encode(tag);
//这种方式写jpg 文件,不会出现上述问题
            ImageIO.write(tag,"jpg",out); //将转换出来的流写成jpg文件
            out.close();
        } catch (IOException e) {
           log.error("图片转换异常======>{}",e.getMessage());
           throw new RuntimeException(e);
        } finally {
            if (file.exists()){
                file.delete();
            }
        }
    }
}
package com.ruim.ifsp.merser.common;

import com.ruim.ifsp.merser.cache.CommonConstants;

import java.util.HashMap;
import java.util.Map;

public class Constants {
    
    public static Map<String, String> respCodeTransMap = new HashMap<String, String>();

    public interface PDF_CREATE_AND_SIGN{
         public static final String PDF_SIGN_CFG_PATH ="ifspconfigs/constant/netsignagent.properties"; //签名地址
         public static final String PDF_FILE_PATH="/data/files/mchts/eleBillTemplate/";//pdf生成地址-临时文件生成存放地址
         public static final String PDF_CREATE_FILE_FONT="eleBillTemplate/simhei.ttf";//freemarker模板文件字体(html文件)
         public static final String PDF_FILE_HEAD_IMG ="eleBillTemplate/HeadLogo.jpg";//贵州农信的logo图片
         public static final String URLSTR =CommonConstants.getProperties("UPLOAD_FILE");// 上传地址
         public static final String REQUESTCHNLNO = "411";// 请求渠道号
         public static final String REAUESTFILETYPE ="04";// 文件类型-PDF
         public static final String REAUESTFILETYPE_IMG ="03";// 文件类型-图片
         public static final String REAUESTFILETYPE_TXT ="99";// 文件类型-文本-对应文件类型为其他
         public static final String DOWNLOAD_URL=CommonConstants.getProperties("DOWNLOAD_FILE");
         public static final String PDF_PAGESIZE=CommonConstants.getProperties("PDF_PAGESIZE");
         public static final String PDF_FILE_NAME_SUFFIX=".pdf";
         public static final String PDF_FILE_CREATE_STATUS_0="0";//成功
         public static final String PDF_FILE_CREATE_STATUS_1="1";//处理失败
         public static final String PDF_FILE_CREATE_STATUS_2="2";//
         public static final String PDF_FILE_CREATE_STATUS_01="01"; //预览
         public static final String PDF_FILE_CREATE_STATUS_02="02"; //下载

         public static final String PDF_FILE_FIELD_TOPLINE="topline";
         public static final String PDF_FILE_FIELD_BOTTOMLINE="bottomLine";
         public static final String PDF_FILE_FIELD_ID="id";
         public static final String PDF_FILE_FIELD_NAME="name";
         public static final String PDF_FILE_FIELD_VALUE="value";
         public static final String PDF_FILE_FIELD_INDEX="index";
         public static final String PDF_FILE_FIELD_DES="des";

         public static final String PDF_SIGN_IMAGE_JBIG=".jbig";//图片类型 jbig
         public static final String PDF_SIGN_IMAGE_BMP=".bmp";
         public static final String PDF_SIGN_IMAGE_JPG=".jpg";
         public static final String PDF_SIGN_IMAGE_TXT=".txt";

         public static final String HTML_IMAGW_HEAD="data:image/jpeg;base64,"; //html 文件中图片信息头文件信息,html文件图片信息显示必须是base64转码图片。

     }
}

5.5生成小票预览

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值