原创/朱季谦

这款工具是笔者在2018年初开发完成的,时隔两载,偶然想起这款小工具,于是,决定将其开源,若有人需要做类似Java批处理实现整理文档的工具,可参考该工具逻辑思路来实现。

该工具是运行在windos系统上的,基于bat脚本与jar包形式协同运行。当时开发该工具的背景是,需要每天定时处理大批量的对账单txt文本信息,将其统一整合到一张Excel文档上,供会计人员获取。在没有该工具之前,项目组上的会计人员,需要每天手动打开大量txt文本,并从每份txt文档里,复制所需信息,然后将获取到的信息再复制到一份当日的Excel文档里。这个过程根据对账单数量而定,若数量过多,手动整理就需花费大量时间,且过程重复操作。基于这个原因,当时就开发了这款小工具,供会计人员使用,其带来的效果是,节省了大量整理时间:会计人员只需把每天邮件收到的批量对账单txt文件,统一放到指定目录下,点击start启动脚本,就可一键自动批量处理完成。

这个工具在当时的工作环境下,是行之有效的,但若换到另一种领域或者环境,还需二次开发做修改。工具整体实现的逻辑并不复杂,笔者只提供一种解决文档重复整理工作的小思路,仅做参考学习之用,毕竟,解决问题的本质不在于工具,而在于思路。

下面,就围绕着业务与具体实现来结束该自动处理工具。

整体结构如下:

java 插入大批量语句性能优化 java批量处理_jar

1.对账单:将同类型对账单批量放入到对账单文件夹中,同类,即格式几乎一样,但数据不一样,如下所示:

java 插入大批量语句性能优化 java批量处理_java批处理工具_02

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 off2 copy /y CopyName.bat 对账单3 copy /y 对账单批量名字集合.txt 对账单4 cd D:\批量处理对账单\对账单5 call CopyName.bat6 java -jar D:\批量处理对账单\Auto.jar

综上,业务人员只需把对账单统一放入到“对账单”目录下:

java 插入大批量语句性能优化 java批量处理_jar_03

点击Start.bat启动,就可得到以下指定数据的统一获取:

java 插入大批量语句性能优化 java批量处理_java_04

接下来,就具体分享一下Java部分的逻辑实现:

代码结构

java 插入大批量语句性能优化 java批量处理_java_05

以maven进行jar依赖,主要有Datas、ExportExcelBase、ExportExcleClient、PutExcel四个类。

1.引入依赖
1 
2 
3 org.apache.poi
4 poi
5 3.10-FINAL
6 
7 
8 org.projectlombok
9 lombok
10 1.18.2
11 
12

2.设置导出基本类,根据需生成的Excel展示数据设置,笔者案例里只需展示“组合名”,“保证金占用金额”,“可用资金额”三个字段,故只需设置name,margin,avaFunds来接受获取到的值;

1 packagecom.put.data;2 importlombok.Data;3 4 /**
5 * 导出数据类6 *@authorzhujiqian7 * @date 2020/10/27 20:098 */
9 @Data10 public classDatas {11 //名字
12 privateString name;13 //保证金
14 privateString margin;15 //可用资金
16 privateString avaFunds;17
18 publicDatas(String name, String margin, String avaFunds) {19 this.name =name;20 this.margin =margin;21 this.avaFunds =avaFunds;22 }23 24 }

3.设置Excel表格生成类

