根据这篇文章:http://blog.sina.com.cn/s/blog_82a09f100101f2uc.html ,和其它文章自己实现如下
项目开发中采用方式三来开发
方式一:调用点阵字库ts24.lib
注:如果中英文混合会有差别,字体大小不好控制,生成打印脚本是一个字符对应一个
import java.io.File; import java.io.FileInputStream; import java.io.UnsupportedEncodingException; import javax.print.Doc; import javax.print.DocFlavor; import javax.print.DocPrintJob; import javax.print.PrintException; import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.print.SimpleDoc; public class PrintChineseByLib { byte[] dotfont; String s_prt = "^XA", s_prt_buffer = ""; public static void main(String[] args) { try { PrintChineseByLib a = new PrintChineseByLib(); a.setCommand(); String str = a.getCommand(); System.out.println(str); a.print(str); } catch (Exception e) { e.printStackTrace(); } } public PrintChineseByLib() throws Exception { File file = new File("c:\\ts24.lib"); FileInputStream fis = new FileInputStream(file); dotfont = new byte[fis.available()]; fis.read(dotfont); fis.close(); } protected void setCommand() { printCN("中国", 10, 100, 30, 30, 34); } protected String getCommand() { return s_prt + s_prt_buffer + "^XZ"; } public void print(String str) throws PrintException { PrintService psZebra = PrintServiceLookup.lookupDefaultPrintService(); if (psZebra == null) { System.out.println("没有发现条码打印机."); return; } DocPrintJob job = psZebra.createPrintJob(); byte[] by = str.getBytes(); DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; Doc doc = new SimpleDoc(by, flavor, null); job.print(doc, null); } /** * 打印英文字符,数字 */ protected void printChar(String str, int x, int y, int h, int w) { System.out.println(str); s_prt_buffer += "^FO" + x + "," + y + "^A0," + h + "," + w + "^FD" + str + "^FS"; } /** * 打印中文字符串 * @param strCN * @param x * @param y * @param h * @param w * @param b 控制字体大小 */ protected void printCN(String strCN, int x, int y, int h, int w, int b) { byte[] ch = str2bytes(strCN); for (int off = 0; off < ch.length;) { if (((int) ch[off] & 0x00ff) >= 0xA0) { int qcode = ch[off] & 0xff; int wcode = ch[off + 1] & 0xff; s_prt_buffer = s_prt_buffer + String.format("^FO%d,%d^XG0000%01X%01X,%d,%d^FS\n", x, y, qcode, wcode, b, b); s_prt += String.format("~DG0000%02X%02X,00072,003,\n", qcode, wcode); qcode = (qcode + 128 - 32) & 0x00ff; wcode = (wcode + 128 - 32) & 0x00ff; int offset = ((int) qcode - 16) * 94 * 72 + ((int) wcode - 1) * 72; for (int j = 0; j < 72; j += 3) { qcode = (int) dotfont[j + offset] & 0x00ff; wcode = (int) dotfont[j + offset + 1] & 0x00ff; int qcode1 = (int) dotfont[j + offset + 2] & 0x00ff; s_prt += String.format("%02X%02X%02X\n", qcode, wcode, qcode1); } x = x + 25 * b; off = off + 2; } else if (((int) ch[off] & 0x00FF) < 0xA0) { ; printChar(String.format("%c", ch[off]), x, y, h, w); x = x + 15; off++; } } } byte[] str2bytes(String s) { if (null == s || "".equals(s)) { return null; } byte[] abytes = null; try { abytes = s.getBytes("gb2312"); } catch (UnsupportedEncodingException ex) { } return abytes; } }
方式二:调用fnthex32.dll
注:在win7的64位操作系统,将jdk换成32位的;执行打印如果中文乱码,将java类编译成GBK的再测试
import java.io.UnsupportedEncodingException; import org.xvolks.jnative.JNative; import org.xvolks.jnative.Type; import org.xvolks.jnative.exceptions.NativeException; import org.xvolks.jnative.pointers.Pointer; import org.xvolks.jnative.pointers.memory.HeapMemoryBlock; public class PrintChineseByDLL { private static void testPrintChinese(String sChn) { try { System.load("c:\\Fnthex32.dll"); JNative n = new JNative("Fnthex32", "GETFONTHEX"); n.setRetVal(Type.INT); n.setParameter(0, Type.STRING, sChn); n.setParameter(1, Type.STRING, "宋体"); n.setParameter(2, Type.INT, "0"); n.setParameter(3, Type.INT, "25"); n.setParameter(4, Type.INT, "0"); n.setParameter(5, Type.INT, "1"); n.setParameter(6, Type.INT, "0"); Pointer p2 = new Pointer(new HeapMemoryBlock(22 * 1024)); p2.setMemory(new byte[21 * 1024]); n.setParameter(7, p2); n.invoke(); System.out.println(p2.getAsString()); } catch (NativeException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } } public static void main(String[] args) throws UnsupportedEncodingException { testPrintChinese("中国"); } }
方式三:生成位图
将需要打印的中文生成位图,位图转成16进制字符
注:这种方式没有乱码问题,字体大小好控制
参考这篇文章http://www.cnblogs.com/Moosdau/archive/2011/03/31/2001404.html
import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import javax.print.Doc; import javax.print.DocFlavor; import javax.print.DocPrintJob; import javax.print.PrintException; import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.print.SimpleDoc; import javax.swing.JTextField; import org.apache.commons.lang3.StringUtils; /** * @author gongchang * 描述:生成位图,并转16进制字符 * 时间:2015年10月26日 上午9:11:28 */ public class PrintChineseByBmp { String imgCodes = "" , begin = "^XA" ,content = "", end = "^XZ"; Integer textNo = 0; public void setCommand() { printCN("中国",28,60,90); } public String getCommand() { return imgCodes+ begin + "\n"+ content+ end; } public void printCN(String text,int size,int x,int y){ BufferedImage img = createImage(text,size); String codeData = convertImageToCode(img); String t = ((img.getWidth() / 8 + ((img.getWidth() % 8 == 0) ? 0 : 1)) * img.getHeight()) + ""; String w = (img.getWidth() / 8 + ((img.getWidth() % 8 == 0) ? 0 : 1)) + ""; // String zpl = "~DGOUTSTR01," + t + "," + w + "," + codeData; ++textNo; imgCodes+= "~DGtext"+ textNo +"," + t + "," + w + "," + codeData+"\n"; content+="^FO"+ x +","+ y +"\n"+ "^XGtext"+ textNo +",1,1^FS\n"; } public final BufferedImage createImage(String text,int size) { size = size == 0 ? 28 : size; Font font = new Font("宋体",Font.BOLD, size); JTextField txt = new JTextField(); txt.setText(text); txt.setFont(font); int width = txt.getPreferredSize().width; int height = txt.getPreferredSize().height; BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D) bi.getGraphics(); g2.setBackground(Color.WHITE); g2.clearRect(0, 0, width, height); g2.setFont(font); g2.setPaint(Color.BLACK); FontRenderContext context = g2.getFontRenderContext(); Rectangle2D bounds = font.getStringBounds(text, context); double x = (width - bounds.getWidth()) / 2; double y = (height - bounds.getHeight()) / 2; double ascent = -bounds.getY(); double baseY = y + ascent; g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.drawString(text, (int) x, (int) baseY); return bi; } public final String convertImageToCode(BufferedImage img) { StringBuffer sb = new StringBuffer(); long clr = 0, n = 0; int b = 0; for (int i = 0; i < img.getHeight(); i++) { for (int j = 0; j < img.getWidth(); j++) { b = b * 2; clr = img.getRGB(j, i); String s = String.format("%X", clr); if (s.substring(s.length() - 6, s.length() - 6 + 6).compareTo( "BBBBBB") < 0) { b++; } n++; if (j == (img.getWidth() - 1)) { if (n < 8) { b = b * (2 ^ (8 - (int) n)); sb.append(StringUtils.leftPad(String.format("%X", b), 2, "0")); // sb.append(String.format("%X", b).PadLeft(2, '0')); b = 0; n = 0; } } if (n >= 8) { sb.append(StringUtils.leftPad(String.format("%X", b), 2, "0")); // sb.append(String.format("%X", b).PadLeft(2, '0')); b = 0; n = 0; } } sb.append("\n"); } return sb.toString(); } public void runPrint(String str) throws PrintException { PrintService printer = PrintServiceLookup.lookupDefaultPrintService(); if (printer == null) { System.out.println("没有发现条码打印机."); return; } DocPrintJob job = printer.createPrintJob(); byte[] by = str.getBytes(); DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; Doc doc = new SimpleDoc(by, flavor, null); job.print(doc, null); } public static void main(String[] args) throws PrintException { PrintChineseByBmp obj = new PrintChineseByBmp(); obj.setCommand(); String command = obj.getCommand(); obj.runPrint(command); System.out.println(command); } }