最近接到一个需求:在需要打印PDF面单的时候,为了提高业务效率,包装员不必手动下载PDF后再手动操作打印,要实现自动驱动打印机来打印PDF。
思路:pdf面单存在服务器上,打印机是连接包装员的电脑的。在每个包装员电脑上安装一个打印接口服务(远程获取PDF保存到本地,然后直接驱动打印机打印,打印完删除本地文件),当业务流程走到需要打印PDF的时候,调用对应的接口(每个包装员对应一个打印接口)打印PDF面单。
首先确定怎么打印PDF:
引用Apache的pdfbox-tools开源项目,驱动打印机打印本地PDF文件(不支持打印远程pdf文件)。
- <dependency>
- <groupId>org.apache.pdfbox</groupId>
- <artifactId>pdfbox-tools</artifactId>
- <version>2.0.11</version>
- </dependency>
打印PDF只须调用PrintPDF类的main方法即可^_^
- public static void main(String[] args) {//test
- String printerName = "PDFCreator";//打印机名
- String pdfFilePath = "D:/pdf/39488.pdf";//pdf路径
- try {
- PrintPDF.main(new String[] {
- "-silentPrint",// 静默打印
- // "-password","abcde",//pdf打开密码
- "-printerName", printerName,// 指定打印机名
- "-orientation", "auto",// 打印方向,auto|landscape|portrait三种可选
- pdfFilePath // 打印PDF文档的路径
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
然后写个打印接口服务,一个简单的Spring-Boot接口项目从远程(erp服务拿到pdf文件,直接驱动打印机打印)下载pdf到打印接口本地,然后直接打印,打印完成,删除本地文件。然后打成jar包,得到pdfPrintSoa-0.0.1-SNAPSHOT.jar
- //打印接口服务
- @RestController
- @EnableAutoConfiguration
- @RequestMapping("/")
- public class PdfController {
-
- //从远程(erp服务拿到pdf文件,直接驱动打印机打印)下载pdf到打印接口本地,然后直接打印,打印完成,删除本地文件
- @RequestMapping("printPdfByUrl")
- @ResponseBody
- public boolean printPdfByUrl(@RequestBody PdfParam pdf) {
- String orderNo = null;
- try {
- String printerName = pdf.getPrinterName();//打印机名
- String url = pdf.getUrl();//pdf远程url
- orderNo = pdf.getOrderNo();
- System.out.println("printerName:" + printerName + ", orderNo:" + orderNo);
- if(null == printerName || url == null || orderNo == null) {
- System.out.println("参数不能为空");
- return false;
- }
- //pdf下载到本地临时存放
- String pdfFilePath = "C:/pdf/" + orderNo + ".pdf";
- downloadNet(url,pdfFilePath);// 下载网络文件
- if(!new File(pdfFilePath).exists()){
- System.out.println(pdfFilePath + " not exist!");
- return false;
- }
- PrintPDF.main(new String[]{
- "-silentPrint",//静默打印
- // "-password","abcde",//pdf打开密码
- "-printerName",printerName ,//指定打印机名
- "-orientation","auto",//打印方向,auto|landscape|portrait三种可选
- pdfFilePath//打印PDF文档的路径
- });
- deleteFile(pdfFilePath);//删除打印完的文件
- System.out.println("orderNo:" + orderNo + "pdf面单打印成功!");
- return true;
- }catch(Exception e){
- e.printStackTrace();
- System.out.println("orderNo:" + orderNo + "pdf面单打印失败!");
- }
- return false;
- }
-
-
- // 下载网络文件
- private static void downloadNet(String sourceFileUrl,String destFilePath){
- int bytesum = 0;
- int byteread = 0;
- InputStream inStream = null;
- FileOutputStream fs = null;
- try {
- URL url = new URL(sourceFileUrl);
- URLConnection conn = url.openConnection();
- inStream = conn.getInputStream();
- fs = new FileOutputStream(destFilePath);
- byte[] buffer = new byte[1024*4];
- while ((byteread = inStream.read(buffer)) != -1) {
- bytesum += byteread;
- System.out.println(bytesum);
- fs.write(buffer, 0, byteread);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally{
- try {
- if(inStream != null){
- inStream.close();
- }
- if(fs != null){
- fs.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private static void deleteFile(String filePath) {
- File file = new File(filePath);
- if (file.exists() && file.isFile()) {
- file.delete();
- }
- }
- public static void main(String[] args) {//test
- String printerName = "PDFCreator";//打印机名
- //pdf路径
- String pdfFilePath = "D:/pdf/39488.pdf";
- try {
- PrintPDF.main(new String[]{
- "-silentPrint",//静默打印
- // "-password","abcde",//pdf打开密码
- "-printerName",printerName ,//指定打印机名
- "-orientation","auto",//打印方向,auto|landscape|portrait三种可选
- pdfFilePath//打印PDF文档的路径
- });
- } catch (PrinterException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
nginx配置,通过alias设置虚拟目录,这样就可以通过URL直接远程访问PDF了(打印接口服务就是这样远程下载PDF的)。
- location /static {
- alias /home/pdf/;
- }
比如nginx配置的域名是www.liu.com,访问http://www.liu.com/static/39488.pdf实际指向的是/home/pdf/394488.pdf
最后,写个DOS批处理文件(pdf打印机启动.bat)给包装员用来启动打印接口服务。
PS:先把打印接口项目生成的jar包pdfPrintSoa-0.0.1-SNAPSHOT.jar放进pdf夹子里,pdf夹子放到c盘
- @echo off
- cd c:\pdf
- java -jar pdfPrintSoa-0.0.1-SNAPSHOT.jar
打印接口服务启动后,需要打印PDF时,通过Http调用包装员对应的打印接口服务就可以了,实现远程驱动打印PDF面单。