Java 指定打印機名稱打印圖片

最近寫個指定打印機打印條碼,並且上傳服務器保存備份,方便下次打印

如果不需要上傳直接將圖片流直接給 new FileInputStream(filePath); Doc doc = new SimpleDoc(圖片流, dof, das);

思路:

1、在前臺用div畫布局

2、轉成base64圖片數據流

3、將數據流發送給後臺

4、後臺進行數據解碼並且上傳

5、上傳成功後根據路徑和打印機名稱調動打印機打印

PS:可能寫的不是很詳細大家湊合看

1、在前臺用div畫布局

HTML

<#include "../include/header.html" />

<script type="text/javascript">
    var viewModel = Hap.createGridViewModel('#grid');
    viewModel.model = {};
</script>
<body>
    <div id="page-content">
        <div class="pull-left" id="toolbar-btn" style="padding-bottom:10px;">
            <span class="btn btn-primary k-grid-add" style="float:left;margin-right:5px;" onclick="MyPrint(viewModel.model)" >打印</span>
        </div><br/>
    </div>
     <!--條碼-->
    <div id="barCode"></div>
    <!--一維碼js-->
    <script src="${base.contextPath}/lib/prints/jquery-barcode.js"></script>
    <!--二維碼js-->
    <script src="${base.contextPath}/lib/prints/jquery-qrcode.min.js"></script>
    <!--生成圖片js-->
    <script src="${base.contextPath}/lib/html2canvas/html2canvas.js"></script>
    <script src="${base.contextPath}/lib/html2canvas/bluebird.min.js"></script>
    <script src="${base.contextPath}/lib/html2canvas/downLoadImg.js"></script>
    <!--
    一維碼和二維碼自行下載
    html2canvas.js,bluebird.min.js,downLoadImg.js 
    這三個文件在  https://download.csdn.net/download/qq_37511501/10232976
    -->
    <script src="${base.contextPath}/lib/prints/print.js"></script>
</body>
</html>

print.JS

2、轉成base64圖片數據流

3、將數據流發送給後臺

/*
* Create By:    lkj
* Create Date:  2018年08月27日10:10:37
* Desc:         打印工具
*
* */

function MyPrint(printData) {
    /**
     *
     * 描述: 該方法判斷進入哪一個打印方法
     * @auther: lkj
     * @date: 2018/8/28 上午9:21
     *
     */
    // 根據類型判斷進入那個方法
    printData.type = "TEST2";
    printData.text = "000002RSEOT";
    printData.code = "21442650";
    printData.printName = "HP DeskJet 2600 series";
    if(printData.type == "TEST"){//打印一維碼   內部追溯條碼
        InternalTracingBarCode(printData);
    }else if(printData.type == "TEST2"){// ZS11E電池包客戶追溯條碼
        K288ABatteryPackCustomerTraceabilityBarCode(printData);
    }
}
function K288ABatteryPackCustomerTraceabilityBarCode(printData) {
    /**
     *
     * 描述:
     * @auther: lkj
     * @date: 2018/8/28 上午9:33
     * @param:printData 需要打印的數據
     */
    // 先進行判斷該條碼是否已經打印過,如果打印過則直接打印 如果沒有打印則獲取服務器照片存儲路徑
    var fileName = printData.text+"-2.png";
    var isPrint = myPostAjax("/is/print",{fileName:fileName,printName:printData.printName});
    if(isPrint.success){
        alert("打印成功");
        return;
    }else{
        if(isPrint.message != null && isPrint.message != "" && isPrint.message != undefined){
            alert(isPrint.message);
            return;
        }
    }
    var barCode = '<div id="TEST">';
    barCode += '<div id="towCode" style="float: left;margin:20px 10px 20px 5px;"></div>';
    barCode += '<div id="content" style="float: left;margin:20px 10px 20px 5px;">';
    barCode += '<span><font size="6px">1234</font><font size="8px">2234</font></span><br/>';
    barCode += '<span><font size="6px">1234567822345678</font></span><br/>';
    barCode += '<span><font size="6px">12345678</font></span><br/>';
    barCode += '<span><font size="6px">1234567822345678</font></span>';
    barCode += '</div>';
    barCode += '<div id="towCode2" style="float: left;margin:20px 10px 20px 5px;"></div>';
    barCode += '</div>';
    var width = 200;// 二維碼寬高
    var height = 200;
    $("#barCode").html(barCode); // 設置條碼內容
    $("#TEST").show(); // 顯示
    // 寬高必須設置,否則無法上傳
    $("#TEST").attr("style","width:"+870+"px;height:245px");
    $('#towCode').qrcode({
        render: "canvas",
        text: printData.text,
        width: width,
        height: height,
    });
    $('#towCode2').qrcode({
        render: "canvas",
        text: printData.text,
        width: width,
        height: height,
    });
    // 設置名稱 一維碼或二維碼內容 加類型 一維碼爲-1  二維碼爲-2
    getImgStr("TEST",fileName,isPrint.code,printData.printName);
}
function InternalTracingBarCode(printData) {
    /**
     *
     * 描述: 打印一維碼 內部追溯條碼
     * @auther: lkj
     * @date: 2018/8/28 上午9:21
     * @param:printData 需要打印的數據
     *
     */
    // 先進行判斷該條碼是否已經打印過,如果打印過則直接打印 如果沒有打印則獲取服務器照片存儲路徑
    var fileName = printData.text+"-1.png";
    var isPrint = myPostAjax("/is/print",{fileName:fileName,printName:printData.printName});
    if(isPrint.success){
        alert("打印成功");
        return;
    }else{
        if(isPrint.message != null && isPrint.message != "" && isPrint.message != undefined){
            alert(isPrint.message);
            return;
        }
    }
    // 設置條碼佈局 PS可以先在工具上畫好再複製過來
    // 改字體樣式和條碼樣式一樣,可以自定義更改
    var fontStyle = "clear:both; background-color: #FFFFFF; color: #000000; text-align: center; font-size: 20px; margin-top: 5px;text-align: center;";
    var barCode = '<div id="TEST">';
    barCode += '<br/><div id="bcTarget"></div>';
    barCode += '<div id="code"></div>';
    barCode += '</div>';
    $("#barCode").html(barCode);// 設置條碼內容
    $("#TEST").show();// 顯示
    $("#bcTarget").barcode(printData.text, "code128",{barWidth:4,barHeight:160,fontSize:20});
    fontStyle += "width:"+$("#bcTarget").width()+"px;";
    $("#TEST").attr("style","width:"+$("#bcTarget").width()+"px;");
    $("#code").attr("style",fontStyle);// K288A電池包客戶追溯條碼
    $("#code").html(printData.code);// 設置顯示條碼
    // 設置名稱 一維碼或二維碼內容 加類型 一維碼爲-1  二維碼爲-2
    getImgStr("TEST",fileName,isPrint.code,printData.printName);

}
function getImgStr(id,fileName,filePath,printName) {
    /**
     *
     * 描述: 將div根據id轉圖片流
     * @auther: lkj
     * @date: 2018/8/28 上午9:20
     * @param:id:DIV的id
     * @param:codeContent:條碼名稱
     * @param:filePath:服務器存儲路徑
     *
     */
    html2canvas($("#"+id), {
        onrendered: function(canvas) {
            canvas.id = "mycanvas";
            // 將div轉成圖片的字符流
            var img = convertCanvasToImage(canvas);
            // 設置需要傳參參數 圖片數據流 文件名稱 文件存儲路徑
            var obj = {imgStr:img.src,fileName:fileName,filePath:filePath,printName:printName};
            // 發送請求至後臺
            var printResult = myPostAjax("/print/internal/tracing/bar/code",obj);
            if(printResult.success){
                alert("打印成功");
            }else{
                alert(printResult.message);
            }
            $("#"+id).hide();// 隱藏
        },
        background:'white'// 背景白色
    });
}
function myPostAjax(url,data){
    /**
     *
     * 描述: 封裝ajax
     * @auther: lkj
     * @date: 2018/8/28 上午9:21
     *
     */
    var resultData = new Object();
    $.ajax({
        type:"POST",
        url:_basePath+url,
        data:data,
        dataType:'json',
        contentType:'application/x-www-form-urlencoded',
        async:false,
        success:function (result) {
            resultData = result;
        }
    })
    return resultData;
}


JAVA

4、後臺進行數據解碼並且上傳

5、上傳成功後根據路徑和打印機名稱調動打印機打印

