java编写打印控件
web打印一直是个棘手的问题,市面上的第三方打印插件也是贵的离谱,这里给出一个可行的解决方案。
SpringBoot项目的web服务,实现的功能:
- 获取电脑可用的打印机列表
- 设置使用的打印机
- 实现静默打印,打印时可以设置{打印份数、打印方向(横向、纵向)、双面 or 单面打印}
需注意的操作:
- 这是java web项目,所以需要打印的客户端电脑需要配置jdk、tomcat、以及设置服务自启(可自行百度,简单)。
- 另一个办法是将jar程序使用exe4j转成可执行文件(下面有简单介绍)。
@RequestMapping("/print")
public R print(@RequestParam(required = false) Map<String, Object> params, HttpServletRequest request) throws FileNotFoundException
此方法接收的参数包括:{"pdf":"pdf的base64位字符串(String)[必要的]","copies":"打印份数(int)[非必要]","duplex":"是否双面打印(boolean)[非必要]"}
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.23</version>
</dependency>
@CrossOrigin
@RestController
public class PrintController {
/**
* @Description: 使用打印机的名称。可以存在数据库里做持久化
*/
private static String printName = "Microsoft Print to PDF";
/**
* @Description: 获取打印机列表
* @Param: []
* @Return: com.wq.print.util.R
*/
@RequestMapping("/list")
public R list() {
ArrayList<String> list = new ArrayList<>();
// 遍历所有打印机的名称
for (PrintService ps : PrinterJob.lookupPrintServices()) {
list.add(ps.getName());
}
if (list.size() != 0) {
return R.ok("获取打印机列表成功").put("list", list);
}
return R.error("暂无可用打印机,请检查系统打印机设置");
}
/**
* @Description: 设置使用的打印机
* @Param:
* @Return: com.wq.print.util.R
*/
@PostMapping("/setPrint")
public R setPrint(@RequestParam("printName") String printName) {
PrintController.printName = printName;
return R.ok("打印机设置成功");
}
/**
* @Description: 打印服务
* @Param:
* @Return: com.wq.print.util.R
*/
@RequestMapping("/print")
public R print(@RequestParam(required = false) Map<String, Object> params, HttpServletRequest request) throws FileNotFoundException {
if ("GET".equals(request.getMethod())) {
return R.error("GET请求方式不被支持,只支持POST请求方式");
}
Object pdfBase64Str = params.get("pdf");
if (StringUtils.isEmpty(pdfBase64Str)) {
return R.error("pdf的Base64字符串有误或为空,请检查");
}
//将前端传来的pdfbase64数组转成字节数组
byte[] pdfByte = PrintController.base64ToFileByte(pdfBase64Str.toString());
//打印份数
int copies = params.get("copies") == null ? 1 : Integer.parseInt(params.get("copies").toString());
//是否双面打印
boolean duplex = params.get("duplex") != null && Boolean.parseBoolean(params.get("duplex").toString());
Boolean print = print(pdfByte, PrintController.printName, copies, duplex);
if (print) {
return R.ok("打印完成");
} else {
return R.error("打印失败");
}
}
/**
* @Description: 打印方法
* pdfByte:需要打印的pdf字节数组
* printName:打印机名称
* copies:打印份数
* duplex:是否双面打印
*/
private Boolean print(byte[] pdfByte, String printName, int copies, boolean duplex) {
try {
//加载pdf文件对象
PDDocument document = PDDocument.load(pdfByte);
//创建打印任务
PrinterJob job = PrinterJob.getPrinterJob();
// 遍历所有打印机的名称
for (PrintService ps : PrinterJob.lookupPrintServices()) {
String psName = ps.getName();
// 选用指定打印机
if (psName.equals(printName) || psName.contains(printName)) {
job.setPrintService(ps);
break;
}
}
job.setPageable(new PDFPageable(document));
Paper paper = new Paper();
// 设置打印纸张大小
paper.setSize(598, 842);
// 设置打印位置 坐标
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
// pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE);//横向 从右向左
// pageFormat.setOrientation(PageFormat.PORTRAIT);//横向 从左向右
pageFormat.setOrientation(PageFormat.PORTRAIT);//纵向
Book book = new Book();
book.append(new PDFPrintable(document, Scaling.ACTUAL_SIZE), pageFormat, 1);
job.setPageable(book);
//打印份数
job.setCopies(copies);
if (duplex) {//双面打印
PrintRequestAttributeSet printSet = new HashPrintRequestAttributeSet();
printSet.add(Sides.DUPLEX);
//执行打印操作
job.print(printSet);
} else {//单面打印
job.print();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* @Description: 文件的base64字符串转字节数组
*/
public static byte[] base64ToFileByte(String strBase64) {
return java.util.Base64.getDecoder().decode(strBase64);
}
}
使用exe4j将jar程序转成exe可执行文件
官网下载exe4j:https://exe4j.apponic.com/ 。下载后 下一步...下一步.....安装。
使用maven的package指令将写好的java程序打成jar包
将此jar包复制到桌面(或者其他好操作的位置)
双击exe文件即可运行。
测试: