Web端调用本地打印机-Java实现

实现思路:

用Java调用本地打印机实现功能,将java程序打包成exe可执行文件,在本地注册表中新增URL协议,最后web端通过该协议实现启动本地exe程序进行打印

实现过程:

1、下载32位TSCActiveX.dll,并注册到windows环境中,指令为Regsvr32.exe TSCActiveX.dll 下载地址:https://download.csdn.net/download/u010188178/10642451

2、创建Java工程(这一步可以先不做,因为我用普通Java工程最终失败了,在这里只是为了说明当时的解决过程)

3、核心代码(见页面底端),这里需要引入外部包 jna-3.0.9.jar

4、添加入口类(main方法类),然后打包成jar文件

5、运行jar,java -jar ******.jar

此时发会报错“Class not fond”,找不到 com.sun.jna.Library,说明第三方包未能引入,解决方案:参考 https://blog.csdn.net/u010188178/article/details/82454220

问题解决,到这一步便可以运行jar文件调用本地打印。

6、使用exe4j将jar文件打包为exe文件 工具及使用说明的下载地址:https://download.csdn.net/download/u010188178/10643229

生成exe文件后,执行之。然后又报错:java.lang.NoClassDefFoundError: com/sun/jna/Library,与上面报错原因类似,找不到第三方包。

经过多次尝试失败,最终未能解决,因此回到上述提到的第“2”步,既然普通工程引入第三方jar包在自身打包过程会如此“不幸”,故想到使用maven来构建并打包项目;同时考虑到web端与exe运行程序之间的参数传递问题,因此我决定使用springboot+maven工程。核心代码不变,其他步骤同上,最终生成有效可执行exe文件。

7、添加自定义URL协议

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\TscPrint]

"URL Protocol"="D:\\test\\tsc_printer.exe"

@="TscPrintProtocol"

[HKEY_CLASSES_ROOT\TscPrint\DefaultIcon]

@="D:\\test\\tsc_printer.exe,1"

[HKEY_CLASSES_ROOT\TscPrint\shell]

[HKEY_CLASSES_ROOT\TscPrint\shell\open]

[HKEY_CLASSES_ROOT\TscPrint\shell\open\command]

@="\"D:\\test\\tsc_printer.exe\" \"%1\""

 

8、在页面上调用自定义协议启动打印程序

 

注意事项:

1、使用的是打印机的命令进行操作,这里需要jna的jar包,还有jdk要求是32位的,并且要要注册对应的dll,对应不同的系统要在不同的Windows下进行注册DLL,注册成功之后需要win+R ,调用并运行  Regsvr32.exe TSCActiveX.dll 指令

2、需要用到第三方jar包,jna

3、打印图片的指令“PUTPCX”仅支持单色PCX图像,上传到打印机前需要先将图片转换成单色PCX格式

转换步骤:

(1)将图片转换成单色位图,比如可使用windows自带的画图工具:打开图片-另存为单色位图

(2)将单色位图转换成PCX格式,比如可用PS工具将其另存为PCX

(讲一下当时解决这个问题的过程:调用打印机PUTPCX命令打印图片始终不能成功打印,然后阅读该型号打印机的编程API,提到该指令仅支持单色PCX图像,于是将矛头指向PCX;通过上网查询,了解PCX格式的头文件结构,单色应该具有这样2个特征,即文件头第3字节的“位/像素”值为1且第65字节平面数也为1;了解到这些后已经兴奋不已,因为自己在大学期间学过图相隐写技术,通过修改图像头文件的某些位置并不会让图片看起来有异样,于是就想当然的直接修改第3和第65字节的十六进制数值;然后保存图片,调用打印机,打印成功,但发现图片完全变了样,说明PCX格式文件头的这2个位置是不允许直接修改的;最后经技术负责人点拨,既然不知道怎样将PCX转换成单色,为何不先将其他格式图片转换成单色,再将其转换成PCX格式,经实验,方案可行。)

 

存在不足:

1.代码仅是技术上的实现,并未结合实际业务进行优化

2.暂不支持图片的打印(已解决)

3.不足之处,请批评指正,指正邮箱:tianjiaoerdai@163.com

 

核心代码:

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.List;

import com.sun.jna.Library;

import com.sun.jna.Native;



