原创/朱季谦

 

这款工具是笔者在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

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 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 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 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 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 nums = writeToDat(path);

170 List 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 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 return d;

203 }

204 public static List 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

查看原文