1.工具类—ZkemSDKUtils 

package com.XXX.gasstation.commons.utils;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.XXX.gasstation.commons.utils.lang.DateUtils;
import net.sf.json.JSONObject;
import java.util.*;

/**
 * @ClassName:${type_name}
 * @Description:${todo}(连接、获取考勤机数据)
 * @author: ZHOUPAN
 * @date ${date} ${time}
 * @Copyright: 2018 www.zsplat.com Inc. All rights reserved.
 * ${tags}
 */
public class ZkemSDKUtils {

    //zkemkeeper.ZKEM.1 为zkemkeeper.dll 注册成功后 在注册表可以查看:HKEY_CLASSES_ROOT最下面
    private static ActiveXComponent zkem = new ActiveXComponent("zkemkeeper.ZKEM.1");

    /**
     * 连接考勤机
     *
     * @param address 考勤机地址
     * @param port    端口号
     * @return
     */
    public static boolean connect(String address, int port) {
        boolean result = zkem.invoke("Connect_NET", address, port).getBoolean();
        return result;
    }

    /**
     * 读取考勤记录到pc缓存。配合getGeneralLogData使用
     *
     * @return
     */
    public static boolean readGeneralLogData() {
        boolean result = zkem.invoke("ReadGeneralLogData", 1).getBoolean();
        return result;
    }

    /**
     * 读取该时间之后的最新考勤数据。 配合getGeneralLogData使用。//网上说有这个方法,但是我用的开发文档没有这个方法,也调用不到,我在controller中处理获取当天数据
     *
     * @param lastest
     * @return
     */
    public static boolean readLastestLogData(Date lastest) {
        boolean result = zkem.invoke("ReadLastestLogData", 2018 - 07 - 24).getBoolean();
        return result;
    }

    /**
     * 获取缓存中的考勤数据。配合readGeneralLogData / readLastestLogData使用。
     *
     * @return 返回的map中,包含以下键值:
     * "EnrollNumber"   人员编号
     * "Time"           考勤时间串,格式: yyyy-MM-dd HH:mm:ss
     * "VerifyMode"
     * "InOutMode"
     * "Year"          考勤时间:年
     * "Month"         考勤时间:月
     * "Day"           考勤时间:日
     * "Hour"            考勤时间:时
     * "Minute"        考勤时间:分
     * "Second"        考勤时间:秒
     */
    public static List<Map<String, Object>> getGeneralLogData() {
        Variant dwMachineNumber = new Variant(1, true);//机器号

        Variant dwEnrollNumber = new Variant("", true);
        Variant dwVerifyMode = new Variant(0, true);
        Variant dwInOutMode = new Variant(0, true);
        Variant dwYear = new Variant(0, true);
        Variant dwMonth = new Variant(0, true);
        Variant dwDay = new Variant(0, true);
        Variant dwHour = new Variant(0, true);
        Variant dwMinute = new Variant(0, true);
        Variant dwSecond = new Variant(0, true);
        Variant dwWorkCode = new Variant(0, true);
        List<Map<String, Object>> strList = new ArrayList<Map<String, Object>>();
        boolean newresult = false;
        do {
            Variant vResult = Dispatch.call(zkem, "SSR_GetGeneralLogData", dwMachineNumber, dwEnrollNumber, dwVerifyMode, dwInOutMode, dwYear, dwMonth, dwDay, dwHour, dwMinute, dwSecond, dwWorkCode);
            newresult = vResult.getBoolean();
            if (newresult) {
                String enrollNumber = dwEnrollNumber.getStringRef();

                //如果没有编号,则跳过。
                if (enrollNumber == null || enrollNumber.trim().length() == 0)
                    continue;
                String month = dwMonth.getIntRef() + "";
                String day = dwDay.getIntRef() + "";
                if (dwMonth.getIntRef() < 10) {
                    month = "0" + dwMonth.getIntRef();
                }
                if (dwDay.getIntRef() < 10) {
                    day = "0" + dwDay.getIntRef();
                }
                String validDate = dwYear.getIntRef() + "-" + month + "-" + day;
                String currentDate = DateUtils.getCurrentTime("yyyy-MM-dd");
                if (currentDate.equals(validDate)) {
                    Map<String, Object> m = new HashMap<String, Object>();
                    //Map<String, Object> user = getUserInfoByNumber(enrollNumber);
                    m.put("EnrollNumber", enrollNumber);
                    m.put("Time", dwYear.getIntRef() + "-" + dwMonth.getIntRef() + "-" + dwDay.getIntRef() + " " + dwHour.getIntRef() + ":" + dwMinute.getIntRef() + ":" + dwSecond.getIntRef());
                    m.put("VerifyMode", dwVerifyMode.getIntRef());
                    m.put("InOutMode", dwInOutMode.getIntRef());
                    m.put("Year", dwYear.getIntRef());
                    m.put("Month", dwMonth.getIntRef());
                    m.put("Day", dwDay.getIntRef());
                    m.put("Hour", dwHour.getIntRef());
                    m.put("Minute", dwMinute.getIntRef());
                    m.put("Second", dwSecond.getIntRef());
                    strList.add(m);
                }
            }
        } while (newresult == true);
        return strList;
    }

