使用java Graphics 绘图工具生成顺丰快递电子面单

2020-12-13 05:14

阅读:305

标签:line   rac   手机   怎样   不能   图片格式   快递单号   day   ||   

      最近公司需要开发一个公司内部使用的快递下单系统,给我的开发任务中有一个生成电子面单功能,为了下单时更方便,利用此功能使用快递公司给我们的打印机直接打印出电子面单,刚接到这个任务时我想这应该很简单,不就是做一个表格打印出来吗,原本以为使用excel或者word等工具直接生成一个文档,后来经理说不用excel和word工具,让用Java直接生成电子面单,刚开始有点懵,因为不知道Java还有绘图功能,因此在网上学习了一下Java怎样绘图,索性直接开干。

     废话不多说直接上代码。

 一、    首先是生成条码工具类,此类是生成快递单号条码。

     SFBarCodeGenerateUtil.java

  1 package testNetty.wu;
  2 
  3 import java.awt.Color;
  4 import java.awt.Graphics;
  5 import java.awt.Image;
  6 import java.awt.image.BufferedImage;
  7 import java.io.BufferedInputStream;
  8 import java.io.BufferedOutputStream;
  9 import java.io.File;
 10 import java.io.FileInputStream;
 11 import java.io.FileNotFoundException;
 12 import java.io.FileOutputStream;
 13 import java.io.OutputStream;
 14 import java.util.ArrayList;
 15 import java.util.List;
 16 import java.util.regex.Pattern;
 17 
 18 import javax.imageio.ImageIO;
 19 
 20 import org.apache.log4j.Logger;
 21 
 22 
 23 import com.sun.image.codec.jpeg.JPEGCodec;
 24 import com.sun.image.codec.jpeg.JPEGImageEncoder;
 25 
 26 /**
 27  * 顺丰速运条码生成工具
28 * 采用 code128c编码规则
29 *
30 * CODE128C:[00]-[99]的数字对集合,共100个 31 * 即只能表示偶数位长度的数字 32 *
33 * @author wu 34 * @version 1.0 35 * @Time 2017/03/29 36 * */ 37 public class SFBarCodeGenerateUtil { 38 39 private static final Logger logger = Logger.getLogger(SFBarCodeGenerateUtil.class.getSimpleName()); 40 41 /**图片格式 jpg 格式*/ 42 public static final String PICTURE_JPG = "JPG"; 43 /**图片格式 png 格式*/ 44 public static final String PICTURE_PNG = "PNG"; 45 /**图片格式 gif 格式*/ 46 public static final String PICTURE_GIF = "GIF"; 47 48 /** code128编码字符集 二维数组*/ 49 private static String[][] code128 = { 50 { " ", " ", "00", "212222", "11011001100" }, 51 { "!", "!", "01", "222122", "11001101100" }, 52 { "\"", "\"", "02", "222221", "11001100110" }, 53 { "#", "#", "03", "121223", "10010011000" }, 54 { "$", "$", "04", "121322", "10010001100" }, 55 { "%", "%", "05", "131222", "10001001100" }, 56 { "&", "&", "06", "122213", "10011001000" }, 57 { "‘", "‘", "07", "122312", "10011000100" }, 58 { "(", "(", "08", "132212", "10001100100" }, 59 { ")", ")", "09", "221213", "11001001000" }, 60 { "*", "*", "10", "221312", "11001000100" }, 61 { "+", "+", "11", "231212", "11000100100" }, 62 { ",", ",", "12", "112232", "10110011100" }, 63 { "-", "-", "13", "122132", "10011011100" }, 64 { ".", ".", "14", "122231", "10011001110" }, 65 { "/", "/", "15", "113222", "10111001100" }, 66 { "0", "0", "16", "123122", "10011101100" }, 67 { "1", "1", "17", "123221", "10011100110" }, 68 { "2", "2", "18", "223211", "11001110010" }, 69 { "3", "3", "19", "221132", "11001011100" }, 70 { "4", "4", "20", "221231", "11001001110" }, 71 { "5", "5", "21", "213212", "11011100100" }, 72 { "6", "6", "22", "223112", "11001110100" }, 73 { "7", "7", "23", "312131", "11101101110" }, 74 { "8", "8", "24", "311222", "11101001100" }, 75 { "9", "9", "25", "321122", "11100101100" }, 76 { ":", ":", "26", "321221", "11100100110" }, 77 { ";", ";", "27", "312212", "11101100100" }, 78 { " }, 79 { "=", "=", "29", "322211", "11100110010" }, 80 { ">", ">", "30", "212123", "11011011000" }, 81 { "?", "?", "31", "212321", "11011000110" }, 82 { "@", "@", "32", "232121", "11000110110" }, 83 { "A", "A", "33", "111323", "10100011000" }, 84 { "B", "B", "34", "131123", "10001011000" }, 85 { "C", "C", "35", "131321", "10001000110" }, 86 { "D", "D", "36", "112313", "10110001000" }, 87 { "E", "E", "37", "132113", "10001101000" }, 88 { "F", "F", "38", "132311", "10001100010" }, 89 { "G", "G", "39", "211313", "11010001000" }, 90 { "H", "H", "40", "231113", "11000101000" }, 91 { "I", "I", "41", "231311", "11000100010" }, 92 { "J", "J", "42", "112133", "10110111000" }, 93 { "K", "K", "43", "112331", "10110001110" }, 94 { "L", "L", "44", "132131", "10001101110" }, 95 { "M", "M", "45", "113123", "10111011000" }, 96 { "N", "N", "46", "113321", "10111000110" }, 97 { "O", "O", "47", "133121", "10001110110" }, 98 { "P", "P", "48", "313121", "11101110110" }, 99 { "Q", "Q", "49", "211331", "11010001110" }, 100 { "R", "R", "50", "231131", "11000101110" }, 101 { "S", "S", "51", "213113", "11011101000" }, 102 { "T", "T", "52", "213311", "11011100010" }, 103 { "U", "U", "53", "213131", "11011101110" }, 104 { "V", "V", "54", "311123", "11101011000" }, 105 { "W", "W", "55", "311321", "11101000110" }, 106 { "X", "X", "56", "331121", "11100010110" }, 107 { "Y", "Y", "57", "312113", "11101101000" }, 108 { "Z", "Z", "58", "312311", "11101100010" }, 109 { "[", "[", "59", "332111", "11100011010" }, 110 { "\\", "\\", "60", "314111", "11101111010" }, 111 { "]", "]", "61", "221411", "11001000010" }, 112 { "^", "^", "62", "431111", "11110001010" }, 113 { "_", "_", "63", "111224", "10100110000" }, 114 { "NUL", "`", "64", "111422", "10100001100" }, 115 { "SOH", "a", "65", "121124", "10010110000" }, 116 { "STX", "b", "66", "121421", "10010000110" }, 117 { "ETX", "c", "67", "141122", "10000101100" }, 118 { "EOT", "d", "68", "141221", "10000100110" }, 119 { "ENQ", "e", "69", "112214", "10110010000" }, 120 { "ACK", "f", "70", "112412", "10110000100" }, 121 { "BEL", "g", "71", "122114", "10011010000" }, 122 { "BS", "h", "72", "122411", "10011000010" }, 123 { "HT", "i", "73", "142112", "10000110100" }, 124 { "LF", "j", "74", "142211", "10000110010" }, 125 { "VT", "k", "75", "241211", "11000010010" }, 126 { "FF", "I", "76", "221114", "11001010000" }, 127 { "CR", "m", "77", "413111", "11110111010" }, 128 { "SO", "n", "78", "241112", "11000010100" }, 129 { "SI", "o", "79", "134111", "10001111010" }, 130 { "DLE", "p", "80", "111242", "10100111100" }, 131 { "DC1", "q", "81", "121142", "10010111100" }, 132 { "DC2", "r", "82", "121241", "10010011110" }, 133 { "DC3", "s", "83", "114212", "10111100100" }, 134 { "DC4", "t", "84", "124112", "10011110100" }, 135 { "NAK", "u", "85", "124211", "10011110010" }, 136 { "SYN", "v", "86", "411212", "11110100100" }, 137 { "ETB", "w", "87", "421112", "11110010100" }, 138 { "CAN", "x", "88", "421211", "11110010010" }, 139 { "EM", "y", "89", "212141", "11011011110" }, 140 { "SUB", "z", "90", "214121", "11011110110" }, 141 { "ESC", "{", "91", "412121", "11110110110" }, 142 { "FS", "|", "92", "111143", "10101111000" }, 143 { "GS", "},", "93", "111341", "10100011110" }, 144 { "RS", "~", "94", "131141", "10001011110" }, 145 { "US", "DEL", "95", "114113", "10111101000" }, 146 { "FNC3", "FNC3", "96", "114311", "10111100010" }, 147 { "FNC2", "FNC2", "97", "411113", "11110101000" }, 148 { "SHIFT", "SHIFT", "98", "411311", "11110100010" }, 149 { "CODEC", "CODEC", "99", "113141", "10111011110" }, 150 { "CODEB", "FNC4", "CODEB", "114131", "10111101110" }, 151 { "FNC4", "CODEA", "CODEA", "311141", "11101011110" }, 152 { "FNC1", "FNC1", "FNC1", "411131", "11110101110" }, 153 { "StartA", "StartA", "StartA", "211412", "11010000100" }, 154 { "StartB", "StartB", "StartB", "211214", "11010010000" }, 155 { "StartC", "StartC", "StartC", "211232", "11010011100" }, 156 { "Stop", "Stop", "Stop", "2331112", "1100011101011" }, 157 }; 158 159 /** 160 * 生产Code128的条形码的code 161 * @param barCode 生成条码的数字号码 162 * @return 163 */ 164 private static String getCode(String barCode) { 165 String rtnCode = "";// 返回的参数 166 List rtnCodeNumb = new ArrayList();// 2截取位的组合 167 int examine = 105; // 首位 168 // 编码不能是奇数 169 if (!((barCode.length() & 1) == 0)) 170 return ""; 171 while (barCode.length() != 0) { 172 int temp = 0; 173 try { 174 // Code128 编码必须为数字 175 temp = (Integer) Integer.valueOf(barCode.substring(0, 2)); 176 } catch (Exception e) { 177 e.printStackTrace(); 178 return ""; 179 } 180 // 获得条纹 181 rtnCode += getValue(barCode, barCode.substring(0, 2), temp); 182 rtnCodeNumb.add(temp); 183 // 条码截取2个就需要去掉用过的前二位 184 barCode = barCode.substring(2); 185 } 186 if (rtnCodeNumb.size() == 0) { 187 return ""; 188 } 189 rtnCode = getValue(examine) + rtnCode; // 获取开始位 190 for (int i = 0; i != rtnCodeNumb.size(); i++) { 191 examine += rtnCodeNumb.get(i) * (i + 1); 192 } 193 examine = examine % 103; // 获得校验位 194 rtnCode += getValue(examine); // 获取校验位 195 rtnCode += "1100011101011"; // 结束位 196 return rtnCode; 197 } 198 199 /** 200 * 根据编号获得条纹 201 * 202 * @param encode 203 * @param p_Value 204 * @param p_SetID 205 * @return 206 */ 207 private static String getValue(String encode, String p_Value, int p_SetID) { 208 return code128[p_SetID][4]; 209 } 210 211 /** 212 * 根据编号获得条纹 213 * @param p_CodeId 214 * @return 215 */ 216 private static String getValue(int p_CodeId) { 217 return code128[p_CodeId][4]; 218 } 219 220 // 条码的高度像素数 221 private static int m_nImageHeight = 40; 222 223 /** 224 * 生成条码 225 * @param barString 条码模式字符串 226 * @param path 生成条码图片的路径 227 */ 228 private static boolean kiCode128C(String barString, String path) { 229 OutputStream out = null; 230 try { 231 File myPNG = new File(path); 232 out = new FileOutputStream(myPNG); 233 int nImageWidth = 0; 234 char[] cs = barString.toCharArray(); 235 for (int i = 0; i != cs.length; i++) { 236 nImageWidth = cs.length; 237 } 238 BufferedImage bi = new BufferedImage(nImageWidth, m_nImageHeight, 239 BufferedImage.TYPE_INT_RGB); 240 Graphics g = bi.getGraphics(); 241 for (int i = 0; i ) { 242 if ("1".equals(cs[i] + "")) { 243 g.setColor(Color.BLACK); 244 g.fillRect(i, 0, 1, m_nImageHeight); 245 } else { 246 g.setColor(Color.WHITE); 247 g.fillRect(i, 0, 1, m_nImageHeight); 248 } 249 } 250 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 251 encoder.encode(bi); 252 return true; 253 } catch (FileNotFoundException fe) { 254 logger.error("系统找不到指定路径!!" + path, fe); 255 return false; 256 } catch (Exception e) { 257 e.printStackTrace(); 258 } finally { 259 try { 260 if (out != null) 261 out.close(); 262 } catch (Exception e2) { 263 e2.printStackTrace(); 264 } 265 } 266 return false; 267 } 268 269 /** 270 * 生成条形码
271 * 条码是图片格式(JPG、PNG、GIF) 272 * @param wayBillNo 273 * 运单号 274 * @param generatePathName 275 * 生成条形码路径及名称 276 * @param width 277 * 条码图片宽度 278 * @param height 279 * 条码图片高度 280 * @param picTyp 281 * 图片格式
282 * JPG、PNG、GIF三种图片类型选择 283 * @return boolean类型值 284 * true 生成成功,false 生成失败 285 * */ 286 public static boolean generateBarCode(String wayBillNo, String generatePathName, int width, 287 int height, String picTyp){ 288 //只能是数字 289 if (!Pattern.matches("[0-9]+", wayBillNo)) { 290 logger.error("生成CODE128C条码只能是0~9的数字不能有其他字符!!"); 291 //运单号长度只能是偶数 292 } else if (wayBillNo.length() % 2 != 0) { 293 logger.error("生成CODE128C条码的长度只能是偶数!!"); 294 //生成条码 295 } else if (kiCode128C(getCode(wayBillNo), generatePathName)){ 296 /** 297 * 设置条码图片的尺寸 298 * */ 299 BufferedInputStream bis = null; 300 BufferedOutputStream out = null; 301 try { 302 File sfFile = new File(generatePathName); 303 if (sfFile.isFile() && sfFile.exists()) { 304 //读取图片 305 bis = new BufferedInputStream(new FileInputStream(generatePathName)); 306 //转换成图片对象 307 Image bi = ImageIO.read(bis); 308 //构建图片流 设置图片宽和高 309 BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 310 //绘制改变尺寸后的图 311 tag.getGraphics().drawImage(bi, 0, 0,width, height, null); 312 //保存图片 313 out = new BufferedOutputStream(new FileOutputStream(generatePathName)); 314 ImageIO.write(tag, picTyp,out); 315 out.flush(); 316 } 317 } catch (Exception e) { 318 e.printStackTrace(); 319 } finally { 320 try { 321 if (out != null) 322 out.close(); 323 if (bis != null) 324 bis.close(); 325 } catch (Exception e2) { 326 e2.printStackTrace(); 327 } 328 } 329 logger.info("条码生成成功. " + generatePathName + " 像素:" + width + "*" + height); 330 return true; 331 } 332 logger.error("条码生成失败!"); 333 return false; 334 } 335 336 }

二、其次是生成电子面单表格类,包含条码、单号、寄件人和收件人信息。

SFOrderGenerateUtil.java

   1 package testNetty.wu;
   2 
   3 import java.awt.BasicStroke;
   4 import java.awt.Color;
   5 import java.awt.Font;
   6 import java.awt.Graphics2D;
   7 import java.awt.Image;
   8 import java.awt.RenderingHints;
   9 import java.awt.image.BufferedImage;
  10 import java.io.BufferedInputStream;
  11 import java.io.BufferedOutputStream;
  12 import java.io.ByteArrayOutputStream;
  13 import java.io.File;
  14 import java.io.FileInputStream;
  15 import java.io.FileNotFoundException;
  16 import java.io.FileOutputStream;
  17 import java.io.IOException;
  18 
  19 import javax.imageio.ImageIO;
  20 
  21 import org.apache.commons.io.FileUtils;
  22 import org.apache.log4j.Logger;
  23 
  24 import com.sun.image.codec.jpeg.JPEGCodec;
  25 import com.sun.image.codec.jpeg.JPEGEncodeParam;
  26 import com.sun.image.codec.jpeg.JPEGImageEncoder;
  27 
  28 /**
  29  * 生成电子面单图片工具
  30  * @author wu
  31  * @version 1.0
  32  * @time 2017/04/25
  33  * */
  34 public class SFOrderGenerateUtil {
  35     
  36      private static final Logger logger = Logger.getLogger(SFOrderGenerateUtil.class.getSimpleName());
  37     
  38      //图片的宽度
  39      public static final int IMG_WIDTH = 1198;
  40      //图片的宽度
  41      public static final int IMG_HEIGHT = 1800;
  42      //LOGO的宽度
  43      public static final int LOGO_WIDTH = 240; 
  44      //LOGO高度
  45      public static final int LOGO_HEIGHT = 100; 
  46      //LOGO客服电话的宽度
  47      public static final int LOGO_TEL_WIDTH = 220; 
  48      //LOGO客服电话高度
  49      public static final int LOGO_TEL_HEIGHT = 84; 
  50      
  51      //Logo路径
  52      public static final String LOGO_PATH = "C:\\Users\\Administrator\\Desktop\\expressLogo\\logoSC.png";
  53      //Logo客服电话
  54      public static final String LOGO_TEL_PATH = "C:\\Users\\Administrator\\Desktop\\expressLogo\\sf_Tel.png";;
  55      
  56     
  57      public static BufferedImage image;  
  58      public static void createImage(String fileLocation) {  
  59          FileOutputStream fos = null;
  60          BufferedOutputStream bos = null;
  61          try {  
  62               fos = new FileOutputStream(fileLocation);  
  63               bos = new BufferedOutputStream(fos);  
  64               JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);  
  65               encoder.encode(image);  
  66          } catch (Exception e) {  
  67                e.printStackTrace();  
  68          } finally {
  69              try {
  70                  if (bos != null) bos.close();
  71                  if (fos != null) fos.close();
  72             } catch (Exception e2) {
  73                 e2.printStackTrace();
  74             }
  75          }
  76     }  
  77     
  78      /**
  79       * 生成订单图片
  80       * @param orderPath 
  81       *                 生成订单存放路径
  82       * @param printTyp
  83       *                 订单打印类型 1:A4纸打印   2:热敏纸打印
  84       * @param orderParam 
  85       *                 生成订单所需的参数对象
  86       * @param isCompress
  87       *                 是否需要根据输入宽高压缩图片
  88       * 
89 * isCompress 为ture时 所输入的宽高才起作用 90 *
91 * @param imgWidth 92 * 图片宽度 93 * @param imgHeidht 94 * 图片高度 95 * @author Administrator 96 * @return 97 * 98 * */ 99 public static boolean generateOrders(String orderPath, SfPrintOrderParam orderParam, String printTyp, boolean isCompress, int imgWidth, int imgHeidht){ 100 if (null == orderParam) 101 return false; 102 int startHeight = 0; //表格的起始高度 103 int startWidth = 0; //表格的起始宽度 104 try { 105 if (orderParam.getSubMailNos().size() == 0 || orderParam.getSubMailNos().isEmpty()) { 106 generateParentOrder(orderPath, orderParam, printTyp, isCompress, imgWidth, imgHeidht); 107 return true; 108 } else { 109 String picPath = orderPath; 110 File mk = new File(picPath + orderParam.getMailNo()); 111 if (mk.exists()){ 112 FileUtils.deleteDirectory(mk); 113 } 114 for (int k = 0; k ) { 115 image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_RGB); 116 Graphics2D g = image.createGraphics(); 117 //以运单号为名称创建存放订单的目录 118 FileUtils.forceMkdir(mk); 119 picPath += orderParam.getMailNo() + "/"; 120 121 //设置背景色为白色 122 g.setColor(Color.WHITE); 123 //设置颜色区域大小 124 g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT); 125 //提高导入Img的清晰度 126 127 128 /* 129 * 绘制表格 填充内容 130 * */ 131 //表格线条的颜色 132 g.setColor(Color.BLACK); 133 134 //消除文本出现锯齿现象 135 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 136 //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); 137 138 //表格的四个边框 139 g.drawLine(startWidth, startHeight, startWidth + 374, startHeight); //上边框 140 g.drawLine(startWidth, startHeight, startWidth, startHeight + 562); //左边框 141 g.drawLine(startWidth, startHeight + 562, startWidth + 375, startHeight + 562); //下边框 142 g.drawLine(startWidth + 374, startHeight, startWidth + 374, startHeight + 563); //右边框 143 144 //绘制表格内容 第一行 145 g.drawLine(startWidth, startHeight + 48, startWidth + 375, startHeight + 48); 146 147 //插入顺丰速运Logo 148 Image logoImg = insertImage(LOGO_PATH, LOGO_WIDTH, LOGO_HEIGHT, true); 149 g.drawImage(logoImg, startWidth + 4, startHeight + 8, null); 150 //插入第二个logo (客服电话) 151 Image logoTelImg = insertImage(LOGO_TEL_PATH, LOGO_TEL_WIDTH, LOGO_TEL_HEIGHT, true); 152 g.drawImage(logoTelImg, startWidth + 280, startHeight + 15, null); 153 154 //填写产品类型 155 Font fontSfTyp = new Font("黑体", Font.BOLD, 36); 156 g.setFont(fontSfTyp); 157 //产品类型字符串 158 String sfProTypStr = orderParam.getEarthCarryFlag(); 159 g.drawString(sfProTypStr, startWidth + 150, startHeight + 41); 160 161 //绘制第二行 162 g.drawLine(startWidth, startHeight + 124, startWidth + 375, startHeight + 124); 163 g.drawLine(startWidth + 276, startHeight + 48, startWidth + 276, startHeight + 124); 164 165 //生成code128c 条码 166 SFBarCodeGenerateUtil.generateBarCode(orderParam.getMailNo(), //运单号 167 picPath + "SFBarCoding_" + orderParam.getMailNo() + ".jpg", //图片名称 168 262, //图片宽度 169 45, //图片高度 170 SFBarCodeGenerateUtil.PICTURE_JPG); 171 //导入条码图片 172 Image sfBarImg = insertImage(picPath + "SFBarCoding_" + orderParam.getMailNo() + ".jpg", 0, 0, false); 173 g.drawImage(sfBarImg, startWidth + 7, startHeight + 53, null); 174 sfBarImg.flush(); 175 176 //设置字体 177 Font fontSfBarCode = new Font("黑体",Font.BOLD,10); 178 g.setFont(fontSfBarCode); 179 180 String pageNum = (k + 1) + "/" + orderParam.getSubMailNos().size(); 181 g.drawString(pageNum, startWidth + 7, startHeight + 108); 182


评论


亲,登录后才可以留言!