700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > freemark+html+jbig生成pdf文件

freemark+html+jbig生成pdf文件

时间:2023-01-04 02:25:17

相关推荐

freemark+html+jbig生成pdf文件

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

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

3.本文使用的技术有freemarker,银联压缩图片解压,springmvc 文件下载等,文件中没有写测试类,如果需要测试的可以直接使用service中方法,资源地址/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";// 文件类型-PDFpublic 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.mon.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 /6/23 10:23**/public class CreatePdfServiceImpl {private static Logger log = LoggerFactory.getLogger(CreatePdfServiceImpl.class);/***@author lxw*@date /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 /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 /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 /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 /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 /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 AliControlFlowStatementWithoutBracesif (os!=null) {os.close();}} catch (IOException e) {log.error("输入流关闭失败!原因:{}",e.getMessage());}}}/***@author lxw*@date /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 /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 /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);//将信息写进模板中 32String 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 /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 /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 /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 /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 /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 /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","2210107000168221");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","-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","01");reqMap.put("jsonBody","");reqMap.put("signBase64","0000000006560000018c000000020800031cff02ff02ff02e9efbf0bff021e70ff02557cf2ff027efaf810ff02862e30bcb067b0ff027d61f1c8e025e0ff02988553d2d6c1f518d53639c0ff0216f5a1fcebc641fc888655c42e6f3d0462e318ff02c49be605fcf8d45a66a918a4a1dfc837158a7f15a371f7880c5dbd5427e3c87813a0ff026309cb5f02953e10c9c4122f0c927321bb58656a12ed5fa56663a6f3a9fd174cff02ab302ee3a6dc3a9e76a241d76ec7a3fcc59f8e46b1906a7c004a35bbd55a58ef40ff0230b934208323d5d5a70303cc0a49cda96f5db775506b3ab7dd49376127076de5ff0264ecf0928ceb7672c5ae1441a9aa2c3bdff0aba3bb2882e73bef87d4492abb9c03d0ff025c367d3618505f9632e87fe6a16e631c8ca30d9b1b65b524147140ff0273b84ef9632c5ce6cbb4bd35890830a61510d2a205e5fcf1f4ff02511d28fc76b6190aa189c061557af17bde6c8941bbcbbf8aa255f7ff025a123662c71d9f10b037466092fd338fb73c93fdcd030b1d1be2ff02c1518d4627b724dc6b39638572f94fb5f9abd01b2ca17ccb80ff0246a48ea96bbb2b650f66d885f86e8458e602ae1ef82b2cedee8b005eeb449428ff024d2caea756b0c73417c1d1044773ef81e55aa3d8413fe14327552919e86dfb671eb4cc420a20ff024e16c891609a7b7625085a4960d03eef28ce019beac86613a119d81f6c86ff029094edbf3d8d1006b5d2f403c615f259884788c09c0e8e5d7fa7dc1ec80f28ff028391a866e99e941b3840be6134078e4b4508e35a09aaa39aa0ff02dbf3a6cc698f32ddfcde5db60a26737e3ce00da7174e495daf92b0ff0209bd9b8c2d6ab430f2f3b75802e5d444aca832b2d7130c00a347e41bb7fd5f28ff027c4ff793c4f301fd34dfded06402a822bf862500b72402d9038ba24758dea50810ff0204de4b7f19c4292fea31b891deb3c446df99c3d8322a4564ff027e8ed1e601c9fa53703b1c16e2a637b56be9dbf4059c01c3afc3fdeb84576e8da3ab40ff022a1749b944c3f6eeb409052c723a2c116aa6f0316c7bc06cf373aaff024b7d86eb64cde2c91f45585e6d4e2b0258291819e10dd38f5d6c80ff024b01e424b2ac1294112bd3eff120c77c44226202ce9f76b163678b9fa988ff025197fe5b6ba189ba1142092a0ac9fe8150c5eaed7afeff0259bc5bbfb24f34f1a79c402aaeff0210765cc5c0c9fb2e6679d75c02f0d5a180ff029cac460c496054641b6b6c7b8a51851cff02551d7ab98e46f269fac585e3e341ff02634cc8e13acb108fa10ff3b4ff02bd5a929e5067cd061c1ecddc56b8ff0222bc9a1e14ca3e985d72976080e0f8ff028f5b789afadd520cab890c7d68ff02cd4ae84089ff02937320ff02d7ff02ff02ff02ff02ff0280ff02ff02c3f2c168ff025d2097a0ff02598aa0ff02850439bdff02691d6c07cc12e7c0ff020beff58298cd73e99316ff025e9351a90d0920491922be2fc0ff029ca329dae08b19246890ad200b8c3aedbe3d5877a4ff025c409d2d18c6aac7574ec4e6181f0da7cc00e97063646f1a44977fe85a73cc590e9c72d319b2c94c98aac4ff026a91cb9f3d3c4577213e0d576533fa5a07ef222fef0c981943fc3c39cadab203e975e5b5457053d10040c64da910145b6ab9dd8f7605e9c937ff026091d1abcd0e085c7d8f08948d01866c8d6162f77b69009fcdcb7f4242259909aaa808600e73343bbe274ae330e58cb53ccd30895880ff022bb15980affb8a43f58ab7b007d535e462fdc2e55612a779687283ebb07491d2087045d8b0a798583832188f8b43d283bf23beea0344c7230cff02e1aa58cfdf1ed79d4f01c28c3ca43162fb596089e8122f46e9e3a8322feabc03509844f361d6b74eb16d520ad97cd4ae3f2971400f3b3713fc82f8ff024bee2a5cb707487f0888ac6cd2ef385975fe9d340bd790fe119a22f409cfde406e6049a9163e8f19acb6dd2299b78b973dff024afcc9137c2a95fd510bc7fca16e19a34af1889adb6cc2cfbc0e38643cf7b7119398100f2846c1aa7fb0ff024f1dd3564f7e238b55c7e01b696afb1958112a6a8d75e41daa9c634b55f666d8001f147ed016afe0ff02134521d2befe186841b4a6bc654d0df4a39cefab1bb3a50a3a722e0b7f25b99ca3ecf7ba5da8da669f6cccff02128f8779d49954ff0030e42104302c4be063c8ee115c1f13b205cafa4786169dbbf8fd53fb426cc86a6804ff02188411a9a962be09d6faf4b98d19b28557fe554969fb9dc1d15c74f4e6d583ec67772bd2efff020b3707a2f8a3aeab541dde39f8b54a047b5b9b1711ecc14f41b752de18cc8ace35d9eb4b81f83875e0db464ebe80ff0284244a1f6c3f5262369aaca88b8693122f7ea793e518d23e90656bfc76c68cde0bfb1f1edace177216f12a58e808a7e4ff02377c65a38b12a3ab4e19cc3134455c2d9f143ec6b99b454015311f5e56f9139e3a720387ef75fba607130f0ec1ba5eaf60eb84ff021f55495f6159e960cb337f44f707ef2b4b018e24db9699fac19eb329e8adbb452c44d081c05b9b8eac40ff023f2a8d38779f16099ef10cd015ba0f4abf7521f215a49ac305815f759d1e68c7cc33c776aa729cc3d7602ca6c5ba5778ff02cbfc9f609256c5fdeeded52c7fc4b92d8e18d45bf9c96d155d4efbea7be0553af0478dc04768a6dea21a5510ff0287378e076b01350bcd281acd93fe8a28a69ff7440cb7fc0f3bd2d43617bb2ee9e571fbdba7cb485ee579c73ced3c8fff02d92a2f890cdaa00afcb65c4419dc3c2d97d62b33a242718f48ff00a2c2487473e7990631326226c6747f274fa5d0b6a71f045b2be11c91f9cbc070ff0298c802325f04565324f020290476bb46e1a2d6bb9319536d4e41ba4d68ae54bc10f9252e5053998cca1b80ff024b539b9236f91fdd10627ad9f77b5f9dd74f44c2f9addb2578730f6e91c4ba8b6f9f1fc8c752d9687a122c2213b387a054c810425ae40250d140ff02198222e7ca3985da2e3d75e41af80fba430a529258a09021a01ba6fc37b3d73fac47056d524cf7d48af9b927f69320ff020963a54a9ae6de723eeb2aff00e93421c1c3e599ca131ea5d9c0b4582e13d60d4b48723a03cfdda6aae79aff022655f7e751a19acd4f4917695f6b2ba77417c7e0f0b0c7a40dcb74f326363c5f6c39396d49cbc695adefb70f6be0ff020f65ab7da7134b8570508dd008c5ac366396393370c2a807c051d651608156ff027544721b6933621d8e8fbd3be55d97d056c2a833eb8c380a80ff022aa031305736d65d6b64eb10c569c8d4452768299d59a431e930ff026f67d3e8c63980aa22a9baa7b6ae8f4f84d8b1810581f868ff02275d4bec8a3edf5724010c9f40c321a811a2cb03ff024d176c5fcbf4523912c2db88586fed8d51c9e219ff028d449599be56448438c0de592d2545feec692a2481cae32f09813b2a38ff020fb0dbc9a9b94b0956406da5cd8d595e06670263fd663463b09aa0ff0206c99c509803b59bd548c5b7d0fefcad714f14ff0276243b6033a658ff024a3cff02ff02ff02ff02ff02ff0280ff02ff0218d9ff026e1e617460a126ff0106e1a680ff02112af812576a80ff021b9ce5f1b786f2ac2d50f63a60ff0de51471fc7dbd118083e4946506ff027ff276578af895cb1bff0033a49b9cd6ff02cdfb940495c6927368e03f471eb7a0743524d39658f1e4e9584cfc27caa0b5ff021d7d4cdcf1edcaa115a0e2cecf15d67c6df51836c9e78e7617ce6ad6ebda759c792668237b6f9aebb37b856d3ba8f766c2ac5e5cf75ac683dc4ae21c0a8c4a4d31e54fe5476ee8845560ff02eccfa8cddd3b970267c5a98b02d5a8f13f24f6d85d2e393f060a80d79b66a9d996b710c3d90a694f81a8862c132cd0c085d31f77599a4a2694ad37c9a5ec9d51f8f620282ff45af919ee6b77793e4072e1f0d3901ed692f91a80ff022870616804302838aa8d10d388eca464da8e269350dff10458ece1347cc785540b2da891756b36aee0a02e7b1ade2a00f3e81632c780f266e0cf64ca5b02913c15b069f9875a79513ff0dd37e166bd5e7b67d543a0ff02c4cadd00dc62de31a2444a611b705253973796ee5cd1d61cb0e19be24b18fe068656717aa0370bc90f9deb2b4bc187b4eb3aac6166199d3ad6531a82ef1ff0114f551afafd1d00a831ab4c806f0e64bf6a824ec18a924f40ff020361446a02ce87b456e2ae57cba22c64a38c27730dbefdca6ce39c4b2d4728f000572e09e2bb1d876b35b40637902f24bf0f4d34a2288c191bef4d264f7d9497fdd1c946e2e749de3b8c9edc1613ef8eff00808f88600f0b2d786af71d90ff026cc1d1aa7ae3cd863efefb11d53264f128975141d5dfa4aec3bac15d48f638b14d952707821e856ce2df9fd909238d5c4661a401269f193f74afe628217dd59401f3ca73c8045f8735060aa96050ff02f7b1ad5e7ecbea3d3266e0ae897fbd8ff34d1edc37440eb29a8251068d803f43b7f6b7eae5cf8c0b1d7069517c757ec110ae02effb9929e5aba315f198317c21958543cc2dc9c0ff0226a02904faa9d80ca2454c9e9e97212c7e8e422d6ca7c537c347641d3b81bc38e811bde4392f8b90ef8c4bc204bbd1885243d8931801e270b0a5100288839db102f9a878f304726dae8580ff02531529bf160b7f6dda8b087a1ea80e82a2ed1c3566804c0343ca68052d31ff00b33c6fedf379b2b5df9f1bacfda414288eba0850798b592c8ec49c20ac4fdfafa798497d56d3f01f349a488d07b8c54fecadd0ff02174a6e5d7b8e82be88819f25e944b20fd7fc47a5e67a5d1ed6f9056c86c46146826c26964f42c25b13df0ee600950ebd45056ed959bf8136811065227193b3becd501cae3a8b50246366c1ebf0332d004d7664ff02898023aacc48928c885f76d0d1a89bf9d0cfc2eddaa55c03ead06f7a406293cb78e014f4577da9ccacc13e12a1e7fb0f0fa64da1c917df9cdd122a2c87c8a62b80ff0229782d208855baf90d7efd377af4e9b17fe4fed608d6ac8566830026c551dbcaaaecafc85e9f25e63b9ea37ff4a8de4ff09d7482d668a1e3a049f1f0aaee5fc3bca31a9b5697ff026b60f5bad5dbd868e35c8c478301026e6601d9eff8a2f8bb3afc60f874d3cf714f8c0829e94e3815e62150db7b6072cd7f9a0aa4c294281d53dadc1c7d3875fe48ff026e74886871516ff7b28cb2fb8a20c03504c03882e83d0eb1f53880ce7aa76c92fd45edcd3090075b3b111a8b8fa5d26249a4e6a02b724dec5b693d4fa72217230893966f29c94b2b1071daeaac973efa0daa20ff0291b44b9307ca5d3a023a2fca1d798f113a15746532e14eaf7c517abacdfbc8af0a5b9e235e79cfe33eef116db3d384b62bd88d9f861eb01f813fcb60e7e2e550810e9f16c4df1836a18b21be80ff02b3ccac6aa3fcbf9f86c72a68f94dba09e10a2c9b71bf534b83c44e7933e8c9b50494cab89567f7d42b92f0b51dcc16b524946420d283fca79415057744b8ff024a6b416164eeb4fd2e4e6f008e2806f45734c3d910ab6124a72036cca9ec0664bcb33825830b565a3ccd8b928665a6db37d5dbed47296d4fbcdfa5156ca19c25ff0251522cde186e8b3fc7053d005cc64c7edcc8369342e01e76b115f7b3d0547f1df3cdc1974f8d48a3cc65fc9b830ad99a8cf0ff00770bdc6f7b14efd756b4a21df0afe0a2ff027a1f7832d269a5c5749e71edb043429be7441908f6303481658314e23a7d0b51b89f4d4895bf13d99e5bd47fdde8aed51333c0f8c5d25e6748227da25306ef460a5728744957a5ef3364ad0376965516f13193fe036ead84f06b2e1e96b1ff02e9f4604cc796d47608b08013fde2b7cc8239b237b7de42669b2be932ec8047809bfc0eaca0c7d0f8f4dee86a53e9167e824124fe080bb77d396eeccbd32fdacd407f3779ff0226724fb9aab527f63b0d376010206126e4dbe07657f11f094474ae59dd8b3dc34fb710e97a968205e60efe54b719624b4ba69a504bcd0c1889a2b658252f92aeccd72087a0ca7deae35f12f435f7186a5294b01f6b1220f9bd1cb0d53f4c1506ecce36a41f9520ff0273b42eff0067a67d6fdf37381905505e6e1aa43daa90552a5e744e17a5b453edbf7d581faa2d9efe9e68fa054b4ae52091b411182994c40950fc0c8b0f51fdf763290b49bb65245cc337eacc82ff021b1c180c13e7dc9323fb4330610c0348b48a09821e02db6ea33c48085249f39f6c4039551e298c4950800e4c09b247bcde05b58513c418cdd70436c8dfd42882125f39b3485210715ee69b50182fff022a3b97842fa40b5cb9471e7deaa32671f5cbdee74314d83cfb9af7ae4c5839c634c217daa12ec57e185bb58937f9d5099ce0de1e5a46556f8bb0911e47cef6d69f33bd979d8ac0ff0205779cb46d589e6a9c57252aa7140f1dfd968e3ab49be4a7b58699e7941f47feb1f2b329e919e9f5c9bbd04edd4b2507b450ff0270e9a0204e241835a54f3b2874fabb7fd713c34e77723a95ac4366749b1edd6e847426310c3dcc6bc16c96bf68ff025dc13b5e3efefac68f835463d53e8c12b07c01323f40c57f2d47ec7d45c7772be2686330d231d916a420ff0277dcf1c6069528a66ed2e1d3040bc7449b11e7afbb7d0205dbbfd37922b72670598c8799c6961132cc40ff02b1aaa2ea28500cb24089199b6757c196ee0e1faf6d1d5cb9b3c0031d91bdbefee7f0a980ff024db7732ddfbe7320849d0e20bf930a60837af776cebff6e9780888ca818f5e419300feff02c0d511f2343e1d14cbcd86b2655699b937943b9c8be640000491c19fb7dcd5762978ff0002634eacdba4ff00bda577890e261d8780ff02195526190f0fbb0831a804bb79ff005a3171b77d75e18703a553c39aa4eb0c4f50aeb69356fbc905db0360bef48e193a1accd243c86154ff025a5962cba0a0244fe9281241915c2b8f8f5ad0812ced0f0c342bd2d26efcff028f79e7ef0e32b33db83c874648ff023baaff02ff02ff02ff02ff02ff02");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.mon.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 mons.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 /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 = pile("\\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 /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 /11/5*@desc 去除文件中存在的回车,换行 符(c)*@return java.lang.String**/public static String removeSpacilChar(String str){String spacilChar = null;if (StringUtils.isNotBlank(str)){// Pattern pattern = pile("\\s*|\t|\r|\n");Matcher matcher = PATTERN_REGX.matcher(str);spacilChar = matcher.replaceAll("");}return spacilChar;}/***@author lxw*@date /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 /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 /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 /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 /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 /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 "01"://预售基金reqData.put("templateName","ZNZJJFTemplate.html");break;case "03"://维修基金reqData.put("templateName","ZNZJJFTemplate.html");break;case "03"://水费缴费//req03Hander(reqData);reqData.put("templateName","ZNSFJFTemplate.html");break;case "07": //广电缴费//req07Hander(reqData);reqData.put("templateName","ZNGDJFTemplate.html");break;case "07": //电费缴费(兴义)reqData.put("templateName","ZNDFJFTemplate.html");break;case "02": //电费缴费(全省-兴义)包含 撤销reqData.put("templateName","ZNDFJFTemplate.html");break;case "041": //欠款还款//req041Hander(reqData);reqData.put("templateName","DKHKTemplate.html");break;case "042": //提前还本reqData.put("templateName","XDTQHBTemplate.html");break;case "044": //结清贷款//req2044Hander(reqData);reqData.put("templateName","XDTQHBTemplate.html");break;case "04": //短信签约变更(签约、解约、变更)//req04Hander(reqData);reqData.put("templateName","ZNDXQYTemplate.html");break;case "01": //助农取款reqData.put("templateName","ZNWDMTemplate.html");break;case "02": //助农转账//req02Hander(reqData);reqData.put("templateName","ZNTRANTemplate.html");break;case "05": //电费预缴费(全省)reqData.put("templateName","ZNDFJFTemplate.html");break;case "03": //电费缴费撤销(全省)reqData.put("templateName","ZNDFJFCXTemplate.html");break;case "08": //电费缴费撤销(兴义)reqData.put("templateName","ZNDFJFCXTemplate.html");break;case "03": //定期转出//req031Hander(reqData);reqData.put("templateName","CCTDQZCTemplate.html");break;case "02": //活期转存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 /11/23*@desc 判断金额是否为全数字(包含小数)*@param amt*@return boolean**/public static boolean numberHandler(String amt){Pattern pattern = pile("([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 /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 /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 :-)*/@Testpublic void shouldAnswerWithTrue(){assertTrue( true );}/*** 测试图片数据生成jpg图片* @throws Exception*/@Testpublic void imgCreateOrViewTest() throws Exception{//测试图片数据转换成图片String imageData ="0000000006560000018c000000020800031cff02ff02ff02e9efbf0bff021e70ff02557cf2ff027efaf810ff02862e30bcb067b0ff027d61f1c8e025e0ff02988553d2d6c1f518d53639c0ff0216f5a1fcebc641fc888655c42e6f3d0462e318ff02c49be605fcf8d45a66a918a4a1dfc837158a7f15a371f7880c5dbd5427e3c87813a0ff026309cb5f02953e10c9c4122f0c927321bb58656a12ed5fa56663a6f3a9fd174cff02ab302ee3a6dc3a9e76a241d76ec7a3fcc59f8e46b1906a7c004a35bbd55a58ef40ff0230b934208323d5d5a70303cc0a49cda96f5db775506b3ab7dd49376127076de5ff0264ecf0928ceb7672c5ae1441a9aa2c3bdff0aba3bb2882e73bef87d4492abb9c03d0ff025c367d3618505f9632e87fe6a16e631c8ca30d9b1b65b524147140ff0273b84ef9632c5ce6cbb4bd35890830a61510d2a205e5fcf1f4ff02511d28fc76b6190aa189c061557af17bde6c8941bbcbbf8aa255f7ff025a123662c71d9f10b037466092fd338fb73c93fdcd030b1d1be2ff02c1518d4627b724dc6b39638572f94fb5f9abd01b2ca17ccb80ff0246a48ea96bbb2b650f66d885f86e8458e602ae1ef82b2cedee8b005eeb449428ff024d2caea756b0c73417c1d1044773ef81e55aa3d8413fe14327552919e86dfb671eb4cc420a20ff024e16c891609a7b7625085a4960d03eef28ce019beac86613a119d81f6c86ff029094edbf3d8d1006b5d2f403c615f259884788c09c0e8e5d7fa7dc1ec80f28ff028391a866e99e941b3840be6134078e4b4508e35a09aaa39aa0ff02dbf3a6cc698f32ddfcde5db60a26737e3ce00da7174e495daf92b0ff0209bd9b8c2d6ab430f2f3b75802e5d444aca832b2d7130c00a347e41bb7fd5f28ff027c4ff793c4f301fd34dfded06402a822bf862500b72402d9038ba24758dea50810ff0204de4b7f19c4292fea31b891deb3c446df99c3d8322a4564ff027e8ed1e601c9fa53703b1c16e2a637b56be9dbf4059c01c3afc3fdeb84576e8da3ab40ff022a1749b944c3f6eeb409052c723a2c116aa6f0316c7bc06cf373aaff024b7d86eb64cde2c91f45585e6d4e2b0258291819e10dd38f5d6c80ff024b01e424b2ac1294112bd3eff120c77c44226202ce9f76b163678b9fa988ff025197fe5b6ba189ba1142092a0ac9fe8150c5eaed7afeff0259bc5bbfb24f34f1a79c402aaeff0210765cc5c0c9fb2e6679d75c02f0d5a180ff029cac460c496054641b6b6c7b8a51851cff02551d7ab98e46f269fac585e3e341ff02634cc8e13acb108fa10ff3b4ff02bd5a929e5067cd061c1ecddc56b8ff0222bc9a1e14ca3e985d72976080e0f8ff028f5b789afadd520cab890c7d68ff02cd4ae84089ff02937320ff02d7ff02ff02ff02ff02ff0280ff02ff02c3f2c168ff025d2097a0ff02598aa0ff02850439bdff02691d6c07cc12e7c0ff020beff58298cd73e99316ff025e9351a90d0920491922be2fc0ff029ca329dae08b19246890ad200b8c3aedbe3d5877a4ff025c409d2d18c6aac7574ec4e6181f0da7cc00e97063646f1a44977fe85a73cc590e9c72d319b2c94c98aac4ff026a91cb9f3d3c4577213e0d576533fa5a07ef222fef0c981943fc3c39cadab203e975e5b5457053d10040c64da910145b6ab9dd8f7605e9c937ff026091d1abcd0e085c7d8f08948d01866c8d6162f77b69009fcdcb7f4242259909aaa808600e73343bbe274ae330e58cb53ccd30895880ff022bb15980affb8a43f58ab7b007d535e462fdc2e55612a779687283ebb07491d2087045d8b0a798583832188f8b43d283bf23beea0344c7230cff02e1aa58cfdf1ed79d4f01c28c3ca43162fb596089e8122f46e9e3a8322feabc03509844f361d6b74eb16d520ad97cd4ae3f2971400f3b3713fc82f8ff024bee2a5cb707487f0888ac6cd2ef385975fe9d340bd790fe119a22f409cfde406e6049a9163e8f19acb6dd2299b78b973dff024afcc9137c2a95fd510bc7fca16e19a34af1889adb6cc2cfbc0e38643cf7b7119398100f2846c1aa7fb0ff024f1dd3564f7e238b55c7e01b696afb1958112a6a8d75e41daa9c634b55f666d8001f147ed016afe0ff02134521d2befe186841b4a6bc654d0df4a39cefab1bb3a50a3a722e0b7f25b99ca3ecf7ba5da8da669f6cccff02128f8779d49954ff0030e42104302c4be063c8ee115c1f13b205cafa4786169dbbf8fd53fb426cc86a6804ff02188411a9a962be09d6faf4b98d19b28557fe554969fb9dc1d15c74f4e6d583ec67772bd2efff020b3707a2f8a3aeab541dde39f8b54a047b5b9b1711ecc14f41b752de18cc8ace35d9eb4b81f83875e0db464ebe80ff0284244a1f6c3f5262369aaca88b8693122f7ea793e518d23e90656bfc76c68cde0bfb1f1edace177216f12a58e808a7e4ff02377c65a38b12a3ab4e19cc3134455c2d9f143ec6b99b454015311f5e56f9139e3a720387ef75fba607130f0ec1ba5eaf60eb84ff021f55495f6159e960cb337f44f707ef2b4b018e24db9699fac19eb329e8adbb452c44d081c05b9b8eac40ff023f2a8d38779f16099ef10cd015ba0f4abf7521f215a49ac305815f759d1e68c7cc33c776aa729cc3d7602ca6c5ba5778ff02cbfc9f609256c5fdeeded52c7fc4b92d8e18d45bf9c96d155d4efbea7be0553af0478dc04768a6dea21a5510ff0287378e076b01350bcd281acd93fe8a28a69ff7440cb7fc0f3bd2d43617bb2ee9e571fbdba7cb485ee579c73ced3c8fff02d92a2f890cdaa00afcb65c4419dc3c2d97d62b33a242718f48ff00a2c2487473e7990631326226c6747f274fa5d0b6a71f045b2be11c91f9cbc070ff0298c802325f04565324f020290476bb46e1a2d6bb9319536d4e41ba4d68ae54bc10f9252e5053998cca1b80ff024b539b9236f91fdd10627ad9f77b5f9dd74f44c2f9addb2578730f6e91c4ba8b6f9f1fc8c752d9687a122c2213b387a054c810425ae40250d140ff02198222e7ca3985da2e3d75e41af80fba430a529258a09021a01ba6fc37b3d73fac47056d524cf7d48af9b927f69320ff020963a54a9ae6de723eeb2aff00e93421c1c3e599ca131ea5d9c0b4582e13d60d4b48723a03cfdda6aae79aff022655f7e751a19acd4f4917695f6b2ba77417c7e0f0b0c7a40dcb74f326363c5f6c39396d49cbc695adefb70f6be0ff020f65ab7da7134b8570508dd008c5ac366396393370c2a807c051d651608156ff027544721b6933621d8e8fbd3be55d97d056c2a833eb8c380a80ff022aa031305736d65d6b64eb10c569c8d4452768299d59a431e930ff026f67d3e8c63980aa22a9baa7b6ae8f4f84d8b1810581f868ff02275d4bec8a3edf5724010c9f40c321a811a2cb03ff024d176c5fcbf4523912c2db88586fed8d51c9e219ff028d449599be56448438c0de592d2545feec692a2481cae32f09813b2a38ff020fb0dbc9a9b94b0956406da5cd8d595e06670263fd663463b09aa0ff0206c99c509803b59bd548c5b7d0fefcad714f14ff0276243b6033a658ff024a3cff02ff02ff02ff02ff02ff0280ff02ff0218d9ff026e1e617460a126ff0106e1a680ff02112af812576a80ff021b9ce5f1b786f2ac2d50f63a60ff0de51471fc7dbd118083e4946506ff027ff276578af895cb1bff0033a49b9cd6ff02cdfb940495c6927368e03f471eb7a0743524d39658f1e4e9584cfc27caa0b5ff021d7d4cdcf1edcaa115a0e2cecf15d67c6df51836c9e78e7617ce6ad6ebda759c792668237b6f9aebb37b856d3ba8f766c2ac5e5cf75ac683dc4ae21c0a8c4a4d31e54fe5476ee8845560ff02eccfa8cddd3b970267c5a98b02d5a8f13f24f6d85d2e393f060a80d79b66a9d996b710c3d90a694f81a8862c132cd0c085d31f77599a4a2694ad37c9a5ec9d51f8f620282ff45af919ee6b77793e4072e1f0d3901ed692f91a80ff022870616804302838aa8d10d388eca464da8e269350dff10458ece1347cc785540b2da891756b36aee0a02e7b1ade2a00f3e81632c780f266e0cf64ca5b02913c15b069f9875a79513ff0dd37e166bd5e7b67d543a0ff02c4cadd00dc62de31a2444a611b705253973796ee5cd1d61cb0e19be24b18fe068656717aa0370bc90f9deb2b4bc187b4eb3aac6166199d3ad6531a82ef1ff0114f551afafd1d00a831ab4c806f0e64bf6a824ec18a924f40ff020361446a02ce87b456e2ae57cba22c64a38c27730dbefdca6ce39c4b2d4728f000572e09e2bb1d876b35b40637902f24bf0f4d34a2288c191bef4d264f7d9497fdd1c946e2e749de3b8c9edc1613ef8eff00808f88600f0b2d786af71d90ff026cc1d1aa7ae3cd863efefb11d53264f128975141d5dfa4aec3bac15d48f638b14d952707821e856ce2df9fd909238d5c4661a401269f193f74afe628217dd59401f3ca73c8045f8735060aa96050ff02f7b1ad5e7ecbea3d3266e0ae897fbd8ff34d1edc37440eb29a8251068d803f43b7f6b7eae5cf8c0b1d7069517c757ec110ae02effb9929e5aba315f198317c21958543cc2dc9c0ff0226a02904faa9d80ca2454c9e9e97212c7e8e422d6ca7c537c347641d3b81bc38e811bde4392f8b90ef8c4bc204bbd1885243d8931801e270b0a5100288839db102f9a878f304726dae8580ff02531529bf160b7f6dda8b087a1ea80e82a2ed1c3566804c0343ca68052d31ff00b33c6fedf379b2b5df9f1bacfda414288eba0850798b592c8ec49c20ac4fdfafa798497d56d3f01f349a488d07b8c54fecadd0ff02174a6e5d7b8e82be88819f25e944b20fd7fc47a5e67a5d1ed6f9056c86c46146826c26964f42c25b13df0ee600950ebd45056ed959bf8136811065227193b3becd501cae3a8b50246366c1ebf0332d004d7664ff02898023aacc48928c885f76d0d1a89bf9d0cfc2eddaa55c03ead06f7a406293cb78e014f4577da9ccacc13e12a1e7fb0f0fa64da1c917df9cdd122a2c87c8a62b80ff0229782d208855baf90d7efd377af4e9b17fe4fed608d6ac8566830026c551dbcaaaecafc85e9f25e63b9ea37ff4a8de4ff09d7482d668a1e3a049f1f0aaee5fc3bca31a9b5697ff026b60f5bad5dbd868e35c8c478301026e6601d9eff8a2f8bb3afc60f874d3cf714f8c0829e94e3815e62150db7b6072cd7f9a0aa4c294281d53dadc1c7d3875fe48ff026e74886871516ff7b28cb2fb8a20c03504c03882e83d0eb1f53880ce7aa76c92fd45edcd3090075b3b111a8b8fa5d26249a4e6a02b724dec5b693d4fa72217230893966f29c94b2b1071daeaac973efa0daa20ff0291b44b9307ca5d3a023a2fca1d798f113a15746532e14eaf7c517abacdfbc8af0a5b9e235e79cfe33eef116db3d384b62bd88d9f861eb01f813fcb60e7e2e550810e9f16c4df1836a18b21be80ff02b3ccac6aa3fcbf9f86c72a68f94dba09e10a2c9b71bf534b83c44e7933e8c9b50494cab89567f7d42b92f0b51dcc16b524946420d283fca79415057744b8ff024a6b416164eeb4fd2e4e6f008e2806f45734c3d910ab6124a72036cca9ec0664bcb33825830b565a3ccd8b928665a6db37d5dbed47296d4fbcdfa5156ca19c25ff0251522cde186e8b3fc7053d005cc64c7edcc8369342e01e76b115f7b3d0547f1df3cdc1974f8d48a3cc65fc9b830ad99a8cf0ff00770bdc6f7b14efd756b4a21df0afe0a2ff027a1f7832d269a5c5749e71edb043429be7441908f6303481658314e23a7d0b51b89f4d4895bf13d99e5bd47fdde8aed51333c0f8c5d25e6748227da25306ef460a5728744957a5ef3364ad0376965516f13193fe036ead84f06b2e1e96b1ff02e9f4604cc796d47608b08013fde2b7cc8239b237b7de42669b2be932ec8047809bfc0eaca0c7d0f8f4dee86a53e9167e824124fe080bb77d396eeccbd32fdacd407f3779ff0226724fb9aab527f63b0d376010206126e4dbe07657f11f094474ae59dd8b3dc34fb710e97a968205e60efe54b719624b4ba69a504bcd0c1889a2b658252f92aeccd72087a0ca7deae35f12f435f7186a5294b01f6b1220f9bd1cb0d53f4c1506ecce36a41f9520ff0273b42eff0067a67d6fdf37381905505e6e1aa43daa90552a5e744e17a5b453edbf7d581faa2d9efe9e68fa054b4ae52091b411182994c40950fc0c8b0f51fdf763290b49bb65245cc337eacc82ff021b1c180c13e7dc9323fb4330610c0348b48a09821e02db6ea33c48085249f39f6c4039551e298c4950800e4c09b247bcde05b58513c418cdd70436c8dfd42882125f39b3485210715ee69b50182fff022a3b97842fa40b5cb9471e7deaa32671f5cbdee74314d83cfb9af7ae4c5839c634c217daa12ec57e185bb58937f9d5099ce0de1e5a46556f8bb0911e47cef6d69f33bd979d8ac0ff0205779cb46d589e6a9c57252aa7140f1dfd968e3ab49be4a7b58699e7941f47feb1f2b329e919e9f5c9bbd04edd4b2507b450ff0270e9a0204e241835a54f3b2874fabb7fd713c34e77723a95ac4366749b1edd6e847426310c3dcc6bc16c96bf68ff025dc13b5e3efefac68f835463d53e8c12b07c01323f40c57f2d47ec7d45c7772be2686330d231d916a420ff0277dcf1c6069528a66ed2e1d3040bc7449b11e7afbb7d0205dbbfd37922b72670598c8799c6961132cc40ff02b1aaa2ea28500cb24089199b6757c196ee0e1faf6d1d5cb9b3c0031d91bdbefee7f0a980ff024db7732ddfbe7320849d0e20bf930a60837af776cebff6e9780888ca818f5e419300feff02c0d511f2343e1d14cbcd86b2655699b937943b9c8be640000491c19fb7dcd5762978ff0002634eacdba4ff00bda577890e261d8780ff02195526190f0fbb0831a804bb79ff005a3171b77d75e18703a553c39aa4eb0c4f50aeb69356fbc905db0360bef48e193a1accd243c86154ff025a5962cba0a0244fe9281241915c2b8f8f5ad0812ced0f0c342bd2d26efcff028f79e7ef0e32b33db83c874648ff023baaff02ff02ff02ff02ff02ff02";//将十六进制的图片信息转换成字节数组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*/@Testpublic 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.mon.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 /6/30 10:19**/@Controllerpublic class MchtPdfCreateController {@Resourceprivate 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.SignResult;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 /6/23 10:21**/public interface CreatePdfService {// public void pdfHandler(PbsEleInvoiceInfo pbsEleInvoiceInfo) throws Exception;/***@author lxw*@date /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.SignAgent;import cn.SignResult;import cn.sign.SignAgentException;import cn.sign.agent.exception.ServerProcessException;import cn.sign.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.mon.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.mon.AmountUtils;import com.ruim.mon.Constants;import com.ruim.mon.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 .HttpURLConnection;import .MalformedURLException;import java.text.DecimalFormat;import java.util.*;/*** @ClassName CreatePdfServiceImpl* @Description* @Author Administrator* @Date /6/23 10:23**/@Service("createPdfService")public class CreatePdfServiceImpl implements CreatePdfService {@Resourceprivate PbsEleInvoiceInfoDao pbsEleInvoiceInfoDao;@Resourceprivate PbsZnorderTicketDao pbsZnorderTicketDao;@Resourceprivate CreatePdfService createPdfService;@Resourceprivate 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 /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 /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 /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 /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 /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 /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 /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 /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 AliControlFlowStatementWithoutBracesif(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 AliControlFlowStatementWithoutBracesif(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 AliControlFlowStatementWithoutBracesif(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 /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 /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 /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 /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 /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 /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 /6/24* @desc 签名**/@Overridepublic 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 /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 /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 AliControlFlowStatementWithoutBracesif (os!=null) {os.close();}} catch (IOException e) {log.error("输入流关闭失败!原因:{}",e.getMessage());}}}/***@author lxw*@date /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 /7/1*@desc pdf信息保存*@param request*@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse**/@Overridepublic 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 /7/3*@desc pdf文件生成处理*@param*@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse**//* @Overridepublic 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 /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 /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 /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 /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 /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": //wordreturn WordCreateHandler(pbsZnorderTicket);case "3": //图片return WordCreateHandler(pbsZnorderTicket);default:throw new Exception("未知的文件生成类型{"+reqData.get("fileType").toString()+"}");}}/***@author lxw*@date /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);//将信息写进模板中 32String 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 /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 /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 /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 /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 /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 /1/5*@desc pdf文件生成和预览*@param request*@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse**/@Overridepublic 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 /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;}@Overridepublic 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 /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("2005.txt");// byte[] decodeBuffer = decoder.decodeBuffer(new String(readPdfFile, "utf-8"));// writePdfFile(decodeBuffer,"viewOrWrite.pdf");// String data = "0000000006560000018c000000020800031cff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02c54c39ef32ca3fa493ad111780ff0207398b6c6042f72b00e1ef2f8e294b2c30ff022c8b150897ac0beae2ae3fcc3ab3e2f4fe6e18ff02312a6df1bcd7215dabfc728543bb756d878ce0ff0212f83ef15d2f92708ea16a8c94a772ff020d63981e4397ec395acfc6dacb5cacf0ff024223c38f60592804793b9f3ff7a888ff025a0a20900d551bada7307d4780ff02758ffd32ff027c599fff02918edcff021128ff028cff029eff0250ff02fdff027c4ea5b16bc0ff027242df4373d134ff02299fbcd4ae10ff02163cff02ff02ff02ff02ff02ff02ff02ff02ff02ff0280ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff023bcec56000d983141658ff022e60ff00b682cc3f0827ea6e90b628305ef67e031f65f9ca28c1418980ff020343af8e64217a32e28668c58aae257f59b1241decd180ff020cd923bc5b2e2297e9121e9f7b8724c19baabe3949e3f8ff005402d08428ff023090d3cfec56f3673d36ae4bc2a14dfcd826f37b859db0ff02155ee06c93332d1715db031778f28a7b07f0e5b8ff0220a62663bb4cdcdab61d4fe4309d5cef61721a80ff0205d62d6b04f8c2fa893aea44c47ec0ec80ff024bf532f09ba890ff028b714f11413cff027e04251180ff0267fd13e360ff0266f0ff02d85fc0ff023b20ff02c572ff02b9f4388b5b5bb2307cff028f84c6bd739dcd25ead604ff020750ae5a15f1d2f9afb24738ec4bab80ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff0280ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02188dc331ac13ad5c437cf6168ec1b48450c5d6c13ca8ff0206d6e2b0f15e2ccc86ac5515585fe3a4e064aad6f823ccb041c3d7bc839c0db17ed446e2cac0ff027da3264b50beafbd5c4a2191203375adf168703c5ece20f9705b3f2c79a12671594e5a7cd3ff0293353a05631b91865a2b5e998df5d48e77cd1d0fd3c0676edbb2ccc3e72c0a0b26056d97537ee609bb0eb3f5e5eaff0219c8e3666873570e8fb7b43341233ae92bce5f7cc54722fe3f31e6094c83160c9fe0b970edff0207f632b91f754ad24969b6ae8f1f6e7f9716056ee42bda4b8a14dc0ff6e0ff02a1782428ece89fac648bc64f32d9dfbe7c91bc9dc52f25c7276c202cda43ff02580b4f942093714c1b95add04f58bd327b6d7e445f2dba24ff029546d1f500b245ff02769f0a406045a440ff0289da7df52936ff0251d0ec93c7ff02ff026b7cff025929b8ff0239e7ff0229402c557c342c8bf9235af6f0ff027bd6952f471f1b94e488d4048e72d7ff02b847a3109eecc1e5d9c53b1264f827399865d0ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02ff02";// 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.mon.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 /6/29 11:04**/@Repository("pbsZnorderTicketDao")public class PbsZnorderTicketDaoImpl extends BaseBatisDao implements PbsZnorderTicketDao {Class<PbsZnorderTicketMapper> pbsZnorderTicketMapper = PbsZnorderTicketMapper.class;@Overridepublic int deleteByPrimaryKey(String txnOrderId) {return getSqlSession().getMapper(pbsZnorderTicketMapper).deleteByPrimaryKey(txnOrderId);}@Overridepublic int insert(PbsZnorderTicket record) {return getSqlSession().getMapper(pbsZnorderTicketMapper).insert(record);}@Overridepublic int insertSelective(PbsZnorderTicket record) throws Exception{return getSqlSession().getMapper(pbsZnorderTicketMapper).insertSelective(record);}@Overridepublic PbsZnorderTicket selectByPrimaryKey(String txnOrderId) {return getSqlSession().getMapper(pbsZnorderTicketMapper).selectByPrimaryKey(txnOrderId);}@Overridepublic int updateByPrimaryKeySelective(PbsZnorderTicket record) {return getSqlSession().getMapper(pbsZnorderTicketMapper).updateByPrimaryKeySelective(record);}@Overridepublic int updateByPrimaryKey(PbsZnorderTicket record) {return getSqlSession().getMapper(pbsZnorderTicketMapper).updateByPrimaryKey(record);}@Overridepublic int insertSelectiveTmp(PbsZnorderTicket record) {return getSqlSession().getMapper(pbsZnorderTicketMapper).insertSelective(record);}}

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/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_TICKETwhere TXN_ORDER_ID = #{txnOrderId,jdbcType=VARCHAR}</select><delete id="deleteByPrimaryKey" parameterType="java.lang.String" >delete from PBS_ZNORDER_TICKETwhere 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_TICKETset 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.monDTO;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="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /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.mon;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.WriterException;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.mon.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 /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.htmlfreemarkerCfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);} catch (Exception e) {e.printStackTrace();}}/***@author lxw*@date /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 /11/5*@desc 去除文件中存在的回车,换行 符(c)*@return java.lang.String**/public static String removeSpacilChar(String str){String spacilChar = null;if (IfspDataVerifyUtil.isNotBlank(str)){Pattern pattern = pile("\\s*|\t|\r|\n");Matcher matcher = pattern.matcher(str);spacilChar = matcher.replaceAll("");}return spacilChar;}/***@author lxw*@date /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 /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 /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 /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 /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 /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 "01"://预售基金reqData.put("templateName","ZNZJJFTemplate.html");break;case "03"://维修基金reqData.put("templateName","ZNZJJFTemplate.html");break;case "03"://水费缴费req03Hander(reqData);reqData.put("templateName","ZNSFJFTemplate.html");break;case "07": //广电缴费req07Hander(reqData);reqData.put("templateName","ZNGDJFTemplate.html");break;case "07": //电费缴费(兴义)reqData.put("templateName","ZNDFJFTemplate.html");break;case "02": //电费缴费(全省-兴义)包含 撤销reqData.put("templateName","ZNDFJFTemplate.html");break;case "041": //欠款还款req041Hander(reqData);reqData.put("templateName","DKHKTemplate.html");break;case "042": //提前还本reqData.put("templateName","XDTQHBTemplate.html");break;case "044": //结清贷款req2044Hander(reqData);reqData.put("templateName","XDTQHBTemplate.html");break;case "04": //短信签约变更(签约、解约、变更)req04Hander(reqData);reqData.put("templateName","ZNDXQYTemplate.html");break;case "01": //助农取款reqData.put("templateName","ZNWDMTemplate.html");break;case "02": //助农转账req02Hander(reqData);reqData.put("templateName","ZNTRANTemplate.html");break;case "05": //电费预缴费(全省)reqData.put("templateName","ZNDFJFTemplate.html");break;case "03": //电费缴费撤销(全省)reqData.put("templateName","ZNDFJFCXTemplate.html");break;case "08": //电费缴费撤销(兴义)reqData.put("templateName","ZNDFJFCXTemplate.html");break;case "03": //定期转出req031Hander(reqData);reqData.put("templateName","CCTDQZCTemplate.html");break;case "02": //活期转存reqData.put("templateName","CCTHQZCTemplate.html");break;default:throw new Exception("未找到对应的小票模板信息");}}/***@author lxw*@date /11/23*@desc 短信签约 业务报文处理*@param reqData*@return void**/public static void req04Hander(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 req07Hander(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 req02Hander(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 req03Hander(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 req041Hander(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 req2044Hander(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 req031Hander(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 /11/23*@desc 判断金额是否为全数字(包含小数)*@param amt*@return boolean**/public static boolean numberHandler(String amt){Pattern pattern = pile("([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 /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 /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.mon;import com.ruim.ifsp.monConstants;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";// 文件类型-PDFpublic 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";//图片类型 jbigpublic 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生成小票预览

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。