public class JavaPrinter {

private static JavaPrinter instance = null;

private JavaPrinter(){

}

public static JavaPrinter getInstance(){

if (instance == null) {

synchronized (JavaPrinter.class) {

if (instance == null) {

instance = new JavaPrinter();

}

}

}

return instance;

}

public interface TscLibDll extends Library {

TscLibDll INSTANCE = (TscLibDll) Native.loadLibrary("TSCLIB", TscLibDll.class);

int about();

int openport(String pirnterName);

int closeport();

int sendcommand(String printerCommand);

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 formfeed();

int nobackfeed();

int windowsfont(int x, int y, int fontheight, int rotation, int fontstyle, int fontunderline, String szFaceName, String content);

}

/**

* 打印入场券,宽高为80.6*201mm

* @param tscName 打印机名称

* @param title 打印标题

* @param others 除标题外的其他文字

* @param qrCode 二维码文字

* @param copies 打印份数

* @auther WolfShadow

* @date 2018年9月4日

*/

public void printTickt(String tscName, String title, List<String> others, String qrCode, int copies){

System.setProperty("jna.encoding", "GBK");// 支持中文

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String time = df.format(new Date());

// TscLibDll.INSTANCE.about();

TscLibDll.INSTANCE.openport(tscName);

// TscLibDll.INSTANCE.downloadpcx("C:\\UL.PCX", "UL.PCX");

// 设定标签的宽度、高度、打印速度、打印浓度、感应器类别、Gap/Black mark垂直间距、Gap/Black mark偏移距离

TscLibDll.INSTANCE.setup("80.6", "201", "5", "8", "1", "2", "0");

TscLibDll.INSTANCE.clearbuffer();

// TscLibDll.INSTANCE.sendcommand("PUTPCX 550,10,\"UL.PCX\"");

/*

1、ActiveXprinterfont采用机器内置编码通常用来打英文。

2、ActiveXwindowsfont可以输出汉字,但是必须是系统中存在的字体。

TSCObj.ActiveXprinterfont ("a","b","c","d","e","f","g");

a:字符串,文字X方向起始点,以点表示。

b:字符串,文字Y方向起始点,以点表示。

c:內建字型名称,共12种(1: 8*12 dots 2: 12*20 dots 3: 16*24 dots 4: 24*32 dots 5: 32*48 dots TST24.BF2: 繁體中文 24*24 TST16.BF2: 繁體中文 16*16 TTT24.BF2: 繁體中文 24*24 (電信碼) TSS24.BF2: 簡體中文 24*24 TSS16.BF2: 簡體中文 16*16 K: 韓文 24*24 L: 韓文 16*16 )

d:字符串,旋转角度

e:字符串,X方向放大倍率1-8

f:字符串,Y方向放大倍率1-8

g:字符串,打印内容

ActiveXwindowsfont(a,b,c,d,e,f,g,h)

说明:使用Windows TTF字体打印文字。

参数:

a:整数类型,文字X方向起始点,以点表示。

b:整数类型,文字Y方向起始点,以点表示。

c:整数类型,字体高度,以点表示。

d:整数类型,旋转角度,逆时针方向旋转。0-旋转0°,90-旋转90°,180-旋转180°,270-旋转270°。

e:整数类型,字体外形。0:标签;1:斜体;2:粗体;3:粗斜体。

f:整数类型,下划线,0:无下划线;1:加下划线。

g:字符串类型,字体名称。如:Arial,Times new Roman。

h:字符串类型,打印文字内容。

int startX = 200, startY = 1300, angle = 90, rowHight = 50;

TscLibDll.INSTANCE.windowsfont(startX, startY, 42, angle, 2, 0, "Arial", title);

int index = 1;

for(String str : others){

TscLibDll.INSTANCE.windowsfont(startX+(index++)*rowHight, startY, 36, angle, 0, 0, "Arial", str);

}

/*

纠错级别:L、M、Q、H

*/

//var cmd = 'QRCODE 条码X方向起始点,条码Y方向起始点,纠错级别,二维码高度,A(A和M),旋转角度,M2(分为类型1和类型2),S1 (s1-s8,默认s7),\"1231你好2421341325454353\"';

String command = "QRCODE 200,600,Q,7,A,0,M2,S7,\"" + qrCode + "\""; // 打印二维码的参数和内容

TscLibDll.INSTANCE.sendcommand(command); // 传送指令

// (打印份数,每页打印张数)

TscLibDll.INSTANCE.printlabel(""+copies, "1");

TscLibDll.INSTANCE.closeport();

System.exit(0);

}

}

 

 

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现服务器远程调用本地打印机,可以使用Java提供的远程方法调用(RMI)技术。以下是一些步骤: 1. 定义打印机接口Printer,其中包含打印方法print(String content)。 ```java public interface Printer extends java.rmi.Remote { public void print(String content) throws java.rmi.RemoteException; } ``` 2. 实现打印机类LocalPrinter,实现Printer接口,并实现打印方法。 ```java public class LocalPrinter extends java.rmi.server.UnicastRemoteObject implements Printer { public LocalPrinter() throws java.rmi.RemoteException { super(); } public void print(String content) throws java.rmi.RemoteException { System.out.println("Printing: " + content); // 在本地打印机打印 } } ``` 3. 创建服务器程序,将LocalPrinter对象注册到RMI注册表中。 ```java public class PrinterServer { public static void main(String[] args) { try { Printer printer = new LocalPrinter(); java.rmi.registry.LocateRegistry.createRegistry(1099); java.rmi.Naming.rebind("//localhost/Printer", printer); System.out.println("Printer server ready."); } catch (Exception e) { System.err.println("Printer server exception: " + e.getMessage()); e.printStackTrace(); } } } ``` 4. 创建客户程序,从RMI注册表中查找Printer对象,并调用打印方法。 ```java public class PrinterClient { public static void main(String[] args) { try { Printer printer = (Printer) java.rmi.Naming.lookup("//localhost/Printer"); printer.print("Hello, world!"); } catch (Exception e) { System.err.println("Printer client exception: " + e.getMessage()); e.printStackTrace(); } } } ``` 5. 运行服务器程序和客户程序,即可实现服务器远程调用本地打印机

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值