生成快递单过程中需要生成条形码,生成条形码可参考:https://www.cnblogs.com/linbky/p/12091248.html
下面这段代码生成的快递单是完全符合京东快递的10 x 13尺寸的快递单,业务需求是移动端操作下单,提交并同步打印快递单。
1 package com.yutong.common.utils.print; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.Graphics2D; 7 import java.awt.Image; 8 import java.awt.image.ImageObserver; 9 import java.awt.print.Book; 10 import java.awt.print.PageFormat; 11 import java.awt.print.Paper; 12 import java.awt.print.Printable; 13 import java.awt.print.PrinterException; 14 import java.awt.print.PrinterJob; 15 import java.util.Date; 16 17 import javax.imageio.ImageIO; 18 import javax.print.DocFlavor; 19 import javax.print.PrintService; 20 import javax.print.PrintServiceLookup; 21 import javax.print.attribute.HashAttributeSet; 22 import javax.print.attribute.HashPrintRequestAttributeSet; 23 import javax.print.attribute.PrintRequestAttributeSet; 24 import javax.print.attribute.standard.PrinterName; 25 26 import org.slf4j.Logger; 27 import org.slf4j.LoggerFactory; 28 29 import com.yutong.common.utils.DateUtils; 30 import com.yutong.common.utils.StringUtils; 31 32 public class Graphic implements ImageObserver, Printable{ 33 34 private static Logger logger = LoggerFactory.getLogger(Graphic.class); 35 36 private static WayBillReceive wayBillReceive; 37 38 private static String filePath; 39 40 @Override 41 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { 42 43 //获取画笔 44 Graphics2D g2=(Graphics2D) graphics; 45 46 //设置画笔颜色 47 g2.setPaint(Color.black); 48 49 g2.translate(pageFormat.getImageableX(),pageFormat.getImageableY()); 50 51 Font font=new Font("黑体",Font.BOLD,36); 52 g2.setFont(font); 53 //外框 上9.6cm ,270px+10(外边距) 54 g2.drawLine(10, 10, 280, 10); //10 55 //外框 左5.4cm 151px+10(外边距) 56 g2.drawLine(10, 10, 10, 161); 57 //外框 下 58 g2.drawLine(10, 161, 280, 161); 59 //外框 右 60 g2.drawLine(280, 10, 280, 161); 61 62 //中间第一横 63 g2.drawLine(10, 66, 280, 66); //56+10 64 //中间第二横 65 g2.drawLine(10, 100, 280, 100);//34+66 66 67 //中间第三横 68 g2.drawLine(10, 117, 280, 117);//17+100 69 //中间第四横 70 g2.drawLine(173, 139, 280, 139);//22+117 71 72 //中部第一条竖线 73 g2.drawLine(30, 100, 30, 161); 74 //中部第二条竖线 75 g2.drawLine(145, 66, 145, 117); 76 //中部第三条竖线 77 g2.drawLine(173, 100, 173, 161); 78 //中部第四条竖线 79 g2.drawLine(201, 117, 201, 161); 80 81 //上半部分 82 //-------------------------------------------------------- 83 //下半部分 84 85 //上 86 g2.drawLine(10, 179, 280,179); //179 87 //左 88 g2.drawLine(10, 179, 10, 299); 89 //下 90 g2.drawLine(10, 299, 280, 299); 91 //右 92 g2.drawLine(280,179, 280, 299); 93 94 95 //中部第一条横线 96 g2.drawLine(10, 199, 280, 199); //20+179 97 98 //中部第二条横线 99 g2.drawLine(10, 245, 280, 245); //45+199 100 101 //中部第三条横线 102 g2.drawLine(10, 265, 280, 265); //20+245 103 104 //中部第四条横线 105 g2.drawLine(10, 282, 280, 282);//17+265 106 107 //中部第一条竖线 108 g2.drawLine(85, 245, 85, 265); 109 //中部第二条竖线 110 g2.drawLine(182, 199, 182, 299); 111 //中部第三条竖线 112 g2.drawLine(224, 245, 224, 265); 113 114 115 String fileName = StringUtils.getUuid()+".png"; 116 try { 117 118 font=new Font("黑体",Font.PLAIN,11); 119 g2.setFont(font); 120 g2.drawString("众", 268, 22); 121 122 //包裹号条形码 123 Image image = ImageIO.read(BarCodeUtil.generateBarCode(wayBillReceive.getDeliveryId()+"-1-1-", filePath+fileName)); 124 g2.drawImage(image, 12, 12, 255, 52, this); 125 126 font=new Font("黑体",Font.PLAIN,9); 127 g2.setFont(font); 128 //重量 129 g2.drawString((wayBillReceive.getWeight()==null?0.00:wayBillReceive.getWeight().doubleValue())+" KG", 220, 64); 130 131 //始发地 132 font=new Font("黑体",Font.PLAIN,9); 133 g2.setFont(font); 134 g2.drawString("始发地:"+wayBillReceive.getSourceSortCenterName(), 13, 76); 135 font=new Font("黑体",Font.BOLD,20); 136 g2.setFont(font); 137 g2.drawString(wayBillReceive.getSourceCrossCode()+"-"+wayBillReceive.getSourceTableTrolleyCode(), 20, 95); 138 139 //目的地 140 font=new Font("黑体",Font.PLAIN,9); 141 g2.setFont(font); 142 g2.drawString("目的地:"+wayBillReceive.getTargetSortCenterName(), 148, 76); 143 font=new Font("黑体",Font.BOLD,16); 144 g2.setFont(font); 145 g2.drawString(wayBillReceive.getSlideNo()+"-"+wayBillReceive.getTargetTableTrolleyCode(), 176, 92); 146 147 //目的站点 148 font=new Font("黑体",Font.PLAIN,13); 149 g2.setFont(font); 150 g2.drawString(wayBillReceive.getSiteName(), 33, 115); 151 152 //路区 153 g2.drawString(wayBillReceive.getRoad(), 148, 115); 154 155 //包裹序列 156 g2.drawString("1/1", 195, 115); 157 158 //客户信息 159 font=new Font("黑体",Font.PLAIN,9); 160 g2.setFont(font); 161 g2.drawString("客", 15, 128); 162 g2.drawString("户", 15, 138); 163 g2.drawString("信", 15, 148); 164 g2.drawString("息", 15, 158); 165 166 String address = wayBillReceive.getReceiveAddress(); 167 int y = 128; 168 if(StringUtils.isNotBlank(address)&&address.length()<=15){ 169 g2.drawString(address, 35, 128); 170 } 171 if(StringUtils.isNotBlank(address)&&address.length()>15&&address.length()<=30){ 172 g2.drawString(address.substring(0,15), 35, 128); 173 g2.drawString(address.substring(15,address.length()), 35, 138); 174 y = 140; 175 } 176 if(StringUtils.isNotBlank(address)&&address.length()>30){ 177 g2.drawString(address.substring(0,15), 35, 128); 178 g2.drawString(address.substring(15,30), 35, 138); 179 g2.drawString(address.substring(30,address.length()), 35, 148); 180 y = 150; 181 } 182 g2.drawString(wayBillReceive.getReceiveName()+" "+(wayBillReceive.getReceiveTel()==null?"":wayBillReceive.getReceiveTel())+" "+(wayBillReceive.getReceiveMobile()==null?"":wayBillReceive.getReceiveMobile()), 35, y+10); 183 y=0; 184 185 //客户签字 186 g2.drawString("客户", 176,126 ); 187 g2.drawString("签字", 176,136 ); 188 189 //应收金额 190 g2.drawString("应收", 176,148 ); 191 g2.drawString("金额", 176,158 ); 192 font=new Font("黑体",Font.PLAIN,10); 193 g2.setFont(font); 194 g2.drawString("¥0.00元", 216,152 ); 195 196 font=new Font("黑体",Font.PLAIN,6); 197 g2.setFont(font); 198 //第一个方框下方日期 199 g2.drawString(DateUtils.format(new Date(), "yyyy-MM-dd"), 175, 170); 200 201 202 203 //第二个框 204 //运单号 205 font=new Font("黑体",Font.PLAIN,13); 206 g2.setFont(font); 207 g2.drawString("运单号:"+wayBillReceive.getDeliveryId(), 90, 193); 208 209 //客户信息 210 font=new Font("黑体",Font.PLAIN,8); 211 g2.setFont(font); 212 g2.drawString("收件信息:"+wayBillReceive.getReceiveName()+" "+(wayBillReceive.getReceiveTel()==null?"":wayBillReceive.getReceiveTel())+" "+(wayBillReceive.getReceiveMobile()==null?"":wayBillReceive.getReceiveMobile()), 13, 207); 213 214 //运单号条形码 215 fileName = StringUtils.getUuid()+".png"; 216 image = ImageIO.read(BarCodeUtil.generateBarCode(wayBillReceive.getDeliveryId(), filePath+fileName)); 217 g2.drawImage(image, 12, 209, 168, 36, this); 218 219 //备注 220 font=new Font("黑体",Font.PLAIN,9); 221 g2.setFont(font); 222 y = 208; 223 String remark = "备注:"+(wayBillReceive.getRemark()==null?"":wayBillReceive.getRemark()); 224 225 if(StringUtils.isNotBlank(remark)&&remark.length()<=10){ 226 g2.drawString(remark, 184, y); 227 } 228 if(StringUtils.isNotBlank(remark)&&remark.length()>10&&remark.length()<=20){ 229 g2.drawString(remark.substring(0,10), 184, y); 230 y = y+10; 231 g2.drawString(remark.substring(10,remark.length()), 184, y); 232 233 } 234 if(StringUtils.isNotBlank(remark)&&remark.length()>20&&remark.length()<=30){ 235 g2.drawString(remark.substring(0,10), 184, y); 236 y = y+10; 237 g2.drawString(remark.substring(10,20), 184, y); 238 y = y+10; 239 g2.drawString(remark.substring(20,remark.length()), 184, y); 240 } 241 y=0; 242 243 244 //次日达、特会送 245 font=new Font("黑体",Font.BOLD,15); 246 g2.setFont(font); 247 g2.drawString((wayBillReceive.getAgingname()==null?"":wayBillReceive.getAgingname()), 25, 260); 248 g2.drawString("", 95, 260); 249 250 251 //寄方信息 252 font=new Font("黑体",Font.PLAIN,6); 253 g2.setFont(font); 254 g2.drawString("寄方信息:"+wayBillReceive.getSenderAddress(), 12, 272); 255 g2.drawString(wayBillReceive.getSenderName()+" "+(wayBillReceive.getSenderMobile()==null?"":wayBillReceive.getSenderMobile())+" "+(wayBillReceive.getSenderTel()==null?"":wayBillReceive.getSenderTel()), 12, 280); 256 257 //商家ID、商家订单号 258 g2.drawString("商家ID:"+wayBillReceive.getCustomerCode(), 185, 272); 259 g2.drawString("B商家订单号:"+wayBillReceive.getOrderId(), 185, 279); 260 261 //提示信息 262 font=new Font("黑体",Font.PLAIN,5); 263 g2.setFont(font); 264 g2.drawString("请您确认包裹完好,保留此包裹联时,代表您已经正常签收并确认外包裹完好", 12, 288); 265 g2.drawString("http://www.jdwl.com 客服电话:400-603-3600", 12, 293); 266 267 //始发城市 268 font=new Font("黑体",Font.PLAIN,6); 269 g2.setFont(font); 270 g2.drawString("始发城市:", 184, 292); 271 font=new Font("黑体",Font.PLAIN,10); 272 g2.setFont(font); 273 g2.drawString(wayBillReceive.getSendCity(), 214, 293); 274 275 //最下方的打印日期 276 font=new Font("黑体",Font.PLAIN,6); 277 g2.setFont(font); 278 g2.drawString(DateUtils.format(new Date(), "yyyy-MM-dd"), 183, 305); 279 g2.dispose(); 280 } catch (Exception e) { 281 logger.info("打印快递单异常"+e); 282 } 283 284 285 286 return Printable.PAGE_EXISTS; 287 } 288 289 @Override 290 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 291 // TODO Auto-generated method stub 292 return false; 293 } 294 295 public synchronized void print(WayBillReceive wbr,String fp){ 296 wayBillReceive = wbr; 297 filePath = fp; 298 PrinterJob printerJob=PrinterJob.getPrinterJob(); 299 300 Book book=new Book(); 301 302 PageFormat pf = new PageFormat(); 303 304 //pf.setOrientation(PageFormat.PORTRAIT); 305 306 Paper p = new Paper(); 307 308 //A4尺寸 590 x 840 309 310 p.setSize(280,317); 311 312 p.setImageableArea(0,0, 280,317); 313 314 315 // 316 // p.setSize(590,840); 317 // 318 // p.setImageableArea(12,12, 590,840); 319 320 321 322 323 pf.setPaper(p); 324 325 book.append(new Graphic(), pf); 326 327 printerJob.setPageable(book); 328 329 HashAttributeSet hs=new HashAttributeSet(); 330 331 DocFlavor flavor = DocFlavor.BYTE_ARRAY.PNG; 332 333 //HPRT PT562(USB) 334 335 //HPRT PT541(USB) 336 337 String printerName="HPRT HLP106S"; 338 // String printerName="Canon iR2520 UFRII LT"; 339 340 hs.add(new PrinterName(printerName, null)); 341 342 PrintService[] pss = PrintServiceLookup.lookupPrintServices(flavor, hs); 343 344 if(pss.length>0){ 345 346 try { 347 348 printerJob.setPrintService(pss[0]); 349 350 printerJob.print(); 351 352 } catch (PrinterException e) { 353 354 logger.info("打印快递单异常"+e); 355 356 } 357 358 } 359 360 } 361 362 }
开发过程中不可能每画一部分或者需要调整字体大小都打印一张纸用来测试,因此可以用下面这段代码来实现预览
下面代码中drawLine方法的内容完全可以用上面第一个print方法的代码代替
package com.yutong.common.utils.print; import java.awt.BasicStroke; import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.print.PageFormat; import java.io.IOException; import java.util.Date; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; import com.yutong.common.utils.DateUtils; import com.yutong.common.utils.StringUtils; public class PrintView extends JPanel { public static void main(String[] args) { /* * 在 AWT 的事件队列线程中创建窗口和组件, 确保线程安全, * 即 组件创建、绘制、事件响应 需要处于同一线程。 */ EventQueue.invokeLater(new Runnable() { @Override public void run() { // 创建窗口对象 MyFrame frame = new MyFrame(); // 显示窗口 frame.setVisible(true); } }); } /** * 窗口 */ public static class MyFrame extends JFrame { public static final String TITLE = "Java图形绘制"; public static final int WIDTH = 800; public static final int HEIGHT = 450; public MyFrame() { super(); initFrame(); } private void initFrame() { // 设置 窗口标题 和 窗口大小 setTitle(TITLE); setSize(WIDTH, HEIGHT); // 设置窗口关闭按钮的默认操作(点击关闭时退出进程) setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 把窗口位置设置到屏幕的中心 setLocationRelativeTo(null); // 设置窗口的内容面板 MyPanel panel = new MyPanel(this); setContentPane(panel); } } /** * 内容面板 */ public static class MyPanel extends JPanel { private MyFrame frame; public MyPanel(MyFrame frame) { super(); this.frame = frame; } /** * 绘制面板的内容: 创建 JPanel 后会调用一次该方法绘制内容, * 之后如果数据改变需要重新绘制, 可调用 updateUI() 方法触发 * 系统再次调用该方法绘制更新 JPanel 的内容。 */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 重新调用 Graphics 的绘制方法绘制时将自动擦除旧的内容 /* 自行打开下面注释查看各绘制效果 */ // 1. 线段 / 折线 drawLine(g); // 2. 矩形 / 多边形 // drawRect(g); // 3. 圆弧 / 扇形 // drawArc(g); // 4. 椭圆 // drawOval(g); // 5. 图片 // drawImage(g); // 6. 文本 // drawString(g); } /** * 1. 线段 / 折线 */ private void drawLine(Graphics g) { //获取画笔 Graphics2D g2=(Graphics2D) g.create(); //设置画笔颜色 g2.setPaint(Color.gray); PageFormat pageFormat = new PageFormat(); g2.translate(pageFormat.getImageableX(),pageFormat.getImageableY()); Font font=new Font("黑体",Font.BOLD,36); g2.setFont(font); //外框 上9.6cm ,270px+10(外边距) g2.drawLine(10, 10, 280, 10); //10 //外框 左5.4cm 151px+10(外边距) g2.drawLine(10, 10, 10, 161); //外框 下 g2.drawLine(10, 161, 280, 161); //外框 右 g2.drawLine(280, 10, 280, 161); //中间第一横 g2.drawLine(10, 66, 280, 66); //56+10 //中间第二横 g2.drawLine(10, 100, 280, 100);//34+66 //中间第三横 g2.drawLine(10, 117, 280, 117);//17+100 //中间第四横 g2.drawLine(173, 139, 280, 139);//22+117 //中部第一条竖线 g2.drawLine(30, 100, 30, 161); //中部第二条竖线 g2.drawLine(145, 66, 145, 117); //中部第三条竖线 g2.drawLine(173, 100, 173, 161); //中部第四条竖线 g2.drawLine(201, 117, 201, 161); //上半部分 //-------------------------------------------------------- //下半部分 //上 g2.drawLine(10, 179, 280,179); //179 //左 g2.drawLine(10, 179, 10, 299); //下 g2.drawLine(10, 299, 280, 299); //右 g2.drawLine(280,179, 280, 299); //中部第一条横线 g2.drawLine(10, 199, 280, 199); //20+179 //中部第二条横线 g2.drawLine(10, 245, 280, 245); //45+199 //中部第三条横线 g2.drawLine(10, 265, 280, 265); //20+245 //中部第四条横线 g2.drawLine(10, 282, 280, 282);//17+265 //中部第一条竖线 g2.drawLine(85, 245, 85, 265); //中部第二条竖线 g2.drawLine(182, 199, 182, 299); //中部第三条竖线 g2.drawLine(224, 245, 224, 265); g2.setPaint(Color.black); String fileName = StringUtils.getUuid()+".png"; try { font=new Font("黑体",Font.PLAIN,12); g2.setFont(font); g2.drawString("众", 268, 22); //包裹号条形码 Image image = ImageIO.read(BarCodeUtil.generateBarCode("JD20191211-1-1", "D://"+fileName)); g2.drawImage(image, 12, 12, 255, 52, this); font=new Font("黑体",Font.PLAIN,9); g2.setFont(font); //重量 g2.drawString("0.5 KG", 220, 61); //始发地 font=new Font("黑体",Font.PLAIN,9); g2.setFont(font); g2.drawString("始发地:河南郑州", 13, 76); font=new Font("黑体",Font.BOLD,20); g2.setFont(font); g2.drawString("23-CC-K", 40, 95); //目的地 font=new Font("黑体",Font.PLAIN,9); g2.setFont(font); g2.drawString("目的地:上海浦东", 148, 76); font=new Font("黑体",Font.BOLD,20); g2.setFont(font); g2.drawString("6-K04", 176, 95); //目的站点 font=new Font("黑体",Font.PLAIN,13); g2.setFont(font); g2.drawString("G上海塘桥营业部", 33, 115); //路区 g2.drawString("84", 148, 115); //包裹序列 g2.drawString("包裹序列", 195, 115); //客户信息 font=new Font("黑体",Font.PLAIN,9); g2.setFont(font); g2.drawString("客", 15, 128); g2.drawString("户", 15, 138); g2.drawString("信", 15, 148); g2.drawString("息", 15, 158); String address = "河南省郑州市郑东新区上河南省郑州市郑省郑州市"; int y = 128; if(StringUtils.isNotBlank(address)&&address.length()<=15){ g2.drawString(address, 35, 128); } if(StringUtils.isNotBlank(address)&&address.length()>15&&address.length()<=30){ g2.drawString(address.substring(0,15), 35, 128); g2.drawString(address.substring(15,address.length()), 35, 140); y = 140; } if(StringUtils.isNotBlank(address)&&address.length()>30){ g2.drawString(address.substring(0,15), 35, 128); g2.drawString(address.substring(15,30), 35, 140); g2.drawString(address.substring(30,address.length()), 35, 150); y = 150; } g2.drawString("小哪吒 15613223333", 35, y+10); y=0; //客户签字 g2.drawString("客户", 176,126 ); g2.drawString("签字", 176,136 ); //应收金额 g2.drawString("应收", 176,148 ); g2.drawString("金额", 176,158 ); font=new Font("黑体",Font.PLAIN,10); g2.setFont(font); g2.drawString("¥8元", 216,152 ); font=new Font("黑体",Font.PLAIN,6); g2.setFont(font); //第一个方框下方日期 g2.drawString(DateUtils.format(new Date(), "yyyy-MM-dd"), 175, 170); //第二个框 //运单号 font=new Font("黑体",Font.PLAIN,13); g2.setFont(font); g2.drawString("运单号:JD20191211", 75, 193); //客户信息 font=new Font("黑体",Font.PLAIN,8); g2.setFont(font); g2.drawString("收件信息:小哪吒 15612312215", 13, 207); //运单号条形码 fileName = StringUtils.getUuid()+".png"; image = ImageIO.read(BarCodeUtil.generateBarCode("JD20191211", "D://"+fileName)); g2.drawImage(image, 12, 209, 168, 36, this); //备注 font=new Font("黑体",Font.PLAIN,9); g2.setFont(font); y = 208; String remark = "备注:"+"热力裤为了任务了了离开的苟富贵丰东接口健康快乐"; if(StringUtils.isNotBlank(remark)&&remark.length()<=10){ g2.drawString(remark, 184, y); } if(StringUtils.isNotBlank(remark)&&remark.length()>10&&remark.length()<=20){ g2.drawString(remark.substring(0,10), 184, y); y = y+10; g2.drawString(remark.substring(10,remark.length()), 184, y); } if(StringUtils.isNotBlank(remark)&&remark.length()>20&&remark.length()<=30){ g2.drawString(remark.substring(0,10), 184, y); y = y+10; g2.drawString(remark.substring(10,20), 184, y); y = y+10; g2.drawString(remark.substring(20,remark.length()), 184, y); } y=0; //次日达、特会送 font=new Font("黑体",Font.BOLD,15); g2.setFont(font); g2.drawString("次日达", 25, 260); g2.drawString("特惠送", 95, 260); //寄方信息 font=new Font("黑体",Font.PLAIN,6); g2.setFont(font); g2.drawString("寄方信息:河南省郑州市中原区西流湖小河边", 12, 272); g2.drawString("小敖丙 18956562321", 12, 280); //商家ID、商家订单号 g2.drawString("商家ID:021K56554545", 185, 272); g2.drawString("B商家订单号:8965466", 185, 279); //提示信息 font=new Font("黑体",Font.PLAIN,5); g2.setFont(font); g2.drawString("请您确认包裹完好,保留此包裹联时,代表您已经正常签收并确认外包裹完好", 12, 288); g2.drawString("http://www.jdwl.com 客服电话:400-603-3600", 12, 293); //始发城市 font=new Font("黑体",Font.PLAIN,6); g2.setFont(font); g2.drawString("始发城市:", 184, 292); font=new Font("黑体",Font.PLAIN,10); g2.setFont(font); g2.drawString("郑州市", 214, 293); //最下方的打印日期 font=new Font("黑体",Font.PLAIN,6); g2.setFont(font); g2.drawString(DateUtils.format(new Date(), "yyyy-MM-dd"), 183, 305); } catch (IOException e) { // TODO Auto-generated catch blo e.printStackTrace(); } g2.dispose(); } } }