feat:增加图片打印接口
This commit is contained in:
parent
eecc053eae
commit
1474746864
10
pom.xml
10
pom.xml
|
@ -21,6 +21,8 @@
|
||||||
<hutool.version>5.8.25</hutool.version>
|
<hutool.version>5.8.25</hutool.version>
|
||||||
<jna.version>5.14.0</jna.version>
|
<jna.version>5.14.0</jna.version>
|
||||||
<pdfbox.version>3.0.2</pdfbox.version>
|
<pdfbox.version>3.0.2</pdfbox.version>
|
||||||
|
<fastjson.version>1.2.83</fastjson.version>
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -68,6 +70,14 @@
|
||||||
<artifactId>pdfbox</artifactId>
|
<artifactId>pdfbox</artifactId>
|
||||||
<version>${pdfbox.version}</version>
|
<version>${pdfbox.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>${fastjson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.dpkj.modules.autoReplyPrint.base;
|
||||||
|
|
||||||
|
import com.dpkj.common.exception.RRException;
|
||||||
|
import com.dpkj.modules.autoReplyPrint.utils.AutoReplyPrint;
|
||||||
|
import com.dpkj.modules.autoReplyPrint.utils.ImageUtils;
|
||||||
|
import com.sun.jna.Pointer;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印基础实现
|
||||||
|
*
|
||||||
|
* @author <a href="https://gitee.com/shi-chongli">石头人</a>
|
||||||
|
* @version 1.0
|
||||||
|
* @since 2025-01-17 14:37:23
|
||||||
|
*/
|
||||||
|
public abstract class BaseImagePrint {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必须要实现这个,获取句柄
|
||||||
|
* @param devName 设备名称
|
||||||
|
* @return 窗口句柄
|
||||||
|
*/
|
||||||
|
public abstract Pointer getHandle(String devName);
|
||||||
|
|
||||||
|
|
||||||
|
public void printFromPath(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
|
||||||
|
Pointer handle = getHandle(devName);
|
||||||
|
try {
|
||||||
|
// 开始打印图片
|
||||||
|
boolean printTag = AutoReplyPrint.INSTANCE.CP_Pos_PrintRasterImageFromFile(handle, dstw, dsth, pszFile, binaryzation_method, compression_method);
|
||||||
|
if( !printTag ){
|
||||||
|
throw new RRException("打印图片失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切纸
|
||||||
|
AutoReplyPrint.INSTANCE.CP_BlackMark_SetBlackMarkPaperCutPosition(handle, 0);
|
||||||
|
boolean cutPaper = AutoReplyPrint.INSTANCE.CP_Pos_FeedAndHalfCutPaper(handle);
|
||||||
|
if ( !cutPaper){
|
||||||
|
throw new RRException("图片裁剪失败,请自行裁剪");
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RRException(e);
|
||||||
|
}finally {
|
||||||
|
if ( handle != null) AutoReplyPrint.INSTANCE.CP_Port_Close(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printFromPathData(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
|
||||||
|
// 获取图片
|
||||||
|
byte[] data = ImageUtils.imageToBytes(pszFile);
|
||||||
|
this.printFromData(devName, dstw, dsth, data, binaryzation_method, compression_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printFromData(String devName, int dstw, int dsth, byte[] data, int binaryzation_method, int compression_method) {
|
||||||
|
Pointer handle = getHandle(devName);
|
||||||
|
try {
|
||||||
|
// 开始打印图片
|
||||||
|
boolean printTag = AutoReplyPrint.INSTANCE.CP_Pos_PrintRasterImageFromData(handle, dstw, dsth, data, data.length, binaryzation_method, compression_method);
|
||||||
|
if( !printTag ){
|
||||||
|
throw new RRException("打印图片失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切纸
|
||||||
|
AutoReplyPrint.INSTANCE.CP_BlackMark_SetBlackMarkPaperCutPosition(handle, 0);
|
||||||
|
boolean cutPaper = AutoReplyPrint.INSTANCE.CP_Pos_FeedAndHalfCutPaper(handle);
|
||||||
|
if ( !cutPaper){
|
||||||
|
throw new RRException("图片裁剪失败,请自行裁剪");
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RRException(e);
|
||||||
|
}finally {
|
||||||
|
if ( handle != null) AutoReplyPrint.INSTANCE.CP_Port_Close(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printFromMultipartFile(String devName, int dstw, int dsth, MultipartFile file, int binaryzation_method, int compression_method){
|
||||||
|
byte[] data = ImageUtils.getByteToMultipartFile(file);
|
||||||
|
this.printFromData(devName, dstw, dsth, data, binaryzation_method, compression_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.dpkj.modules.autoReplyPrint.controller;
|
||||||
|
|
||||||
|
import com.dpkj.common.vo.Result;
|
||||||
|
import com.dpkj.modules.autoReplyPrint.service.ImagePrintService;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印控制层
|
||||||
|
*
|
||||||
|
* @author <a href="https://gitee.com/shi-chongli">石头人</a>
|
||||||
|
* @version 1.0
|
||||||
|
* @since 2025-01-17 13:57:11
|
||||||
|
*/
|
||||||
|
@RequestMapping("/autoReplyPrint")
|
||||||
|
public class ImagePrintController {
|
||||||
|
|
||||||
|
@Resource(name = "USBImagePrint")
|
||||||
|
private ImagePrintService usbImagePrintService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印,通过路径
|
||||||
|
*/
|
||||||
|
@GetMapping("/usb/imagePrint/path")
|
||||||
|
Result<Void> usbImagePrintFromPath(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
|
||||||
|
@RequestParam(defaultValue = "500") Integer width,
|
||||||
|
@RequestParam(defaultValue = "500") Integer height,
|
||||||
|
@RequestParam String path, Integer binaryMethod, Integer compressionMethod){
|
||||||
|
this.usbImagePrintService.imagePrintFromPath(usbName, width, height, path, binaryMethod, compressionMethod);
|
||||||
|
return Result.ok("图片打印成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印,通过byte[]
|
||||||
|
*/
|
||||||
|
@GetMapping("/usb/imagePrint/pathData")
|
||||||
|
Result<Void> usbImagePrintFromData(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
|
||||||
|
@RequestParam(defaultValue = "500") Integer width,
|
||||||
|
@RequestParam(defaultValue = "500") Integer height,
|
||||||
|
@RequestParam String path, Integer binaryMethod, Integer compressionMethod){
|
||||||
|
this.usbImagePrintService.imagePrintFromPathData(usbName, width, height, path, binaryMethod, compressionMethod);
|
||||||
|
return Result.ok("图片打印成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印,通过multipartFile文件
|
||||||
|
*/
|
||||||
|
@GetMapping("/usb/imagePrint/multipartFile")
|
||||||
|
Result<Void> usbImagePrintFromData(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
|
||||||
|
@RequestParam(defaultValue = "500") Integer width,
|
||||||
|
@RequestParam(defaultValue = "500") Integer height,
|
||||||
|
@RequestParam MultipartFile file, Integer binaryMethod, Integer compressionMethod){
|
||||||
|
this.usbImagePrintService.imagePrintFromMultipartFile(usbName, width, height, file, binaryMethod, compressionMethod);
|
||||||
|
return Result.ok("图片打印成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印,通过byte[]
|
||||||
|
*/
|
||||||
|
@GetMapping("/usb/imagePrint/data")
|
||||||
|
Result<Void> usbImagePrintFromData(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
|
||||||
|
@RequestParam(defaultValue = "500") Integer width,
|
||||||
|
@RequestParam(defaultValue = "500") Integer height,
|
||||||
|
@RequestParam byte[] data, Integer binaryMethod, Integer compressionMethod){
|
||||||
|
this.usbImagePrintService.imagePrintFromData(usbName, width, height, data, binaryMethod, compressionMethod);
|
||||||
|
return Result.ok("图片打印成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.dpkj.modules.autoReplyPrint.service;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印服务接口
|
||||||
|
*
|
||||||
|
* @author <a href="https://gitee.com/shi-chongli">石头人</a>
|
||||||
|
* @version 1.0
|
||||||
|
* @since 2025-01-17 11:38:36
|
||||||
|
*/
|
||||||
|
public interface ImagePrintService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印
|
||||||
|
* @param devName 设备名称/usb/tcp/com
|
||||||
|
* @param dstw 要打印的宽度
|
||||||
|
* @param dsth 要打印的高度
|
||||||
|
* @param pszFile 图片的路径
|
||||||
|
* @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
|
||||||
|
* @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
|
||||||
|
*/
|
||||||
|
void imagePrintFromPath(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印,内部直接读取转换为byte进行打印
|
||||||
|
* @param devName 设备名称/usb/tcp/com
|
||||||
|
* @param dstw 要打印的宽度
|
||||||
|
* @param dsth 要打印的高度
|
||||||
|
* @param pszFile 图片的路径
|
||||||
|
* @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
|
||||||
|
* @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
|
||||||
|
*/
|
||||||
|
void imagePrintFromPathData(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接传输数据进行打印
|
||||||
|
* @param devName 设备名称/usb/tcp/com
|
||||||
|
* @param dstw 要打印的宽度
|
||||||
|
* @param dsth 要打印的高度
|
||||||
|
* @param data 图片数据
|
||||||
|
* @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
|
||||||
|
* @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
|
||||||
|
*/
|
||||||
|
void imagePrintFromData(String devName, int dstw, int dsth, byte[] data, int binaryzation_method, int compression_method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接传的MultipartFile文件过来
|
||||||
|
* @param devName 设备名称/usb/tcp/com
|
||||||
|
* @param dstw 要打印的宽度
|
||||||
|
* @param dsth 要打印的高度
|
||||||
|
* @param file 图片数据
|
||||||
|
* @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
|
||||||
|
* @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
|
||||||
|
*/
|
||||||
|
void imagePrintFromMultipartFile(String devName, int dstw, int dsth, MultipartFile file, int binaryzation_method, int compression_method);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.dpkj.modules.autoReplyPrint.service.impl;
|
||||||
|
|
||||||
|
import com.dpkj.common.exception.RRException;
|
||||||
|
import com.dpkj.modules.autoReplyPrint.base.BaseImagePrint;
|
||||||
|
import com.dpkj.modules.autoReplyPrint.service.ImagePrintService;
|
||||||
|
import com.dpkj.modules.autoReplyPrint.utils.AutoReplyPrint;
|
||||||
|
import com.sun.jna.Pointer;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片打印服务
|
||||||
|
*
|
||||||
|
* @author <a href="https://gitee.com/shi-chongli">石头人</a>
|
||||||
|
* @version 1.0
|
||||||
|
* @since 2025-01-17 11:38:36
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service("USBImagePrint")
|
||||||
|
public class USBImagePrintServiceImpl extends BaseImagePrint implements ImagePrintService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pointer getHandle(String devName) {
|
||||||
|
try {
|
||||||
|
return AutoReplyPrint.INSTANCE.CP_Port_OpenUsb(devName, 1);
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RRException("获取USB句柄失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void imagePrintFromPath(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
|
||||||
|
super.printFromPath(devName, dstw, dsth, pszFile, binaryzation_method, compression_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void imagePrintFromPathData(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
|
||||||
|
super.printFromPathData(devName, dstw, dsth, pszFile, binaryzation_method, compression_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void imagePrintFromData(String devName, int dstw, int dsth, byte[] data, int binaryzation_method, int compression_method) {
|
||||||
|
super.printFromData(devName, dstw, dsth, data, binaryzation_method, compression_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void imagePrintFromMultipartFile(String devName, int dstw, int dsth, MultipartFile file, int binaryzation_method, int compression_method) {
|
||||||
|
super.printFromMultipartFile(devName, dstw, dsth, file, binaryzation_method, compression_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.dpkj.modules.autoReplyPrint.utils;
|
||||||
|
|
||||||
|
import com.dpkj.common.exception.RRException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片转换工具
|
||||||
|
*
|
||||||
|
* @author <a href="https://gitee.com/shi-chongli">石头人</a>
|
||||||
|
* @version 1.0
|
||||||
|
* @since 2025-01-17 14:06:09
|
||||||
|
*/
|
||||||
|
public class ImageUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取图片并转换为byte数组
|
||||||
|
* @param imagePath 图片路径
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] imageToBytes(String imagePath) {
|
||||||
|
try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get(imagePath)));
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
|
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = bis.read(buffer)) != -1) {
|
||||||
|
baos.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
return baos.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RRException("读取图片信息失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件byte[],通过 MultipartFile
|
||||||
|
* @param file 文件信息
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] getByteToMultipartFile(MultipartFile file){
|
||||||
|
// 验证文件是否为空
|
||||||
|
if (file.isEmpty()) {
|
||||||
|
throw new RRException("文件内容为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证文件类型
|
||||||
|
String contentType = file.getContentType();
|
||||||
|
if (contentType == null || !contentType.startsWith("image/")) {
|
||||||
|
throw new RRException("只支持图片文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件扩展名
|
||||||
|
String fileName = file.getOriginalFilename();
|
||||||
|
String fileExtension = fileName != null ?
|
||||||
|
fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase() : "";
|
||||||
|
|
||||||
|
// 验证扩展名
|
||||||
|
List<String> allowedExtensions = Arrays.asList("jpg", "jpeg", "png", "gif");
|
||||||
|
if (!allowedExtensions.contains(fileExtension)) {
|
||||||
|
throw new RRException("不支持的文件格式");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 转换为字节数组
|
||||||
|
return file.getBytes();
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RRException("获取文件字节失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue