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;
    }



}

猜你喜欢

转载自blog.csdn.net/qq_37511501/article/details/82150661
今日推荐