效果:
实现:主入口
public static void main(String[] args) {
//获取默认的打印机
PrintService defaultPrint = PrintServiceLookup.lookupDefaultPrintService();
//设置打印内容
String fnSku = "M010000000003306079";
String productName = "SmallRig FS5 Support for 1954 VCT-14 Shoulder Plate 2104";
String sku= "5689723";
//打印张数
int num = 1;
//打印
print(fnSku,productName,sku,num,defaultPrint );
}
主程序
/**
* @Description:
* 通过生成图片打印条形码
* @Author: qiuxiaoxing
* @CreateDate: 2021/3/25 17:55
* @Version: 1.0
*/
public static String print(String fnSku, String productName, String sku,int num,PrintService defaultPrint){
try {
//***************设置条形码***************
byte[] codeData = BarCodeImageUtil.generateBarCode128(fnSku, 10.00, 0.2, true);
ByteArrayInputStream codeImgIn = new ByteArrayInputStream(codeData);
BufferedImage codeImg = ImageIO.read(codeImgIn);
//***************设置名称***************
//每张图片的高度
int image_height = 300;
//每行或者每个文字的高度
int line_height = 50;
int every_line = image_height / line_height;
//转换英文名称
String[] name = changeProductName(productName);
// 每张图片有多少行文字
byte[] nameData = TextToImageUtil.createImage(name, new Font("宋体", Font.BOLD, 60), 1700, image_height, every_line, line_height);
ByteArrayInputStream nameImgIn = new ByteArrayInputStream(nameData);
BufferedImage nameImg = ImageIO.read(nameImgIn);
//***************设置sku***************
String[] strArr1 = new String[]{"NEW "+sku};
// 每张图片的高度
int image_height1 = 300;
//每行或者每个文字的高度
int line_height1 = 30;
int every_line1 = image_height1 / line_height1;
// 每张图片有多少行文字
byte[] skuData = TextToImageUtil.createImage(strArr1, new Font("宋体", Font.BOLD, 60), 2000, image_height1, every_line1, line_height1);
ByteArrayInputStream skuImgIn = new ByteArrayInputStream(skuData);
BufferedImage skuImg = ImageIO.read(skuImgIn);
//***************绘制需要打印的图片***************
//设置生成的图片宽高
BufferedImage image = new BufferedImage(890, 500, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
//绘制白色背景
g.setColor(Color.WHITE);
g.fillRect(0, 0, 890, 500);
//绘制条形码
//计算x的偏移量,让条形码居中
int width = codeImg.getWidth();
int x =(890-width)/2;
g.drawImage(codeImg, x, 40, null);
//绘制名称
g.drawImage(nameImg, 55, 296, null);
//绘制sku
g.drawImage(skuImg, 40, 430, null);
g.dispose();
ByteArrayOutputStream ous = new ByteArrayOutputStream();
try {
ImageIO.write(image, "png", ous);
} catch (IOException e) {
e.printStackTrace();
}
byte[] bytes = ous.toByteArray();
/*try{
//生成图片查看(测试使用)
FileImageOutputStream imageOutput = new FileImageOutputStream(new File("D:\\Backup\\桌面\\print1.jpg"));
imageOutput.write(bytes, 0, bytes.length);
imageOutput.close();
} catch(Exception ex) {
ex.printStackTrace();
}*/
//调用打印机
JPGPrint(bytes,num,defaultPrint);
} catch (Exception e) {
return e.getMessage();
}
return null;
}
/**
* 特殊处理英文名称
* @param productName
* @return
*/
private static String[] changeProductName(String productName) {
String[] s = productName.split(" ");
java.util.List<String> list = new ArrayList<>();
for(int i = 0; i < s.length; i++){
if(StrUtil.isNotEmpty(s[i])){
list.add(s[i]);
}
}
//需要打印的字符
List<String> neadPrint = new ArrayList();
if(list.size() <= 5){
for(int j = 0; j < list.size(); j++){
if(j<(list.size()-1)){
neadPrint.add(list.get(j) + " ");
}else{
neadPrint.add(list.get(j));
}
}
}else{
//前2个单词 + ... + 后3个单词
neadPrint.add(list.get(0)+" ");
neadPrint.add(list.get(1)+" ");
neadPrint.add(" ... ");
neadPrint.add(list.get(list.size()-3)+" ");
neadPrint.add(list.get(list.size()-2)+" ");
neadPrint.add(list.get(list.size()-1));
}
String nameUp = "";
String nameDown = "";
//一行最多25个字符
for(String it : neadPrint){
if(nameUp.length() < 25){
nameUp = nameUp + it;
}else{
nameDown = nameDown + it;
}
}
if(nameUp.length() > 25){
nameDown = nameUp.substring(25,nameUp.length())+nameDown;
nameUp = nameUp.substring(0,25);
}
if(nameDown.length() > 0){
nameDown = nameDown.trim();
}
if(nameDown.length() > 25){
nameDown = nameDown.substring(0,25);
}
return new String[]{nameUp+nameDown};
}
/**
* 打印图片
* @param buf
* @param num
* @param defaultPrint
*/
public static void JPGPrint(byte[] buf,int num,PrintService defaultPrint){
InputStream fis = null;
try {
// 设置打印格式,如果未确定类型,可选择autosense
DocFlavor flavor = DocFlavor.INPUT_STREAM.PNG;
// 设置打印参数
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(OrientationRequested.PORTRAIT);
//份数
aset.add(new Copies(num));
aset.add(PrintQuality.HIGH);
//单面打印
aset.add(Sides.ONE_SIDED);
aset.add(MediaSizeName.ISO_B10);
DocAttributeSet das = new HashDocAttributeSet();
//设置打印纸张的大小(以毫米为单位)
das.add(new MediaPrintableArea(0f, 0f, 50f, 45f, MediaPrintableArea.MM));
// 构造待打印的文件流
fis = new ByteArrayInputStream(buf);
Doc doc = new SimpleDoc(fis, flavor, das);
// 创建打印作业
DocPrintJob job = defaultPrint.createPrintJob();
job.print(doc, aset);
} catch (Exception e1) {
e1.printStackTrace();
} finally {
// 关闭打印的文件流
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
生产条形码和文字图片的工具类
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TextToImageUtil {
public static void main(String[] args) {
String message = "SmallRig FS5";
String[] strArr = message.split("\n");
int image_height = 700; // 每张图片的高度
int line_height = 30; //每行或者每个文字的高度
int every_line = image_height / line_height; // 每张图片有多少行文字
byte[] re = createImage(strArr, new Font("宋体", Font.PLAIN, 22), 350, image_height, every_line, line_height);
try{
FileImageOutputStream imageOutput = new FileImageOutputStream(new File("D:\\Backup\\桌面\\obj.jpg"));
imageOutput.write(re, 0, re.length);
imageOutput.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
/**
* 根据str,font的样式等生成图片
* @param strArr
* @param font
* @param width
* @param image_height 每张图片的高度
* @param every_line 每张图片有多少行文字
* @param line_height 每行或者每个文字的高度
* @return
*/
public static byte[] createImage(String[] strArr, Font font,
int width, int image_height, int every_line, int line_height){
FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(font);
int stringWidth = fm.charWidth('字');// 标点符号也算一个字
int line_string_num = width % stringWidth == 0 ? (width / stringWidth) : (width / stringWidth) + 1;
List<String> listStr = new ArrayList<>();
List<String> newList = new ArrayList<>();
for (int h = 0; h < strArr.length; h++) {
listStr.add(strArr[h]);
}
for (int j = 0; j < listStr.size(); j++) {
if( listStr.get(j).length() > line_string_num){
newList.add(listStr.get(j).substring(0,line_string_num));
listStr.add(j+1,listStr.get(j).substring(line_string_num));
listStr.set(j,listStr.get(j).substring(0,line_string_num));
}else{
newList.add(listStr.get(j));
}
}
int a = newList.size();
int b = every_line;
int imgNum = a % b == 0 ? (a / b) : (a / b) + 1;
ByteArrayOutputStream ous = new ByteArrayOutputStream();
for (int m = 0; m < imgNum; m++) {
// 创建图片
BufferedImage image = new BufferedImage(width, image_height,
BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
g.setClip(0, 0, width, image_height);
g.setColor(Color.white); // 背景色白色
g.fillRect(0, 0, width, image_height);
g.setColor(Color.black);// 字体颜色黑色
g.setFont(font);// 设置画笔字体
// 每张多少行,当到最后一张时判断是否填充满
for (int i = 0; i < every_line; i++) {
int index = i + m * every_line;
if (newList.size() - 1 >= index) {
//g.drawString(newList.get(index), 0, line_height * (i + 1)+12);
MyDrawString(newList.get(index), 0, line_height * (i + 1)+12,0.9,g);
}
}
g.dispose();
try {
ImageIO.write(image, "png", ous);
} catch (IOException e) {
e.printStackTrace();
}
}
return ous.toByteArray();
}
public static void MyDrawString(String str,int x,int y,double rate,Graphics g){
String tempStr=new String();
int orgStringWight=g.getFontMetrics().stringWidth(str);
int orgStringLength=str.length();
int tempx=x;
int tempy=y;
while(str.length()>0)
{
tempStr=str.substring(0, 1);
str=str.substring(1, str.length());
g.drawString(tempStr, tempx, tempy);
tempx=(int)(tempx+(double)orgStringWight/(double)orgStringLength*rate);
}
}
}
import org.apache.commons.lang.ObjectUtils;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
public class BarCodeImageUtil {
/**
* 生成code128条形码
*
* @param height 条形码的高度
* @param width 条形码的宽度
* @param message 要生成的文本
* @param withQuietZone 是否两边留白
* @return 图片对应的字节码
*/
public static byte[] generateBarCode128(String message, Double height, Double width, boolean withQuietZone) {
Code128Bean bean = new Code128Bean();
// 分辨率
int dpi = 512;
// 设置两侧是否留白
bean.doQuietZone(withQuietZone);
// 设置条形码高度和宽度
bean.setBarHeight((double) ObjectUtils.defaultIfNull(height, 9.0D));
if (width != null) {
bean.setModuleWidth(width);
}
// 设置图片类型
String format = "image/png";
ByteArrayOutputStream ous = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, dpi,
BufferedImage.TYPE_BYTE_BINARY, false, 0);
// 生产条形码
bean.generateBarcode(canvas, message);
try {
canvas.finish();
} catch (IOException e) {
}
return ous.toByteArray();
}
public static void main(String[] args) {
byte[] bytes = generateBarCode128("768LQ-BSE2346B", 10.00, 0.2, true);
try{
FileImageOutputStream imageOutput = new FileImageOutputStream(new File("D:\\Backup\\桌面\\obj.jpg"));
imageOutput.write(bytes, 0, bytes.length);
imageOutput.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
maven 依赖
<dependency>
<groupId>net.sf.barcode4j</groupId>
<artifactId>barcode4j</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.6</version>
<scope>compile</scope>
</dependency>