原创/朱季谦
这款工具是笔者在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</ 4 artifactId>poi 5 version>3.10-FINAL 6 7 8 >org.projectlombok 9 >lombok10 >1.18.211 12 >
2.设置导出基本类,根据需生成的Excel展示数据设置,笔者案例里只需展示“组合名”,“保证金占用金额”,“可用资金额”三个字段,故只需设置name,margin,avaFunds来接受获取到的值;
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 String margin; 15 可用资金 16 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 com.put.put; 2 3 import org.apache.poi.hssf.usermodel.*; 4 org.apache.poi.hssf.util.Region; 5 6 java.io.File; 7 java.io.FileNotFoundException; 8 java.io.FileOutputStream; 9 java.io.IOException; 10 11 12 * HSSF - 提供读写Microsoft Excel格式档案的功能。 13 * 14 * XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。 15 16 17 * @date 2020/10/27 20:33 18 19 ExportExcelBase { 20 private HSSFWorkbook hwb=null 21 private HSSFSheet sheet= 22 ExportExcelBase(HSSFWorkbook hwb,HSSFSheet sheet){ 23 this.hwb=hwb; 24 this.sheet=sheet; 25 26 HSSFWorkbook getHwb() { 27 return hwb; 28 29 void setHwb(HSSFWorkbook hwb) { 30 this.hwb = 31 32 HSSFSheet getSheet() { 33 sheet; 34 35 setSheet(HSSFSheet sheet) { 36 this.sheet = 37 38 39 40 * 创建设置表格头 41 42 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,1)">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=.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 colSum 76 77 void createNormalTwoRow(String[] params,1)"> 78 HSSFRow row1=this.sheet.createRow(1 79 row1.setHeight(( 80 HSSFCell cell2=row1.createCell(0 81 cell2.setCellType(1 82 cell2.setCellValue(new HSSFRichTextString("统计时间"+params[0]+"至"+params[1])); 83 new Region(1,1)">short) 0,1,1)"> 84 HSSFCellStyle cellStyle= 85 cellStyle.setAlignment((short) 2 86 cellStyle.setVerticalAlignment((short) 1 87 cellStyle.setWrapText( 88 HSSFFont font= 89 font.setBoldweight(( 90 font.setFontName("宋体" 91 font.setFontHeight((short) 250 92 93 cell2.setCellStyle(cellStyle); 94 95 96 97 98 * 表单内容 99 wb 100 row 101 col 102 align 103 val 104 105 void cteateCell(HSSFWorkbook wb,HSSFRow row,1)">int col,1)"> align,String val) { 106 HSSFCell cell = row.createCell(col); 107 cell.setCellType(1108 cell.setCellValue( HSSFRichTextString(val)); 109 HSSFCellStyle cellstyle = wb.createCellStyle(); 110 cellstyle.setAlignment(align); 111 cell.setCellStyle(cellstyle); 112 113 114 115 116 * 文档输出流 117 fileName 118 119 outputExcle(String fileName) { 120 FileOutputStream fos = 121 try { 122 fos = new FileOutputStream( File(fileName)); 123 .hwb.write(fos); 124 fos.close(); 125 } catch (FileNotFoundException var4) { 126 var4.printStackTrace(); 127 } (IOException var5) { 128 var5.printStackTrace(); 129 } 130 131 }
4.设置Excel根据数据导出类
com.put.data.Datas; java.text.SimpleDateFormat; 8 java.util.Date; java.util.List; 11 * TODO 13 14 15 * @date 2020/10/27 20:24 16 17 ExportExcleClient { 19 20 21 ExportExcelBase exportExcel = 22 SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日"24 ExportExcleClient() { 25 this.hwb = HSSFWorkbook(); 26 this.exportExcel = new ExportExcelBase(this.hwb,1)">.sheet); 27 28 29 30 * 导出Excel 31 @return 32 33 String exportExcel() { 34 String a = this.df.format(new Date()) + "对账单集合.xls"35 String b = "D:\\批量处理对账单\\对账单集处理结果\\" + a; 36 .exportExcel.outputExcle(b); 37 b; 38 39 40 41 * 设置导出格式 42 data 43 44 45 public String alldata(List<Datas> data) { 46 if (data.size() != 0) { 47 this.sheet = this.exportExcel.getHwb().createSheet("对账单集合"48 this.exportExcel.setSheet(49 int number = 250 51 for(int i = 0; i < number; ++i) { 52 this.sheet.setColumnWidth(i,800053 } 54 55 HSSFCellStyle cellStyle = 56 cellStyle.setAlignment((short)257 cellStyle.setVerticalAlignment((short)158 cellStyle.setWrapText(59 HSSFFont font = 60 font.setBoldweight((short)70061 font.setFontName("宋体"62 font.setFontHeight((short)20063 cellStyle.setFont(font); 64 this.exportExcel.createNormalHead("对账单整合表",number); 65 String[] params = new String[]{new Date()),1)"> Date())}; 66 .exportExcel.createNormalTwoRow(params,1)">67 HSSFRow row2 = this.sheet.createRow(268 HSSFCell cell0 = row2.createCell(069 cell0.setCellStyle(cellStyle); 70 cell0.setCellValue(new HSSFRichTextString("组合名")); 71 HSSFCell cell1 = row2.createCell(172 cell1.setCellStyle(cellStyle); 73 cell1.setCellValue(new HSSFRichTextString("保证金占用金额"74 HSSFCell cell2 = row2.createCell(275 cell2.setCellStyle(cellStyle); 76 cell2.setCellValue(new HSSFRichTextString("可用资金额"77 78 int i = 0; i < data.size(); ++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 + 381 this.exportExcel.cteateCell(short)682 83 84 85 86 87 return ""88 89 }
5.批量读取txt文本截取指定数据类
com.put; com.put.put.ExportExcleClient; import java.io.* java.util.ArrayList; * @date 2020/10/27 20:08 14 PutExcel { 16 PutExcel() { 18 static List<String> readTxtFile1(String TxtName,String filePath) { 19 ArrayList list = ArrayList(); 20 21 System.out.println("该组合:" + TxtName); 22 File file = File(filePath); 23 if (file.isFile() && file.exists()) { 24 InputStreamReader read = new InputStreamReader(new FileInputStream(file),"GBK" 25 BufferedReader bufferedReader = BufferedReader(read); 26 String lineTxt = 27 28 while( 29 do 30 if ((lineTxt = bufferedReader.readLine()) == read.close(); 32 list; 33 } 34 } while(!lineTxt.contains("持仓保证金:") && !lineTxt.contains("保证金占用:") && !lineTxt.contains("保证金占用 Margin Occupied:") && !lineTxt.contains("保证金占用 Margin Occupied:" 35 String ZiJin; 36 String b; 38 c; 39 String d; 40 e; 41 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 52 list.add(E); 53 } else if (lineTxt.contains("保证金占用:" 54 ZiJin = lineTxt.replace(" ",1)"> 55 a = ZiJin.indexOf("保" 56 b = 57 c = b.indexOf("." 58 d = b.substring(0,1)"> 59 e = d.indexOf(":" 60 f = 61 E = d.substring(e + 1 62 63 } if (lineTxt.contains("保证金占用 Margin Occupied:" 64 ZiJin = lineTxt.replace(" ",1)"> 65 a = ZiJin.indexOf("保" 66 b = 67 c = b.indexOf("." 68 d = b.substring(0,1)"> 69 e = d.indexOf(":" 70 f = 71 E = d.substring(e + 1 72 73 } if (lineTxt.contains("保证金占用 Margin Occupied:" 74 ZiJin = lineTxt.replace(" ",1)"> 75 a = ZiJin.indexOf("保" 76 b = 77 c = b.indexOf("." 78 d = b.substring(0,1)"> 79 e = d.indexOf(":" 80 f = 81 E = d.substring(e + 1 82 83 } 84 } 85 } else 86 System.out.println("找不到指定的文件" 87 88 } (Exception var16) { 89 System.out.println("读取文件内容出错" 90 var16.printStackTrace(); 91 92 94 readTxtFile2(String TxtName,1)"> 95 ArrayList list = 97 99 System.out.println("该组合:" +100 File file = 101 102 InputStreamReader read = 103 BufferedReader bufferedReader = 104 String lineTxt = 105 106 107 108 109 110 112 } while(!lineTxt.contains("可用资金:") && !lineTxt.contains("可用资金 Fund Avail.:") && !lineTxt.contains("可用资金 Fund Avail.:"114 115 116 118 119 120 121 if (lineTxt.contains("可用资金:"122 ZiJin = lineTxt.replace(" ",1)">123 ZiJin = lineTxt.replace(" ",1)">124 a = ZiJin.indexOf("可"125 b =126 c = b.indexOf("."127 d = b.substring(0,1)">128 e = d.indexOf(":"129 f =130 E = d.substring(e + 1131 132 } if (lineTxt.contains("可用资金 Fund Avail.:"133 ZiJin = lineTxt.replace(" ",1)">134 ZiJin = lineTxt.replace(" ",1)">135 a = ZiJin.indexOf("可"136 b =137 c = b.lastIndexOf("."138 d = b.substring(0,1)">139 e = d.indexOf(":"140 f =141 E = d.substring(e + 1142 143 } if (lineTxt.contains("可用资金 Fund Avail.:"144 lineTxt.replace(" ",1)">145 ZiJin = lineTxt.replace(" ",1)">146 a = ZiJin.indexOf("可"147 b =148 c = b.lastIndexOf("."149 d = b.substring(0,1)">150 e = d.indexOf(":"151 f =152 E = d.substring(e + 1153 154 155 156 } 157 System.out.println("找不到指定的文件"158 159 } 160 System.out.println("读取文件内容出错"161 162 163 164 165 166 167 static main(String[] argv) { 168 String path = "D:\\批量处理对账单\\对账单\\对账单批量名字集合.txt"169 List<String> nums = writeToDat(path); 170 List<Datas> listData = 171 int i = 0; i < nums.size(); ++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 = ExportExcleClient(); 180 client.alldata(listData); 181 String url = client.exportExcel(); 182 System.out.println(url); 183 184 185 static Datas ZuHe(String TxtName) { 186 String address = "D:\\批量处理对账单\\对账单\\" + TxtName; 187 List<String> r1 = readTxtFile1(TxtName,address); 188 List<String> r2 = readTxtFile2(TxtName,1)">189 int c = TxtName.indexOf("."190 String txt = TxtName.substring(0191 System.out.println(txt); 192 System.out.println(r1); 193 Datas d = 194 if (r1.isEmpty() && r2.isEmpty()) { 195 196 System.out.println(txt + "--" + r1 + "---" + r2); 197 d = new Datas(txt,"无","无"198 199 } 200 d = 201 202 d; 203 204 writeToDat(String path) { 205 File file = File(path); 206 ArrayList list = 207 208 String encoding = "GBK"209 InputStreamReader read = FileInputStream(file),encoding); 210 BufferedReader bw = 211 String line = 212 213 while((line = bw.readLine()) != 214 list.add(line); 215 216 bw.close(); 217 } (IOException var7) { 218 var7.printStackTrace(); 219 220 221 222 }
以上的代码,大部分都是在2018年左右写成,现再阅读,代码风格甚为稚嫩。我没有做大的修改,原因是,想要留住这些代码最初的样子,就像留住刚毕业那会的记忆一般。整体实现逻辑并不算复杂,但再简单的东西,能解决问题,都是值得分享的东西。在此基础上,还可继续完善与扩展,给需要用到的业务人员带来方便。
这是我开源的第一个小工具,以此为励,在以后的日子里,要更加深入地学习,并将所学与所得,多多分享。在我看来,输入的东西,不一定是自己的,但输出的,一定是自己的。
这,就是我喜欢输出的原因之一。
最后,附上第一个github源码链接:https://github.com/z924931408/auto-put-tool