开源一套原创文本处理工具:Java+Bat脚本实现自动批量处理对账单工具
原创/朱季谦
这款工具是笔者在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