原創/朱季謙
這款工具是筆者在2018年初開發完成的,時隔兩載,偶然想起這款小工具,於是,決定將其開源,若有人需要做類似Java批處理實現整理文件的工具,可參考該工具邏輯思路來實現。
該工具是執行在windos系統上的,基於bat指令碼與jar包形式協同執行,當時開發該工具的背景是,需要定時處理大批量的對賬單txt文字資訊,將其統一整合到一張Excel文件上,供會計人員獲取。在沒有該工具之前,專案組上的會計人員,需要每天手動開啟大量txt文字,並從每份txt文件裡,複製所需資訊,將獲取到的資訊再複製到一份當日的Excel文件裡。這個過程花費需近一小時,且重複操作,基於這個原因,當時就開發了這款小工具,供會計人員使用,其帶來的效果是,節省了大量整理時間:會計人員只需把每天郵件收到的對賬單txt,統一放到指定目錄下,點選start啟動指令碼,就可一鍵自動批量處理完成。
這個工具在當時的工作環境下,是行之有效的,但若換到另一種領域或者環境,還需二次開發做修改。工具整體實現的邏輯並不複雜,筆者只提供一種解決文件重複工作的小思路,僅做參考學習之用,畢竟,解決問題的本質不在於工具,而在於思路。
下面,就圍繞著業務與具體實現來結束該自動處理工具。
整體結構如下:
1.對賬單:將同型別對賬單批量放入到對賬單資料夾中,同類,即格式幾乎一樣,但資料不一樣,如下所示:
2.對賬單集處理結果:批量處理獲取到的資料,會統一寫入到一份自動生成的Excel文件裡,該文件存放在“對賬單集處理結果”目錄底下;
3.Auto.jar:由Java語言開發的jar包,通過迴圈讀取各txt文字資料,從讀取文字指定欄位資料,擷取其名字與對應保證金、可用資金,再寫入到自動生成的Excel文件裡。
4.CopyName.bat:bat指令碼,將本目錄下的txt檔名批量寫入到“對賬單批量名字集合.txt”;
CopyName.bat如下:
1 @dir /a-d /b *.txt>對賬單批量名字集合.txt
5.Start.bat:bat指令碼,主要實現是,將CopyName.bat和“對賬單批量名字集合.txt”都複製到“對賬單”目錄,然後執行CopyName.bat,將該目錄底下的所有.txt字尾的檔名,寫入到“對賬單批量名字集合.txt”,再啟動Auto.jar包,該jar會去“對賬單批量名字集合.txt”獲取所在目錄下各txt文件名字,再根據這些名字去讀取對應的txt文件。
Start.bat主要程式碼如下:
1 @echo off 2 copy /y CopyName.bat 對賬單 3 copy /y 對賬單批量名字集合.txt 對賬單 4 cd D:\批量處理對賬單\對賬單 5 call CopyName.bat 6 java -jar D:\批量處理對賬單\Auto.jar
綜上,業務人員只需把對賬單統一放入到“對賬單”目錄下:
點選Start.bat啟動,就可得到以下指定資料的統一獲取:
接下來,就具體分享一下Java部分的邏輯實現:
程式碼結構
以maven進行jar依賴,主要有Datas、ExportExcelBase、ExportExcleClient、PutExcel四個類。
1.引入依賴
1 <dependencies> 2 <dependency> 3 <groupId>org.apache.poi</groupId> 4 <artifactId>poi</artifactId> 5 <version>3.10-FINAL</version> 6 </dependency> 7 <dependency> 8 <groupId>org.projectlombok</groupId> 9 <artifactId>lombok</artifactId> 10 <version>1.18.2</version> 11 </dependency> 12 </dependencies>
2.設定匯出基本類,根據需生成的Excel展示資料設定,筆者案例裡只需展示“組合名”,“保證金佔用金額”,“可用資金額”三個欄位,故只需設定name,margin,avaFunds來接受獲取到的值;
1 package com.put.data; 2 import lombok.Data; 3 4 /** 5 * 匯出資料類 6 * @author zhujiqian 7 * @date 2020/10/27 20:09 8 */ 9 @Data 10 public class Datas { 11 //名字 12 private String name; 13 //保證金 14 private String margin; 15 //可用資金 16 private String avaFunds; 17 18 public Datas(String name, String margin, String avaFunds) { 19 this.name = name; 20 this.margin = margin; 21 this.avaFunds = avaFunds; 22 } 23 24 }
3.設定Excel表格生成類
1 package com.put.put; 2 3 import org.apache.poi.hssf.usermodel.*; 4 import org.apache.poi.hssf.util.Region; 5 6 import java.io.File; 7 import java.io.FileNotFoundException; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 11 /** 12 * HSSF - 提供讀寫Microsoft Excel格式檔案的功能。 13 * 14 * XSSF - 提供讀寫Microsoft Excel OOXML格式檔案的功能。 15 * 16 * @author zhujiqian 17 * @date 2020/10/27 20:33 18 */ 19 public class ExportExcelBase { 20 private HSSFWorkbook hwb=null; 21 private HSSFSheet sheet=null; 22 public ExportExcelBase(HSSFWorkbook hwb,HSSFSheet sheet){ 23 this.hwb=hwb; 24 this.sheet=sheet; 25 } 26 public HSSFWorkbook getHwb() { 27 return hwb; 28 } 29 public void setHwb(HSSFWorkbook hwb) { 30 this.hwb = hwb; 31 } 32 public HSSFSheet getSheet() { 33 return sheet; 34 } 35 public void setSheet(HSSFSheet sheet) { 36 this.sheet = sheet; 37 } 38 39 /** 40 * 建立設定表格頭 41 */ 42 public void createNormalHead(String headString,int colSum){ 43 //建立表格標題行,第一行 44 HSSFRow row=this.sheet.createRow(0); 45 //建立指定行的列,第一列 46 HSSFCell cell=row.createCell(0); 47 //設定標題行預設行高 48 row.setHeight((short) 500); 49 //設定表格內容型別:0-數值型;1-字串;2-公式型;3-空值;4-布林型;5-錯誤 50 cell.setCellType(1); 51 //設定表格標題內容 52 cell.setCellValue(new HSSFRichTextString(headString)); 53 // 指定合併區域 54 this.sheet.addMergedRegion(new Region(0, (short)0, 0, (short)colSum)); 55 // 定義單元格格式,新增單元格表樣式,並新增到工作簿 56 HSSFCellStyle cellStyle=this.hwb.createCellStyle(); 57 // 設定單元格水平對齊居中型別 58 cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); 59 // 指定單元格垂直居中對齊 60 cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); 61 // 指定單元格自動換行 62 cellStyle.setWrapText(true); 63 //設定字型 64 HSSFFont font=this.hwb.createFont(); 65 font.setBoldweight((short) 700); 66 font.setFontName("宋體"); 67 font.setFontHeight((short) 300); 68 cellStyle.setFont(font); 69 cell.setCellStyle(cellStyle); 70 } 71 72 /** 73 *表單第二行 74 * @param params 75 * @param colSum 76 */ 77 public void createNormalTwoRow(String[] params,int colSum){ 78 HSSFRow row1=this.sheet.createRow(1); 79 row1.setHeight((short) 300); 80 HSSFCell cell2=row1.createCell(0); 81 cell2.setCellType(1); 82 cell2.setCellValue(new HSSFRichTextString("統計時間"+params[0]+"至"+params[1])); 83 this.sheet.addMergedRegion(new Region(1, (short) 0,1,(short)colSum)); 84 HSSFCellStyle cellStyle=this.hwb.createCellStyle(); 85 cellStyle.setAlignment((short) 2); 86 cellStyle.setVerticalAlignment((short) 1); 87 cellStyle.setWrapText(true); 88 HSSFFont font=this.hwb.createFont(); 89 font.setBoldweight((short) 700); 90 font.setFontName("宋體"); 91 font.setFontHeight((short) 250); 92 cellStyle.setFont(font); 93 cell2.setCellStyle(cellStyle); 94 } 95 96 97 /** 98 * 表單內容 99 * @param wb 100 * @param row 101 * @param col 102 * @param align 103 * @param val 104 */ 105 public void cteateCell(HSSFWorkbook wb, HSSFRow row, int col, short align, String val) { 106 HSSFCell cell = row.createCell(col); 107 cell.setCellType(1); 108 cell.setCellValue(new HSSFRichTextString(val)); 109 HSSFCellStyle cellstyle = wb.createCellStyle(); 110 cellstyle.setAlignment(align); 111 cell.setCellStyle(cellstyle); 112 } 113 114 115 /** 116 * 文件輸出流 117 * @param fileName 118 */ 119 public void outputExcle(String fileName) { 120 FileOutputStream fos = null; 121 try { 122 fos = new FileOutputStream(new File(fileName)); 123 this.hwb.write(fos); 124 fos.close(); 125 } catch (FileNotFoundException var4) { 126 var4.printStackTrace(); 127 } catch (IOException var5) { 128 var5.printStackTrace(); 129 } 130 } 131 }
4.設定Excel根據資料匯出類
1 package com.put.put; 2 3 4 import com.put.data.Datas; 5 import org.apache.poi.hssf.usermodel.*; 6 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 import java.util.List; 10 11 /** 12 * TODO 13 * 14 * @author zhujiqian 15 * @date 2020/10/27 20:24 16 */ 17 public class ExportExcleClient { 18 private HSSFWorkbook hwb=null; 19 private HSSFSheet sheet=null; 20 21 ExportExcelBase exportExcel = null; 22 SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日"); 23 24 public ExportExcleClient() { 25 this.hwb = new HSSFWorkbook(); 26 this.exportExcel = new ExportExcelBase(this.hwb, this.sheet); 27 } 28 29 /** 30 * 匯出Excel 31 * @return 32 */ 33 public String exportExcel() { 34 String a = this.df.format(new Date()) + "對賬單集合.xls"; 35 String b = "D:\\批量處理對賬單\\對賬單集處理結果\\" + a; 36 this.exportExcel.outputExcle(b); 37 return b; 38 } 39 40 /** 41 * 設定匯出格式 42 * @param data 43 * @return 44 */ 45 public String alldata(List<Datas> data) { 46 if (data.size() != 0) { 47 this.sheet = this.exportExcel.getHwb().createSheet("對賬單集合"); 48 this.exportExcel.setSheet(this.sheet); 49 int number = 2; 50 51 for(int i = 0; i < number; ++i) { 52 this.sheet.setColumnWidth(i, 8000); 53 } 54 55 HSSFCellStyle cellStyle = this.hwb.createCellStyle(); 56 cellStyle.setAlignment((short)2); 57 cellStyle.setVerticalAlignment((short)1); 58 cellStyle.setWrapText(true); 59 HSSFFont font = this.hwb.createFont(); 60 font.setBoldweight((short)700); 61 font.setFontName("宋體"); 62 font.setFontHeight((short)200); 63 cellStyle.setFont(font); 64 this.exportExcel.createNormalHead("對賬單整合表", number); 65 String[] params = new String[]{this.df.format(new Date()), this.df.format(new Date())}; 66 this.exportExcel.createNormalTwoRow(params, number); 67 HSSFRow row2 = this.sheet.createRow(2); 68 HSSFCell cell0 = row2.createCell(0); 69 cell0.setCellStyle(cellStyle); 70 cell0.setCellValue(new HSSFRichTextString("組合名")); 71 HSSFCell cell1 = row2.createCell(1); 72 cell1.setCellStyle(cellStyle); 73 cell1.setCellValue(new HSSFRichTextString("保證金佔用金額")); 74 HSSFCell cell2 = row2.createCell(2); 75 cell2.setCellStyle(cellStyle); 76 cell2.setCellValue(new HSSFRichTextString("可用資金額")); 77 78 for(int i = 0; i < data.size(); ++i) { 79 System.out.println("==============" + ((Datas)data.get(i)).getName() + " " + ((Datas)data.get(i)).getMargin() + " " + ((Datas)data.get(i)).getAvaFunds()); 80 HSSFRow row = this.sheet.createRow((short)i + 3); 81 this.exportExcel.cteateCell(this.hwb, row, 0, (short)6, ((Datas)data.get(i)).getName()); 82 this.exportExcel.cteateCell(this.hwb, row, 1, (short)6, ((Datas)data.get(i)).getMargin()); 83 this.exportExcel.cteateCell(this.hwb, row, 2, (short)6, ((Datas)data.get(i)).getAvaFunds()); 84 } 85 } 86 87 return ""; 88 } 89 }
5.批量讀取txt文字擷取指定資料類
1 package com.put; 2 3 import com.put.data.Datas; 4 import com.put.put.ExportExcleClient; 5 import java.io.*; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 /** 10 * TODO 11 * 12 * @author zhujiqian 13 * @date 2020/10/27 20:08 14 */ 15 public class PutExcel { 16 public PutExcel() { 17 } 18 public static List<String> readTxtFile1(String TxtName, String filePath) { 19 ArrayList list = new ArrayList(); 20 try { 21 System.out.println("該組合:" + TxtName); 22 File file = new File(filePath); 23 if (file.isFile() && file.exists()) { 24 InputStreamReader read = new InputStreamReader(new FileInputStream(file), "GBK"); 25 BufferedReader bufferedReader = new BufferedReader(read); 26 String lineTxt = null; 27 28 while(true) { 29 do { 30 if ((lineTxt = bufferedReader.readLine()) == null) { 31 read.close(); 32 return list; 33 } 34 } while(!lineTxt.contains("持倉保證金:") && !lineTxt.contains("保證金佔用:") && !lineTxt.contains("保證金佔用 Margin Occupied:") && !lineTxt.contains("保證金佔用 Margin Occupied:")); 35 String ZiJin; 36 int a; 37 String b; 38 int c; 39 String d; 40 int e; 41 int f; 42 String E; 43 if (lineTxt.contains("持倉保證金:")) { 44 ZiJin = lineTxt.replace(" ", ""); 45 a = ZiJin.indexOf("持"); 46 b = ZiJin.substring(a); 47 c = b.indexOf("."); 48 d = b.substring(0, c + 3); 49 e = d.indexOf(":"); 50 f = d.length(); 51 E = d.substring(e + 1, f); 52 list.add(E); 53 } else if (lineTxt.contains("保證金佔用:")) { 54 ZiJin = lineTxt.replace(" ", ""); 55 a = ZiJin.indexOf("保"); 56 b = ZiJin.substring(a); 57 c = b.indexOf("."); 58 d = b.substring(0, c + 3); 59 e = d.indexOf(":"); 60 f = d.length(); 61 E = d.substring(e + 1, f); 62 list.add(E); 63 } else if (lineTxt.contains("保證金佔用 Margin Occupied:")) { 64 ZiJin = lineTxt.replace(" ", ""); 65 a = ZiJin.indexOf("保"); 66 b = ZiJin.substring(a); 67 c = b.indexOf("."); 68 d = b.substring(0, c + 3); 69 e = d.indexOf(":"); 70 f = d.length(); 71 E = d.substring(e + 1, f); 72 list.add(E); 73 } else if (lineTxt.contains("保證金佔用 Margin Occupied:")) { 74 ZiJin = lineTxt.replace(" ", ""); 75 a = ZiJin.indexOf("保"); 76 b = ZiJin.substring(a); 77 c = b.indexOf("."); 78 d = b.substring(0, c + 3); 79 e = d.indexOf(":"); 80 f = d.length(); 81 E = d.substring(e + 1, f); 82 list.add(E); 83 } 84 } 85 } else { 86 System.out.println("找不到指定的檔案"); 87 } 88 } catch (Exception var16) { 89 System.out.println("讀取檔案內容出錯"); 90 var16.printStackTrace(); 91 } 92 return list; 93 } 94 public static List<String> readTxtFile2(String TxtName, String filePath) { 95 ArrayList list = new ArrayList(); 96 97 try { 98 99 System.out.println("該組合:" + TxtName); 100 File file = new File(filePath); 101 if (file.isFile() && file.exists()) { 102 InputStreamReader read = new InputStreamReader(new FileInputStream(file), "GBK"); 103 BufferedReader bufferedReader = new BufferedReader(read); 104 String lineTxt = null; 105 106 while(true) { 107 do { 108 if ((lineTxt = bufferedReader.readLine()) == null) { 109 read.close(); 110 return list; 111 } 112 } while(!lineTxt.contains("可用資金:") && !lineTxt.contains("可用資金 Fund Avail.:") && !lineTxt.contains("可用資金 Fund Avail.:")); 113 String ZiJin; 114 int a; 115 String b; 116 int c; 117 String d; 118 int e; 119 int f; 120 String E; 121 if (lineTxt.contains("可用資金:")) { 122 ZiJin = lineTxt.replace(" ", ""); 123 ZiJin = lineTxt.replace(" ", ""); 124 a = ZiJin.indexOf("可"); 125 b = ZiJin.substring(a); 126 c = b.indexOf("."); 127 d = b.substring(0, c + 3); 128 e = d.indexOf(":"); 129 f = d.length(); 130 E = d.substring(e + 1, f); 131 list.add(E); 132 } else if (lineTxt.contains("可用資金 Fund Avail.:")) { 133 ZiJin = lineTxt.replace(" ", ""); 134 ZiJin = lineTxt.replace(" ", ""); 135 a = ZiJin.indexOf("可"); 136 b = ZiJin.substring(a); 137 c = b.lastIndexOf("."); 138 d = b.substring(0, c + 3); 139 e = d.indexOf(":"); 140 f = d.length(); 141 E = d.substring(e + 1, f); 142 list.add(E); 143 } else if (lineTxt.contains("可用資金 Fund Avail.:")) { 144 lineTxt.replace(" ", ""); 145 ZiJin = lineTxt.replace(" ", ""); 146 a = ZiJin.indexOf("可"); 147 b = ZiJin.substring(a); 148 c = b.lastIndexOf("."); 149 d = b.substring(0, c + 3); 150 e = d.indexOf(":"); 151 f = d.length(); 152 E = d.substring(e + 1, f); 153 list.add(E); 154 } 155 } 156 } else { 157 System.out.println("找不到指定的檔案"); 158 } 159 } catch (Exception var16) { 160 System.out.println("讀取檔案內容出錯"); 161 var16.printStackTrace(); 162 } 163 164 return list; 165 } 166 167 public static void main(String[] argv) { 168 String path = "D:\\批量處理對賬單\\對賬單\\對賬單批量名字集合.txt"; 169 List<String> nums = writeToDat(path); 170 List<Datas> listData = new ArrayList(); 171 for(int i = 0; i < nums.size(); ++i) { 172 if (!(nums.get(i)).equals("對賬單批量名字集合.txt")) { 173 listData.add(ZuHe(nums.get(i))); 174 System.out.println("--------==========" + ZuHe(nums.get(i))); 175 } 176 } 177 178 System.out.println("-----------" + listData); 179 ExportExcleClient client = new ExportExcleClient(); 180 client.alldata(listData); 181 String url = client.exportExcel(); 182 System.out.println(url); 183 } 184 185 public static Datas ZuHe(String TxtName) { 186 String address = "D:\\批量處理對賬單\\對賬單\\" + TxtName; 187 List<String> r1 = readTxtFile1(TxtName, address); 188 List<String> r2 = readTxtFile2(TxtName, address); 189 int c = TxtName.indexOf("."); 190 String txt = TxtName.substring(0, c); 191 System.out.println(txt); 192 System.out.println(r1); 193 Datas d = null; 194 if (r1.isEmpty() && r2.isEmpty()) { 195 if (r1.isEmpty() && r2.isEmpty()) { 196 System.out.println(txt + "--" + r1 + "---" + r2); 197 d = new Datas(txt, "無", "無"); 198 } 199 } else { 200 d = new Datas(txt, r1.get(0), r2.get(0)); 201 } 202 return d; 203 } 204 public static List<String> writeToDat(String path) { 205 File file = new File(path); 206 ArrayList list = new ArrayList(); 207 try { 208 String encoding = "GBK"; 209 InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding); 210 BufferedReader bw = new BufferedReader(read); 211 String line = null; 212 213 while((line = bw.readLine()) != null) { 214 list.add(line); 215 } 216 bw.close(); 217 } catch (IOException var7) { 218 var7.printStackTrace(); 219 } 220 return list; 221 } 222 }
以上的程式碼,大部分都是在2018年左右寫成,現再閱讀,程式碼風格甚為稚嫩。我沒有做大的修改,原因是,想要留住這些程式碼最初的樣子,就像留住剛畢業那會的記憶一般。整體實現邏輯並不算複雜,但再簡單的東西,能解決問題,都是值得分享的東西。在此基礎上,還可繼續完善與擴充套件,給需要用到的業務人員帶來方便。
這是我開源的第一個小工具,以此為勵,在以後的日子裡,要更加深入地學習,並將所學與所得,多多分享。在我看來,輸入的東西,不一定是自己的,但輸出的,一定是自己的。
這,就是我喜歡輸出的原因之一。
最後,附上第一個github原始碼連結:https://github.com/z924931408/auto-put-tool