佳博蓝牙打印机PDF在线设计模板
业务场景:自定义的模板通过 佳博蓝牙打印机进行打印
1.打印格式通过代码去拼接(麻烦) 2.直接打印pdf(方便,可延伸业务)
最终方案流程:通过html设计打印界面----》html生成pdf文件模板-----》pdf模板填充数据-----》发送给手机端进行打印
通过html设计打印界面(网上找的条码在线设计,进行的二次开发)
二次开发主要代码块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | var head = "<?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><title>" +(parseInt(pdfwidth)-25)+ "|" +(parseInt(pdfheight)-25)+ "</title><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/><style type='text/css' rel='stylesheet'>* { margin: 0; padding: 0; }body { font-family: 'Microsoft YaHei UI'; } " ; var footer = "</body></html>" ; var sourcesvg; var svgtype; //rect一维码(1.bar) use二维码(2.qr) //把一维码元素替换掉 sourcesvg = $( "svg" ).parent().html(); if (sourcesvg != undefined) { if (sourcesvg.indexOf( "<rect x" ) != -1) { svgtype = "bar" ; } else { svgtype = "qr" ; } $( "svg" ).parent().html( "<img class='sourcesvg' style='height: 100%;width: 100%' src='${" + svgtype + "codeImg}'>" ); } //所有img后面都加${img} $( "div[class=hiprint-printPaper-content] img" ).each( function () { $( this ).parent().append( "thimg" ) }); if (svgtype == "bar" ){ $( ".sourcesvg" ).parent().append( "<div class='hibarcode_displayValue'>${code}</div>" ); } var clone = $( 'div.hiprint-printPaper-content' ).clone(); clone.find( '.hiprint-headerLine' ).remove(); clone.find( '.hiprint-footerLine' ).remove(); clone.find( '.hiprint-paperNumber' ).remove(); var html = clone.html(); var reg = new RegExp( "thimg" , "g" ); //g,表示全部替换。 html = html.replace(reg, "</img>" ); //直接写里面会失效 reg = new RegExp( "<br>" , "g" ); //g,表示全部替换。 html = html.replace(reg, "<br/>" ); //直接写里面会失效 //添加pdf尺寸 head = head + "@page{ size:" + pdfwidth + "mm " + pdfheight + "mm; }" ; head = head + "</style></head><body>" ; html = head + html + footer; //console.log(html); //删除所有图片的thimg $( "div[class=hiprint-printPaper-content] img" ).each( function () { var tupian=$( this ).parent().html(); tupian=tupian.substring(0,tupian.indexOf( "thimg" )); $( this ).parent().html(tupian); }); $( ".sourcesvg" ).parent().html(sourcesvg); var blob = new Blob([html], {type: "text/plain;charset=utf-8" }); saveAs(blob,Math.uuid()+ ".html" ); |
下面是JAVA后端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <!--打印pdf生成--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version> 2.3 . 23 </version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version> 5.2 . 0 </version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version> 5.4 . 2 </version> </dependency> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version> 9.0 . 8 </version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version> 3.1 . 0 </version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version> 3.1 . 0 </version> </dependency> <dependency> <groupId>net.sf.barcode4j</groupId> <artifactId>barcode4j-light</artifactId> <version> 2.0 </version> </dependency> <!--pdf生成图片--> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version> 2.0 . 19 </version> </dependency> |
html生成pdf文件模板-----》pdf模板填充数据
说明:这里的打印html模板文件是上传到配置界面的 然后在数据库保存这个html地址 ,然后后台代码下载
主要代码块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | package com.tengnat.mes.configuration.modular.printer.service; import com.tengnat.assist.exception.BusinessException; import com.tengnat.mes.common.consts.ApplicationConst; import com.tengnat.mes.common.enums.IsDelEnum; import com.tengnat.mes.common.utils.file.FileUtil; import com.tengnat.mes.configuration.core.dao.SqlDao; import com.tengnat.mes.configuration.core.utils.BarcodeUtil; import com.tengnat.mes.configuration.core.utils.FreemarkerTemplate; import com.tengnat.mes.configuration.core.utils.PDFUtils; import com.tengnat.mes.configuration.core.utils.QRCodeUtils; import com.tengnat.mes.configuration.modular.printer.dao.PrintTemplateDao; import com.tengnat.mes.configuration.modular.printer.entity.PrintTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Service; import org.springframework.util.ResourceUtils; import org.xhtmlrenderer.simple.PDFRenderer; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by SkinApe on 2020/5/9. * 打印pdf生成 */ @Service public class PrinterPdfService { private String svgtype; @Autowired private PrintTemplateDao printTemplateDao; @Autowired private SqlDao sqlDao; /** * 生成 * @param code 单据 * @param type 模板类型 * @param request * @return */ public List<Map<String,Object>> creatPdf(String code,String type){ //,HttpServletRequest request 这里很纠结springboot打成的jar的锅!!!!!! //String printPath = request.getSession().getServletContext().getRealPath("/")+ "files/print/";//打印路径 String printPath = System.getProperty( "user.dir" )+ "/files/print/" ; //打印路径 String tempathPath = printPath+ "template/" ; //模板路径 String barCodePath = printPath + "images/" ; //一维码路径 String qrCodePath = printPath + "images/" ; //二维码路径 QRCodeUtils.mkdirs(barCodePath); QRCodeUtils.mkdirs(qrCodePath); QRCodeUtils.mkdirs(tempathPath); //根据模板查询对应的执行sql PrintTemplate printTemplate=printTemplateDao.findByPrintIdentifyingAndTemplateTypeAndIsDel(type, "bluetooth" + "" , IsDelEnum.DEL_No.getCode()); Map<String,Object> params = new HashMap<>(); Map<String, Object> valueMap = new HashMap<>(); List<Map> dataMaplist = new ArrayList<>(); //执行查询sql if (printTemplate== null ) { throw new BusinessException( "无打印模板:" +type); } params.put(ApplicationConst.SQL_KEY, printTemplate.getSql()); valueMap.put( "code" , code); params.put(ApplicationConst.SQL_QUERY_VALUE_KEY, valueMap); dataMaplist = sqlDao.findList(params); List<Map<String,Object>> resultlist= new ArrayList<>(); for (Map<String,Object> dataMap:dataMaplist){ //dataMap.put("code","5201314"); String uuid = UUID.randomUUID().toString(); String pdfPath = printPath + uuid + ".pdf" ; //pdf String htmlPath = printPath + uuid + ".html" ; //html try { //下载打印模板 获取打印模板宽度 String pdfwidthHeight=downLoadFromUrl(printTemplate.getTemplateUrl(),uuid+ ".html" ,tempathPath); if (svgtype.equals( "barcodeImg" )){ //生成条形码 File barCodeFile = new File(barCodePath+uuid + "bar.png" ); BarcodeUtil.generateToFile(dataMap.get( "code" ).toString(), BarcodeUtil.IMG_TYPE_PNG, barCodeFile); System.out.println( "生成条形码完成!" ); } else { //生成二维码 String qRCodePath=QRCodeUtils.encode(dataMap.get( "code" ).toString(),qrCodePath,uuid + "qr.png" ); System.out.println( "生成二维码完成!" ); } //生成html FreemarkerTemplate tp = new FreemarkerTemplate( "UTF-8" ); tp.setTemplateDirectoryPath(tempathPath); String osName = System.getProperties().getProperty( "os.name" ); //liunx环境 if (osName.equals( "Linux" )) { dataMap.put( "barcodeImg" , barCodePath+uuid + "bar.png" ); dataMap.put( "qrcodeImg" , qrCodePath+uuid + "qr.png" ); } else { dataMap.put( "barcodeImg" , "/" +barCodePath.replace( "\\" , "/" )+uuid + "bar.png" ); dataMap.put( "qrcodeImg" , "/" +qrCodePath.replace( "\\" , "/" )+uuid + "qr.png" ); } //封装数据 end File htmlFile = new File(htmlPath); tp.processToFile(uuid+ ".html" , dataMap, htmlFile); System.out.println( "生成html完成!" ); //生成pdf PDFUtils.htmlFileToPDFFile(htmlFile, new File(pdfPath), new File(printPath)); System.out.println( "生成pdf完成!" ); //生成图片 //PDFUtils.pdfToImage(pdfPath,printPath+uuid + ".png",Integer.parseInt(pdfwidthHeight.split("\\|")[0])*8); //System.out.println("生成pdf图片完成!"); Map<String,Object> result= new HashMap<>(); result.put( "pdf" , "files/print/" +uuid + ".pdf" ); result.put( "pdfWidth" ,pdfwidthHeight.split( "\\|" )[ 0 ]); result.put( "pdfHeight" ,pdfwidthHeight.split( "\\|" )[ 1 ]); result.put( "code" ,code); resultlist.add(result); //删除刚刚生成的内容 除了pdf FileUtil.deleteFile(printPath, 1 , new String[]{uuid}); //throw new BusinessException("删除的路径:"+FileUtil.chu()); } catch (IOException e) { e.printStackTrace(); } catch (Throwable throwable) { throwable.printStackTrace(); } } return resultlist; } /** * 下载打印模板 获取打印模板宽度 和 高度 * @param urlStr * @param fileName * @param savePath * @throws IOException */ public String downLoadFromUrl(String urlStr,String fileName,String savePath) throws IOException{ URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //设置超时间为3秒 conn.setConnectTimeout( 3 * 1000 ); //防止屏蔽程序抓取而返回403错误 conn.setRequestProperty( "User-Agent" , "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)" ); //得到输入流 InputStream inputStream = conn.getInputStream(); byte [] buffer = new byte [ 1024 ]; int len = 0 ; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while ((len = inputStream.read(buffer)) != - 1 ) { bos.write(buffer, 0 , len); } bos.close(); //获取自己数组 byte [] getData =bos.toByteArray(); //文件保存位置 File saveDir = new File(savePath); if (!saveDir.exists()){ saveDir.mkdir(); } File file = new File(saveDir+File.separator+fileName); FileOutputStream fos = new FileOutputStream(file); fos.write(getData); String pdfwidthHeight = "0" ; String str = new String(getData); if (str.indexOf( "barcodeImg" )!=- 1 ){ svgtype= "barcodeImg" ; } else { svgtype= "qrcodeImg" ; } //设置匹配规则 String regStr = "<title.*>(.*)</title>" ; Pattern pattern = Pattern.compile(regStr); while (str != null ) { Matcher m = pattern.matcher(str); if (m.find()) { pdfwidthHeight=m.group( 1 ); break ; } } if (fos!= null ){ fos.close(); } if (inputStream!= null ){ inputStream.close(); } return pdfwidthHeight; } } |
佳博蓝牙打印PDFAndroid源码:https://www.baldhome.com/article/40
解压密码!!!!
关注光头e家回复佳博蓝牙打印
本文为程序员之家原创文章,转载无需和我联系,但请注明来自程序员之家www.baldhome.com