使用java Graphics 繪圖工具生成順豐快遞電子面單

来源:https://www.cnblogs.com/wm-dv/archive/2019/07/04/11135573.html
-Advertisement-
Play Games

最近公司需要開發一個公司內部使用的快遞下單系統,給我的開發任務中有一個生成電子面單功能,為了下單時更方便,利用此功能使用快遞公司給我們的印表機直接列印出電子面單,剛接到這個任務時我想這應該很簡單,不就是做一個表格列印出來嗎,原本以為使用excel或者word等工具直接生成一個文檔,後來經理說不用ex ...


      最近公司需要開發一個公司內部使用的快遞下單系統,給我的開發任務中有一個生成電子面單功能,為了下單時更方便,利用此功能使用快遞公司給我們的印表機直接列印出電子面單,剛接到這個任務時我想這應該很簡單,不就是做一個表格列印出來嗎,原本以為使用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  * 順豐速運條碼生成工具<br/>
 28  * 採用 code128c編碼規則<br/>
 29  * <pre>
 30  *    CODE128C:[00]-[99]的數字對集合,共100個
 31  *    即只能表示偶數位長度的數字
 32  * </pre>
 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             { "<", "<", "28", "322112", "11100110100" },
 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<Integer> rtnCodeNumb = new ArrayList<Integer>();// 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 < cs.length; 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      * 生成條形碼<br/>
271      * 條碼是圖片格式(JPG、PNG、GIF)
272      * @param wayBillNo 
273      *            運單號
274      * @param generatePathName 
275      *            生成條形碼路徑及名稱
276      * @param width 
277      *            條碼圖片寬度
278      * @param height
279      *            條碼圖片高度
280      * @param picTyp
281      *            圖片格式<br/>
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       * <pre>
  89       *        isCompress 為ture時 所輸入的寬高才起作用
  90       * </pre>
  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<

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Web Service技術在我第一次接觸,又沒有實際使用時完全不理解這是什麼。以為是一種類似Spring,Shiro的編程框架。後來漸漸理解,WS(即Web Service縮寫)是一種通用的介面規範,並按照該規範編寫介面對外提供服務。 ...
  • 一、簡介 在使用mybatis時我們需要重覆的去創建pojo類、mapper文件以及dao類並且需要配置它們之間的依賴關係,比較麻煩且做了大量的重覆工作,mybatis官方也發現了這個問題, 因此給我們提供了mybatis generator工具來幫我們自動創建pojo類、mapper文件以及dao ...
  • 1. 為什麼是Spring Cloud Gateway 一句話,Spring Cloud已經放棄Netflix Zuul了。現在Spring Cloud中引用的還是Zuul 1.x版本,而這個版本是基於過濾器的,是阻塞IO,不支持長連接。Zuul 2.x版本跟1.x的架構大一樣,性能也有所提升。既然 ...
  • ​ 1.python的歷史 python2和python3的區別 python2 源碼不統一,重覆代碼 python 源碼統一,沒有重覆代碼 2004 Django框架的誕生 2.python是編程語言 3.python的種類 4.變數 變數定義的規則: 一個變數名在記憶體中只有一個。 5.常量 變數 ...
  • 一、Redis集群簡介 1、RedisCluster概念 Redis的分散式解決方案,在3.0版本後推出的方案,有效地解決了Redis分散式的需求,當一個服務宕機可以快速的切換到另外一個服務。redis cluster主要是針對海量數據+高併發+高可用的場景。 二、與SpringBoot2.0整合 ...
  • 下載地址 ...
  • 提交leetcode的時候遇到了問題,一直說訪問越界,但仔仔細細檢查n多遍,就是檢查不出來。 因為我用到了count全局變數,自加一來表明當前數組訪問的位置, 後來突然想到,是不是在運行的時候沒有對這個全局變數清零…… 果然,清零之後就可以了……已經3:47了,這裡先上代碼,明天再詳細說吧…… ch ...
  • 1.什麼是Redis? Redis(Remote Dictionary Server)遠程字典伺服器。 是完全開源免費的,用C語言編寫的,遵守BSD協議,是一個高性能的(key/value)分散式記憶體資料庫,基於記憶體運行並支持持久化的NoSql資料庫,是當前最熱門的NoSql資料庫之一,也被人們稱為 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...