Controller

package com.hand.utils.prints.controllers;


import com.hand.hap.core.IRequest;
import com.hand.hap.system.controllers.BaseController;
import com.hand.hap.system.dto.ResponseData;
import com.hand.utils.components.mapper.UtilMapper;
import com.hand.utils.prints.dto.PrintDto;
import com.hand.utils.prints.service.IPrintService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
/**
 * @Auther:lkj
 * @Date:2018/8/27 13:44
 * @E-mail:
 * @Description:條碼打印工具
 */
@Controller
public class PrintController extends BaseController {

    @Autowired
    private IPrintService service;

    @Autowired
    private UtilMapper utilMapper;

    @RequestMapping(value = "/print/internal/tracing/bar/code")
    @ResponseBody
    public ResponseData scanningKeyPartsBarcode(PrintDto data, HttpServletRequest request){
        /**
         *
         * 功能描述: 打印內部追溯條碼 並且上傳至服務器備份
         *
         * @auther:lkj
         * @date:2018/8/27 下午1:47
         * @param:[data, request]
         * @return:com.hand.hap.system.dto.ResponseData
         *
         */
        IRequest requestCtx = createRequestContext(request);
        ResponseData responseData = new ResponseData();
        try {
            responseData = service.printInternalTracingBarCode(requestCtx,data);
        } catch (Exception e) {
            e.printStackTrace();
            responseData.setSuccess(false);
            responseData.setMessage(e.getMessage());
            String insertMysql = "INSERT INTO hme_print_event(ERROR_MSG,FILE_PATH,PRINT_NAME)VALUES";
            insertMysql += "('"+e.getMessage()+"','"+data.getFilePath()+"/"+data.getFileName()+"','"+data.getPrintName()+"')";
            utilMapper.insertMysql(insertMysql);
        }

        return responseData;
    }

    @RequestMapping(value = "/is/print")
    @ResponseBody
    public ResponseData isPrint(PrintDto data, HttpServletRequest request){
        /**
         *
         * 功能描述: 查詢改條碼是否打印過 如果打印過則直接打印 不在上傳
         *
         * @auther:lkj
         * @date:2018/8/27 下午1:47
         * @param:[data, request]
         * @return:com.hand.hap.system.dto.ResponseData
         *
         */
        IRequest requestCtx = createRequestContext(request);
        ResponseData responseData = new ResponseData();
        try {
            responseData = service.isPrint(requestCtx,data);
        } catch (Exception e) {
            e.printStackTrace();
            responseData.setSuccess(false);
            responseData.setMessage(e.getMessage());
            String insertMysql = "INSERT INTO hme_print_event(ERROR_MSG,FILE_PATH,PRINT_NAME)VALUES";
            insertMysql += "('"+e.getLocalizedMessage()+"','"+data.getFilePath()+"/"+data.getFileName()+"','"+data.getPrintName()+"')";
            utilMapper.insertMysql(insertMysql);
        }

        return responseData;
    }


}

IPrintService

package com.hand.utils.prints.service;


import com.hand.hap.core.IRequest;
import com.hand.hap.system.dto.ResponseData;
import com.hand.utils.prints.dto.PrintDto;
import com.hand.workshops.dto.WorkshopsIpc;

public interface IPrintService {

    /**
     *
     * 功能描述: 打印內部追溯條碼 並且上傳至服務器備份
     *
     * @auther:lkj
     * @date:2018/8/27 下午1:48
     * @param requestCtx 用戶信息
     * @param data 數據
     * @return:ResponseData
     */
    ResponseData printInternalTracingBarCode(IRequest requestCtx, PrintDto data) throws Exception;

    /**
     *
     * 功能描述:查詢改條碼是否打印過 如果打印過則直接打印 不在上傳
     *
     * @auther:lkj
     * @date:2018/8/27 下午2:19
     * @param requestCtx 用戶信息
     * @param data 數據
     * @return:ResponseData
     *
     */
    ResponseData isPrint(IRequest requestCtx, PrintDto data) throws Exception;
}

PrintServiceImpl

package com.hand.utils.prints.service.impl;