    /**
     * 获取用户信息
     *
     * @return 返回的Map中,包含以下键值:
     * "EnrollNumber"  人员编号
     * "Name"          人员姓名
     * "Password"      人员密码
     * "Privilege"
     * "Enabled"       是否启用
     */
    public static List<Map<String, Object>> getUserInfo() {
        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        //将用户数据读入缓存中。
        boolean result = zkem.invoke("ReadAllUserID", 1).getBoolean();

        Variant v0 = new Variant(1);
        Variant sdwEnrollNumber = new Variant("", true);
        Variant sName = new Variant("", true);
        Variant sPassword = new Variant("", true);
        Variant iPrivilege = new Variant(0, true);
        Variant bEnabled = new Variant(false, true);

        while (result) {
            //从缓存中读取一条条的用户数据
            result = zkem.invoke("SSR_GetAllUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();

            //如果没有编号,跳过。
            String enrollNumber = sdwEnrollNumber.getStringRef();
            if (enrollNumber == null || enrollNumber.trim().length() == 0)
                continue;

            //由于名字后面会产生乱码,所以这里采用了截取字符串的办法把后面的乱码去掉了,以后有待考察更好的办法。
            //只支持2位、3位、4位长度的中文名字。
            String name = sName.getStringRef();
            if (sName.getStringRef().length() > 4) {
                name = sName.getStringRef().substring(0, 4);
            }
            //如果没有名字,跳过。
            if (name.trim().length() == 0)
                continue;
            Map<String, Object> m = new HashMap<String, Object>();
            m.put("EnrollNumber", enrollNumber);
            m.put("Name", name);
            m.put("Password", sPassword.getStringRef());
            m.put("Privilege", iPrivilege.getIntRef());
            m.put("Enabled", bEnabled.getBooleanRef());

            resultList.add(m);
        }
        return resultList;
    }


    /**
     * 设置用户信息
     *
     * @param number
     * @param name
     * @param password
     * @param isPrivilege
     * @param enabled
     * @return
     */
    public static boolean setUserInfo(String number, String name, String password, int isPrivilege, boolean enabled) {
        Variant v0 = new Variant(1);
        Variant sdwEnrollNumber = new Variant(number, true);
        Variant sName = new Variant(name, true);
        Variant sPassword = new Variant(password, true);
        Variant iPrivilege = new Variant(isPrivilege, true);
        Variant bEnabled = new Variant(enabled, true);

        boolean result = zkem.invoke("SSR_SetUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();
        return result;
    }

    /**
     * 获取用户信息
     *
     * @param number 考勤号码
     * @return
     */
    public static Map<String, Object> getUserInfoByNumber(String number) {
        Variant v0 = new Variant(1);
        Variant sdwEnrollNumber = new Variant(number, true);
        Variant sName = new Variant("", true);
        Variant sPassword = new Variant("", true);
        Variant iPrivilege = new Variant(0, true);
        Variant bEnabled = new Variant(false, true);
        boolean result = zkem.invoke("SSR_GetUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();
        if (result) {
            Map<String, Object> m = new HashMap<String, Object>();
            m.put("EnrollNumber", number);
            m.put("Name", sName.getStringRef());
            m.put("Password", sPassword.getStringRef());
            m.put("Privilege", iPrivilege.getIntRef());
            m.put("Enabled", bEnabled.getBooleanRef());
            return m;
        }
        return null;
    }

    public static void main(String[] args) {
        ZkemSDKUtils sdk = new ZkemSDKUtils();
        Map<String, Object> map = new HashMap<String, Object>();
        boolean connFlag = sdk.connect("192.168.1.201", 4370);
        if (connFlag) {
            boolean flag = sdk.readGeneralLogData();
            List<Map<String, Object>> strList = sdk.getGeneralLogData();
            map.put("strList", strList);
            System.out.println("flag" + flag);
            System.out.println(JSONObject.fromObject(map).toString());
        }
    }

}

2. Controller层
@ResponseBody
    @RequestMapping(value = "/queryAttendance", method = RequestMethod.POST)
    public String queryAttendance(@RequestBody String params, HttpServletRequest request, HttpServletResponse response) {
        String returnString = null;
        Map<String, Object> map = new HashMap<String, Object>();
        List<Map<String,Object>> attendanceList = new ArrayList<Map<String,Object>>();
        int realCount =0;
        try {
            //是否连接考勤机
            String address = PropertiesUtil.loadResource("ZKE_IP", "config/config.properties");
            int port =Integer.parseInt(PropertiesUtil.loadResource("PORT", "config/config.properties"));
            boolean  connFlag = ZkemSDKUtils.connect(address, port);
            if(connFlag){
                boolean flag = ZkemSDKUtils.readGeneralLogData();
                List<Map<String,Object>> userList = ZkemSDKUtils.getUserInfo();//获取所有用户
                List<Map<String,Object>> strList = ZkemSDKUtils.getGeneralLogData();//获取所有数据
                Map<String, Object> mapAll = new HashMap<String, Object>();
                for (int i = 0; i < userList.size(); i++) {
                    Map<String, Object> userMap = userList.get(i);
                    // 用户真实数据
                    mapAll = new HashMap<String, Object>();
                    mapAll.put("EnrollNumber",MapUtils.getString(userMap, "EnrollNumber"));
                    mapAll.put("Name",MapUtils.getString(userMap, "Name"));
                    mapAll.put("Privilege",MapUtils.getString(userMap, "Privilege"));
                    String EnrollNumber1 = MapUtils.getString(userMap, "EnrollNumber");
                    List<Map<String, Object>> infoList = new ArrayList<Map<String, Object>>();
                    for (int j = 0;  j < strList.size(); j++) {
                        Map<String, Object> strMap = strList.get(j);
                        String EnrollNumber2 =MapUtils.getString(strMap, "EnrollNumber");
                        if (EnrollNumber1.equals(EnrollNumber2)){
                            infoList.add(strMap);//这个人所有的打卡数据
                        }
                    }

                    if (infoList.size()==0){
                        mapAll.put("startTime","");
                        mapAll.put("endTime","");
                    }
                    if (infoList.size()==1){
                        Map<String, Object> strMap = infoList.get(0);
                        String startTime = MapUtils.getString(strMap, "Time");
                        mapAll.put("startTime",startTime);
                        mapAll.put("endTime","");
                        realCount++;
                    }
                    if (infoList.size()>1){
                        Map<String, Object> strMap0 = infoList.get(0);
                        Map<String, Object> strMap1 = infoList.get(infoList.size()-1);
                        String startTime = MapUtils.getString(strMap0, "Time");
                        String endTime = MapUtils.getString(strMap1, "Time");
                        mapAll.put("startTime",startTime);
                        mapAll.put("endTime",endTime);
                        realCount++;
                    }
                    //mapAll.put("timeList",infoList);
                    attendanceList.add(mapAll);
                }
                //第一个人打卡的开始时间,最后一个人结束时间
                if (strList.size()>1){
                    Map<String, Object> strMap0 = strList.get(0);
                    Map<String, Object> strMap1 = strList.get(strList.size()-1);
                    String startTime = MapUtils.getString(strMap0, "Time");
                    String endTime = MapUtils.getString(strMap1, "Time");
                    map.put("startTime",startTime);
                    map.put("endTime",endTime);
                }
                map.put(STATUS, STATUS_TRUE);
                map.put(DATA, attendanceList);
                map.put(COUNT, attendanceList.size());
                map.put("realCount", realCount);
            }
        } catch (NullPointerException e) {
            SystemLogger.error("appController.queryAttendance", e);
            map.put(STATUS, STATUS_FALSE);
            map.put(MSG, ERROR_PARAM_NULL);
        } catch (ClassCastException e) {
            SystemLogger.error("appController.queryAttendance", e);
            map.put(STATUS, STATUS_FALSE);
            map.put(MSG, ERROR_PARAM_CLASS_CAST);
        } catch (Exception e) {
            SystemLogger.error("appController.queryAttendance.Exception", e);
            map.put(STATUS, STATUS_FALSE);
            map.put(MSG, ERROR_EXCEPTION);
        }
        returnString = JSONObject.fromObject(map).toString();
        returnString = JSAESUtils.aesEncrypt(returnString);
        return returnString;
    }