1 packagecom.put.put;2 3 import org.apache.poi.hssf.usermodel.*;4 importorg.apache.poi.hssf.util.Region;5 6 importjava.io.File;7 importjava.io.FileNotFoundException;8 importjava.io.FileOutputStream;9 importjava.io.IOException;10 11 /**
12 * HSSF - 提供读写Microsoft Excel格式档案的功能。13 *14 * XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。15 *16 *@authorzhujiqian17 * @date 2020/10/27 20:3318 */
19 public classExportExcelBase {20 private HSSFWorkbook hwb=null;21 private HSSFSheet sheet=null;22 publicExportExcelBase(HSSFWorkbook hwb,HSSFSheet sheet){23 this.hwb=hwb;24 this.sheet=sheet;25 }26 publicHSSFWorkbook getHwb() {27 returnhwb;28 }29 public voidsetHwb(HSSFWorkbook hwb) {30 this.hwb =hwb;31 }32 publicHSSFSheet getSheet() {33 returnsheet;34 }35 public voidsetSheet(HSSFSheet sheet) {36 this.sheet =sheet;37 }38 39 /**
40 * 创建设置表格头41 */
42 public void createNormalHead(String headString,intcolSum){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(newHSSFRichTextString(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 *@paramparams75 *@paramcolSum76 */
77 public void createNormalTwoRow(String[] params,intcolSum){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 *@paramwb100 *@paramrow101 *@paramcol102 *@paramalign103 *@paramval104 */
105 public void cteateCell(HSSFWorkbook wb, HSSFRow row, int col, shortalign, String val) {106 HSSFCell cell =row.createCell(col);107 cell.setCellType(1);108 cell.setCellValue(newHSSFRichTextString(val));109 HSSFCellStyle cellstyle =wb.createCellStyle();110 cellstyle.setAlignment(align);111 cell.setCellStyle(cellstyle);112 }113 114 115 /**
116 * 文档输出流117 *@paramfileName118 */
119 public voidoutputExcle(String fileName) {120 FileOutputStream fos = null;121 try{122 fos = new FileOutputStream(newFile(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 packagecom.put.put;2 3 4 importcom.put.data.Datas;5 import org.apache.poi.hssf.usermodel.*;6 7 importjava.text.SimpleDateFormat;8 importjava.util.Date;9 importjava.util.List;10 11 /**
12 * TODO13 *14 *@authorzhujiqian15 * @date 2020/10/27 20:2416 */
17 public classExportExcleClient {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 publicExportExcleClient() {25 this.hwb = newHSSFWorkbook();26 this.exportExcel = new ExportExcelBase(this.hwb, this.sheet);27 }28 29 /**
30 * 导出Excel31 *@return
32 */
33 publicString exportExcel() {34 String a = this.df.format(new Date()) + "对账单集合.xls";35 String b = "D:\\批量处理对账单\\对账单集处理结果\\" +a;36 this.exportExcel.outputExcle(b);37 returnb;38 }39 40 /**
41 * 设置导出格式42 *@paramdata43 *@return
44 */
45 public String alldata(Listdata) {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(newDate())};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 packagecom.put;2 3 importcom.put.data.Datas;4 importcom.put.put.ExportExcleClient;5 import java.io.*;6 importjava.util.ArrayList;7 importjava.util.List;8 9 /**
10 * TODO11 *12 *@authorzhujiqian13 * @date 2020/10/27 20:0814 */
15 public classPutExcel {16 publicPutExcel() {17 }18 public static ListreadTxtFile1(String TxtName, String filePath) {19 ArrayList list = newArrayList();20 try{21 System.out.println("该组合:" +TxtName);22 File file = newFile(filePath);23 if (file.isFile() &&file.exists()) {24 InputStreamReader read = new InputStreamReader(new FileInputStream(file), "GBK");25 BufferedReader bufferedReader = newBufferedReader(read);26 String lineTxt = null;27 28 while(true) {29 do{30 if ((lineTxt = bufferedReader.readLine()) == null) {31 read.close();32 returnlist;33 }34 } while(!lineTxt.contains("持仓保证金:") && !lineTxt.contains("保证金占用:") && !lineTxt.contains("保证金占用 Margin Occupied:") && !lineTxt.contains("保证金占用 Margin Occupied:"));35 String ZiJin;36 inta;37 String b;38 intc;39 String d;40 inte;41 intf;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 returnlist;93 }94 public static ListreadTxtFile2(String TxtName, String filePath) {95 ArrayList list = newArrayList();96 97 try{98 99 System.out.println("该组合:" +TxtName);100 File file = newFile(filePath);101 if (file.isFile() &&file.exists()) {102 InputStreamReader read = new InputStreamReader(new FileInputStream(file), "GBK");103 BufferedReader bufferedReader = newBufferedReader(read);104 String lineTxt = null;105 106 while(true) {107 do{108 if ((lineTxt = bufferedReader.readLine()) == null) {109 read.close();110 returnlist;111 }112 } while(!lineTxt.contains("可用资金:") && !lineTxt.contains("可用资金 Fund Avail.:") && !lineTxt.contains("可用资金 Fund Avail.:"));113 String ZiJin;114 inta;115 String b;116 intc;117 String d;118 inte;119 intf;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 returnlist;165 }166 167 public static voidmain(String[] argv) {168 String path = "D:\\批量处理对账单\\对账单\\对账单批量名字集合.txt";169 List nums =writeToDat(path);170 List listData = newArrayList();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 = newExportExcleClient();180 client.alldata(listData);181 String url =client.exportExcel();182 System.out.println(url);183 }184 185 public staticDatas ZuHe(String TxtName) {186 String address = "D:\\批量处理对账单\\对账单\\" +TxtName;187 List r1 =readTxtFile1(TxtName, address);188 List 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 returnd;203 }204 public static ListwriteToDat(String path) {205 File file = newFile(path);206 ArrayList list = newArrayList();207 try{208 String encoding = "GBK";209 InputStreamReader read = new InputStreamReader(newFileInputStream(file), encoding);210 BufferedReader bw = newBufferedReader(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 returnlist;221 }222 }

以上的代码,大部分都是在2018年左右写成,现再阅读,代码风格甚为稚嫩。我没有做大的修改,原因是,想要留住这些代码最初的样子,就像留住刚毕业那会的记忆一般。整体实现逻辑并不算复杂,但再简单的东西,能解决问题,都是值得分享的东西。在此基础上,还可继续完善与扩展,给需要用到的业务人员带来方便。

这是我开源的第一个小工具,以此为励,在以后的日子里,要更加深入地学习,并将所学与所得,多多分享。在我看来,输入的东西,不一定是自己的,但输出的,一定是自己的。

这,就是我喜欢输出的原因之一。

最后,附上第一个github源码链接:https://github.com/z924931408/auto-put-tool