对接打印机,首先要有自己的思路。目前主流的小票打印机有蓝牙、wifi、USB接口、网口。我的项目对接的wifi打印接口。
佳博打印机配置IP地址,链接无线(问的商家,买打印机最好找个有耐心的)
下载打印机驱动。(这个感觉是最折腾人的,一定要看好型号,因为一不注意,型号就选错了。配置完发现驱动版本安装错误一定管商家要驱动卸载程序,先卸载再重装别问我怎么知道的)
引入jar包
pom.xml文件中添加依赖
net.java.dev.jna
打印工具类(下面的DLL文件是佳博提供的支持Windows64位的SDK。这个管商家要寻找适合自己项目环境的)
import com.sun.jna.Library; import com.sun.jna.Native; public interface TscLibDll extends Library { //这里现场需要修改 TscLibDll INSTANCE = (TscLibDll) Native.loadLibrary ("D:\\JavaJDK\\TSCLIB.dll",TscLibDll.class); // 以下为dll函数库支持的方法,方法的作用与参数说明见附件【dll函数库api文档】 int about (); int openport (String pirnterName); int closeport (); int sendcommand (String printerCommand); int sendBinaryData (byte[] printerCommand, int CommandLength); int setup (String width,String height,String speed,String density,String sensor,String vertical,String offset); int downloadpcx (String filename,String image_name); int barcode (String x,String y,String type,String height,String readable,String rotation,String narrow,String wide,String code); int printerfont (String x,String y,String fonttype,String rotation,String xmul,String ymul,String text); int clearbuffer (); int printlabel (String set, String copy); int windowsfont (int x, int y, int fontheight, int rotation, int fontstyle, int fontunderline, String szFaceName, String content); int windowsfontUnicode(int x, int y, int fontheight, int rotation, int fontstyle, int fontunderline, String szFaceName, byte[] content); int windowsfontUnicodeLengh(int x, int y, int fontheight, int rotation, int fontstyle, int fontunderline, String szFaceName, byte[] content, int length); byte usbportqueryprinter(); }
打印命令
enum Command { /** * 复位打印机 */ RESET(new byte[]{0x1b, 0x40}), /** * 加粗 */ toLarge2(new byte[]{0x1B, 0x45, 0x01}), /** * 加大1倍 */ toLarge(new byte[]{0x1D, 0x21, 0x01}), /** * 切纸 */ CUT_PAPER(new byte[]{0x1D, 0x56, 1}), /** * 蜂鸣 */ BUZZING(new byte[]{0x1B, 0x42, 2, 6}), /** * 水平居中 */ ALINE_CENTER(new byte[]{0x1B, 0x61, 1}), /** * 左对齐 */ ALINE_LEFT(new byte[]{0x1B, 0x61, 0}), /** * 右对齐 */ ALINE_RIGHT(new byte[]{0x1B, 0x61, 2}), /** * 行间距 */ LINE_HEIGHT_DEFAULT(new byte[]{0x1B, 0x32}), /** * 横向跳格 */ SKIP_SPACE(new byte[]{0x1B, 0x44, 16, 20, 24, 28}); Command(byte[] commandBytes) { this.commandBytes = commandBytes; } private byte[] commandBytes; public byte[] getCommandBytes() { return commandBytes; } }
打印
public String GPrinter(Map<String, Object> params){
try {
int maxMaterialLength = 13; //物料名称占位长度(中文)
int maxCountLength = 8;//重量占位长度(数字)
int maxUnitLength = 2;//最大单位长度
//数据列
ArrayList tableList = (ArrayList) params.get("tableData");
//第一行表头空格计算
StringBuffer FMSpace = new StringBuffer();
for (int w = 0; w < maxMaterialLength-2; w++) {
FMSpace.append("\u3000"); // 表头品名后面添加的空格占位符
}
StringBuffer FCSpace = new StringBuffer();
for (int e = 0; e < maxCountLength-4; e++) {
FCSpace.append(" "); // 表头品名后面添加的空格占位符
}
//客户
String purchaseUnitsName = params.get("purchaseUnitsName").toString();
//日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = sdf.format(new Date());//日期
System.setProperty("jna.encoding", "GBK");
TscLibDll.INSTANCE.openport("GP-D801 Series");
//切纸,加粗,字号:中,凤鸣
// TscLibDll.INSTANCE.sendBinaryData(Command.RESET.getCommandBytes(),Command.RESET.getCommandBytes().length);
TscLibDll.INSTANCE.sendBinaryData(Command.ALINE_CENTER.getCommandBytes(),Command.ALINE_CENTER.getCommandBytes().length);
TscLibDll.INSTANCE.sendcommand("***********销售出库小票***********");
TscLibDll.INSTANCE.sendcommand("客户:"+purchaseUnitsName+"");
TscLibDll.INSTANCE.sendcommand("日期:"+dateString+"");
TscLibDll.INSTANCE.sendBinaryData(Command.toLarge2.getCommandBytes(),Command.toLarge2.getCommandBytes().length);
TscLibDll.INSTANCE.sendBinaryData(Command.toLarge.getCommandBytes(), Command.toLarge.getCommandBytes().length);
TscLibDll.INSTANCE.sendcommand("--------------------------------");
StringBuffer nameDetail = new StringBuffer();
nameDetail.append("品名"+FMSpace+"数量"+FCSpace+"单位");
TscLibDll.INSTANCE.sendcommand(nameDetail.toString());
StringBuffer detail = new StringBuffer();
for(int i=0; i< tableList.size(); i++){
HashMap map = (HashMap)tableList.get(i);
String materialName = map.get("material").toString();//物料名称
detail.append(materialName);
if(materialName.contains("(")){
for (int r = 0; r < maxMaterialLength-materialName.length()-1; r++) {
detail.append("\u3000"); // 表头品名后面添加的空格占位符
}
}else{
for (int r = 0; r < maxMaterialLength-materialName.length(); r++) {
detail.append("\u3000"); // 表头品名后面添加的空格占位符
}
}
BigDecimal count = new BigDecimal(map.get("weight").toString());//填写的数量
detail.append(count.toString());
for (int u = 0; u < 8-count.precision(); u++) {
detail.append(" "); // 添加相同数量的空格
}
String unit = map.get("unit").toString();//单位
for (int t = 0; t < maxUnitLength-unit.length(); t++) {
detail.append("\u3000"); // 添加相同数量的空格
}
detail.append(unit + "\n");
}
TscLibDll.INSTANCE.sendcommand(detail.toString());
TscLibDll.INSTANCE.sendcommand("--------------------------------");
TscLibDll.INSTANCE.sendcommand("");
TscLibDll.INSTANCE.sendcommand("");
TscLibDll.INSTANCE.sendcommand("");
TscLibDll.INSTANCE.sendcommand("");
TscLibDll.INSTANCE.sendBinaryData(Command.CUT_PAPER.getCommandBytes(), Command.CUT_PAPER.getCommandBytes().length);
// TscLibDll.INSTANCE.sendBinaryData(Command.BUZZING.getCommandBytes(), Command.BUZZING.getCommandBytes().length);
// TscLibDll.INSTANCE.clearbuffer();
TscLibDll.INSTANCE.closeport();
return "出库完毕,打印成功";
} catch (Exception e) {
return e.getMessage();
}
}
打印效果
总结:总之通过这次写打印接口需要注意的点:确定调用何种打印接口,一定要找有耐心的商家。佳博打印机提供的SDK还是描述的太模糊了,一上来就让人摸不着头脑,好多资料还是在网上查的。
推荐阅读