import com.hand.hap.core.IRequest;
import com.hand.hap.system.dto.ResponseData;
import com.hand.utils.components.mapper.UtilMapper;
import com.hand.utils.prints.dto.PrintDto;
import com.hand.utils.prints.service.IPrintService;
import com.hand.utils.uploads.service.impl.UploadServiceImpl;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.print.*;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PrintQuality;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;

@Service
@Transactional(rollbackFor = Exception.class)
public class PrintServiceImpl implements IPrintService{
    private static final Logger logger = LoggerFactory.getLogger(PrintServiceImpl.class);
    @Autowired
    private UtilMapper utilMapper;
    // 因爲這邊是工廠的業務,所以我這邊需要把錯誤信息記錄到數據庫下,好方便以後查看錯誤信息
    private String insertErrorMsgSql = "INSERT INTO hme_print_event(ERROR_MSG,FILE_PATH,PRINT_NAME)VALUES";
    
    @Override
    public ResponseData printInternalTracingBarCode(IRequest requestCtx, PrintDto data)throws Exception {
        /**
         *
         * 功能描述: 打印內部追溯條碼 並且上傳至服務器備份
         *
         * @auther:lkj
         * @date:2018/8/27 下午1:50
         * @param:[requestCtx, data]
         * @return:com.hand.hap.system.dto.ResponseData
         *
         */
        ResponseData responseData = new ResponseData();
        String filename = data.getFileName();
        if(!ifNotNull(data.getImgListStr())){
            responseData.setSuccess(false);
            responseData.setMessage("圖片不可以爲空");
            String insertMysql = insertErrorMsgSql+"('圖片不可以爲空','"+filename+"','"+data.getPrintName()+"')";
            utilMapper.insertMysql(insertMysql);
            return responseData;
        }
        if(!ifNotNull(data.getFileName())){
            responseData.setSuccess(false);
            responseData.setMessage("圖片名稱不可以爲空");
            String insertMysql = insertErrorMsgSql+"('圖片名稱不可以爲空','"+filename+"','"+data.getPrintName()+"')";
            utilMapper.insertMysql(insertMysql);
            return responseData;
        }
        String imgStr = data.getImgStr().split(",")[1];
        UploadServiceImpl.GenerateImage(imgStr,data.getFilePath()+"/"+filename);
/* UploadServiceImpl.GenerateImage  之前寫的上傳圖片工具
//解碼
public static boolean GenerateImage(String imgStr, String imgFilePath) throws IOException {
    // 對字節數組字符串進行Base64解碼並生成圖片
    if (imgStr == null) // 圖像數據爲空
        return false;
    BASE64Decoder decoder = new BASE64Decoder();
        // Base64解碼
        byte[] bytes = decoder.decodeBuffer(imgStr);
        for (int i = 0; i < bytes.length; ++i) {
            if (bytes[i] < 0) {// 調整異常數據
                bytes[i] += 256;
            }
        }
        // 生成jpeg圖片
        OutputStream out = new FileOutputStream(imgFilePath);
        out.write(bytes);
        out.flush();
        out.close();
        return true;

}*/
        //  上傳條碼後打印條碼
        String filePath = data.getFilePath()+"/"+filename;
        return print(filePath,data.getPrintName());
    }

    @Override
    public ResponseData isPrint(IRequest requestCtx, PrintDto data) throws Exception {
        /**
         *
         * 功能描述: 查詢改條碼是否打印過 如果打印過則直接打印 不在上傳
         *
         * @auther:lkj
         * @date:2018/8/27 下午2:32
         * @param:[requestCtx, data]
         * @return:com.hand.hap.system.dto.ResponseData
         *
         */
        ResponseData responseData = new ResponseData();
        String sql = "SELECT T.PROFILE_VALUE FROM SYS_PROFILE_VALUE T WHERE ";
        sql += "T.PROFILE_ID = ( SELECT PROFILE_ID FROM sys_profile WHERE PROFILE_NAME = 'UPLOAD_BARCODE' ) ";
        String filePath = utilMapper.mysql(sql);
        if(!ifNotNull(filePath)){
            responseData.setSuccess(false);
            responseData.setMessage("UPLOAD_BARCODE:快碼沒有維護條碼存放地址");
            String insertMysql = insertErrorMsgSql+"('UPLOAD_BARCODE:快碼沒有維護條碼存放地址','','')";
            utilMapper.insertMysql(insertMysql);
            return responseData;
        }
        File file;
        // 先判斷該文件夾是否存在 如果不存在則創建文件夾,並且返回路徑
        file = new File(filePath);
        if(!file.exists()){
            file.mkdirs();
            responseData.setSuccess(false);
            responseData.setCode(filePath);
            return responseData;
        }else{//如果存在則查詢改條碼是否打印過,如果打印過就直接打印,否則返回路徑
            String fileName = filePath+"/"+data.getFileName();
            file = new File(fileName);
            if(file.exists()){

                return print(fileName,data.getPrintName());
            }
            responseData.setSuccess(false);
            responseData.setCode(filePath);
            return responseData;
        }

    }
    public ResponseData print(String filePath,String printName)throws Exception {
        /**
         *
         * 功能描述:調用指定打印機打印圖片
         *
         * @auther:lkj
         * @date:2018/8/28 下午1:37
         * @param:[filePath]
         * @return:void
         *
         */
        ResponseData responseData = new ResponseData();
        FileInputStream fin = null;
        javax.print.PrintService[] printServices = PrinterJob.lookupPrintServices();
        if(printServices.length == 0){
            String insertMysql = insertErrorMsgSql+"('打印機列表爲空','"+filePath+"','"+printName+"')";
            utilMapper.insertMysql(insertMysql);
            responseData.setSuccess(false);
            responseData.setMessage("打印機列表爲空");
            return responseData;
        }
        javax.print.PrintService printService = null;
        for (int i = 0; i < printServices.length; i++) {
            String sps = printServices[i].toString();
            logger.info("Print :" + sps);
            System.out.println("Print :" + sps);
            // 查詢匹配打印機
            if (sps.contains(printName)) {
                printService = printServices[i];
                break;
            }
        }
        if (null == printService) {
            String insertMysql = insertErrorMsgSql+"('沒有匹配到所指定的打印機','"+filePath+"','"+printName+"')";
            utilMapper.insertMysql(insertMysql);
            responseData.setSuccess(false);
            responseData.setMessage("沒有匹配到所指定的打印機");
            return responseData;
        }
        System.out.println("Print Start");
        logger.info("Print Start");
        DocFlavor dof = null;
        if (filePath.endsWith(".gif")) {
            dof = DocFlavor.INPUT_STREAM.GIF;
        } else if (filePath.endsWith(".jpg")) {
            dof = DocFlavor.INPUT_STREAM.JPEG;
        } else if (filePath.endsWith(".png")) {
            dof = DocFlavor.INPUT_STREAM.PNG;
        }
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
        pras.add(OrientationRequested.PORTRAIT);
        pras.add(new Copies(1));
        pras.add(PrintQuality.HIGH);
        DocAttributeSet das = new HashDocAttributeSet();
        // 設置打印紙張的大小(以毫米爲單位)
        das.add(new MediaPrintableArea(0, 0, 210, 296, MediaPrintableArea.MM));
        fin = new FileInputStream(filePath);
        Doc doc = new SimpleDoc(fin, dof, das);
        DocPrintJob job = printService.createPrintJob();
        job.print(doc, pras);
        fin.close();
        logger.info("打印成功!文件:"+filePath+"數量爲:"+1);
        System.out.println("Print End");
        logger.info("Print End");
        return responseData;
    }


    // 判斷是否爲空
    private boolean ifNotNull(Object o) {
        if (o == null || "".equals(o)) {
            return false;
        }
        return true;
    }

}

DTO

package com.hand.utils.prints.dto;

/**
 * @Auther:lkj
 * @Date:2018/8/27 13:44
 * @E-mail:
 * @Description:
 */
public class PrintDto {

    private String imgStr;// 圖片流

    private String[] imgListStr;// 批量上傳

    private String fileName;//文件名稱

    private String filePath;// 文件路徑

    private String printName;// 打印機名稱

    public String getPrintName() {
        return printName;
    }

    public void setPrintName(String printName) {
        this.printName = printName;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getImgStr() {
        return imgStr;
    }

    public void setImgStr(String imgStr) {
        this.imgStr = imgStr;
    }

    public String[] getImgListStr() {
        imgListStr = this.getImgStr().split(",");
        return imgListStr;
    }

    public void setImgListStr(String[] imgListStr) {
        this.imgListStr = imgListStr;
    }



}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章