读取文本文件内容并写到excel

最近工作中有项工作做的劳神不说,更少眼睛累…于是写了下面的工具帮忙干活.

工作内容,查看日志,将执行存在异常的组件找出来,说明白点就是看组件开始时间,结束时间,比对看哪个组件执行费时…,从而改进程序

之前是日志在服务器上,使用vi看

日志文件xxx.log

2018-09-07 16:58:01.343 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ 不定长通讯组件
2018-09-07 16:58:01.344 DEBUG  TEST_C-00000174 [AbstractComm        ] 通讯组件 @ 使用接入适配器
2018-09-07 16:58:01.345 INFO   TEST_C-00000174 [AbstractComm        ] 通讯组件 @ 接收数据[4408],报文数据不记录
2018-09-07 16:58:01.346 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ 不定长通讯组件
2018-09-07 16:58:01.346 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ 拆包组件
2018-09-07 16:58:01.346 DEBUG  TEST_C-00000174 [MessageUnpack       ] 报文拆包组件 @ 使用报文'test/message/req.rcd',拆包变量名'recv'
...
...
2018-09-07 16:58:01.347 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ 拆包组件
2018-09-07 16:58:01.347 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ groovy脚本组件
...
...
2018-09-07 16:58:01.348 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ groovy脚本组件
2018-09-07 16:58:01.348 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ 拼包组件
2018-09-07 16:58:01.349 DEBUG  TEST_C-00000174 [MessagePack         ] 报文拼包组件 @ 使用报文'test/message/res_dc.rcd',拼包变量名'send'
...
...
2018-09-07 16:58:01.354 DEBUG  TEST_C-00000174 [MessagePack         ] 报文拼包组件 @ 拼包后报文为[4408]:
2018-09-07 16:58:01.356 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ 拼包组件
2018-09-07 16:58:01.356 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ 服务网关SDK发送组件

组件执行是严格按照流程,一个执行完才能进入下一个…
但是日志是异步输出的,导致日志输出的顺序与组件执行的顺序没有必然关系,就是会出现后面执行的组件日志中出现在文件的靠前的位置,添加了工作的难度…

预处理–>src.txt

使用shell命令将满足条件的日志行输出到指定文件中,src.txt,作为解析的源文件
grep 组件 ../TEST_C.log | grep TEST_C-00000174 > src.txt
这句意思是,从TEST_C.log日志中搜索 包含TEST_C-00000174的行中含有组件两个字的行内容输出到src.txt中.>代表输出

2018-09-07 16:58:01.343 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ 不定长通讯组件
2018-09-07 16:58:01.344 DEBUG  TEST_C-00000174 [AbstractComm        ] 通讯组件 @ 使用接入适配器
2018-09-07 16:58:01.345 INFO   TEST_C-00000174 [AbstractComm        ] 通讯组件 @ 接收数据[24],报文数据不记录
2018-09-07 16:58:01.346 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ 不定长通讯组件
2018-09-07 16:58:01.346 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ 拆包组件
2018-09-07 16:58:01.346 DEBUG  TEST_C-00000174 [MessageUnpack       ] 报文拆包组件 @ 使用报文'test/message/req.rcd',拆包变量名'recv'
2018-09-07 16:58:01.347 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ 拆包组件
2018-09-07 16:58:01.347 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件开始 @ groovy脚本组件
2018-09-07 16:58:01.348 DEBUG  TEST_C-00000174 [AbstractComponent   ] 组件结束 @ groovy脚本组件
...

使用工具将其拉到本地,或者之后的操作也在服务器上就行了,将dos脚本,编写成shell脚本即可,上面的shell脚本作为参考

处理目标–>dest.xlsx

时间 分秒的毫秒数 时差 日志级别 流水 组件名称 内容
2018-09-07 16:58:01.343 1343 1343 DEBUG TEST_C-00000174 组件开始 不定长通讯组件
2018-09-07 16:58:01.343 1343 0 DEBUG TEST_C-00000174 组件开始 不定长通讯组件
2018-09-07 16:58:01.344 1344 1 DEBUG TEST_C-00000174 通讯组件 使用接入适配器
2018-09-07 16:58:01.345 1345 1 INFO TEST_C-00000174 通讯组件 接收数据[4408],报文数据不记录
2018-09-07 16:58:01.346 1346 1 DEBUG TEST_C-00000174 组件开始 拆包组件
2018-09-07 16:58:01.346 1346 0 DEBUG TEST_C-00000174 组件结束 不定长通讯组件

使用到的jar包

dom4j-1.6.1.jar
poi-3.9.jar
poi-ooxml-3.9.jar
poi-ooxml-schemas-3.9.jar
xmlbeans-2.3.0.jar

代码

注:从当前目录的src.txt读取文件内容,处理后放入到当前目录的dest.xlsx文件中
源文件与目标文件路径可以在配置文件txt2excel.properties中修改.
这里只是用POI操作.xlsx的,

package com.yangxuan.excel;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class TXT2Excel {
    private static String srcPath;
    private static String destPath;
    static{
        Properties prop = new Properties();
        try {
            //读取配置文件.properties中的信息
            prop.load(new FileInputStream(new File("txt2excel.properties")));
            srcPath = prop.getProperty("srcPath");  
            destPath = prop.getProperty("destPath");    
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }

    public static void write(String destPath,List<String> fileContent) throws IOException, ParseException{
        //ArrayList<String> row = new ArrayList<String>();
        XSSFWorkbook xssfwb = new XSSFWorkbook();
        XSSFSheet xssfSheet = xssfwb.createSheet("sheet111");
        XSSFRow xssfRow = null; 
        //读取文件内容
        long old = 0L;
        //处理文本数据
        String content = "";
        for (int i = 0; i < fileContent.size(); i++) {
            content = fileContent.get(i);
            String cell1 = content.substring(0, 23).trim();
            long cell2 = dateFormat(cell1);
            xssfRow = xssfSheet.createRow(i);
            xssfRow.createCell(0).setCellValue(cell1);
            xssfRow.createCell(1).setCellValue(cell2);
            xssfRow.createCell(2).setCellValue(cell2-old);
            old=cell2;
            xssfRow.createCell(3).setCellValue(content.substring(23, 30).trim());
            xssfRow.createCell(4).setCellValue(content.substring(30, 46).trim());
            String[] split2 = content.substring(70).split("@");
            if(split2.length==2){
                xssfRow.createCell(5).setCellValue(split2[0].trim());
                xssfRow.createCell(6).setCellValue(split2[1].trim());
            }else{
                xssfRow.createCell(5).setCellValue(content.substring(70).trim());
            }
        }
        FileOutputStream fos = new FileOutputStream(new File(destPath));
        xssfwb.write(fos);
    }
    /**
     * 将字符串数据转化为毫秒数
     * @return 分+秒+毫秒位的毫秒数
     * @throws ParseException 
     */
    public static long dateFormat(String dateString) throws ParseException{

        String sub = dateString.substring(0,16);
        Calendar c = Calendar.getInstance();
        //2018-09-07 16
        c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(sub));
        long timeInMillis1 = c.getTimeInMillis();
        //2018-09-07 16:58:01.343
        c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(dateString));
        long timeInMillis2 = c.getTimeInMillis();

        return timeInMillis2-timeInMillis1;
    }
    /**
     * 获取文件内容
     * @param srcPath
     * @return List<String>
     * @throws IOException
     */
    public static final List<String> getFileContent(String srcPath) throws IOException
    {
        List<String> fileContent = new ArrayList<String>();  
        try {
            File f = new File(srcPath);
            if (f.exists()) {
                FileReader fr = new FileReader(srcPath);
                BufferedReader br = new BufferedReader(fr); // 建立BufferedReader对象,并实例化为br
                String line = br.readLine(); // 从文件读取一行字符串
                // 判断读取到的字符串是否不为空

                while (line != null) {
                    if(line.length()>0){
                        fileContent.add(line);
                    }
                    line = br.readLine(); // 从文件中继续读取一行数据
                }
                //排序
                Collections.sort(fileContent);
                br.close(); // 关闭BufferedReader对象
                fr.close(); // 关闭文件
            }

        } catch (IOException e) {
            throw e;
        }
        return fileContent;
    }
    public static void main(String[] args) throws IOException, InvalidFormatException, ParseException {
        List<String> fileContent = getFileContent(srcPath);
        TXT2Excel.write(destPath,fileContent);
    }
}

配置文件txt2excel.properties

放在txt2excel.jar包同级目录中

#\u6E90\u6587\u4EF6
srcPath=src.txt
#\u76EE\u6807\u6587\u4EF6
destPath=dest.xlsx

前提,组件执行按照流程,一个结束流程后的另一个才会开始,日志记录了组件执行时间戳,只是由于日志的异步输出导致日志内容更流程所示内容有差异

这里对读取到的文件行内容进行排序处理

写入excel前做时差计算,方便查看

eclipse打jar包为可执行jar

  • file–>Export–>java–>Runnable JAR File–>Next

  • Launch configuration:TXT2Excel - txt2excel
    类名-工程名
    这里是下拉框选择的,前提TXT2Excel类中必须有main方法作为程序入口,

  • Export destination:H:\utils\txt2excel.jar
    这一步是指定打包到哪个目录下,并指定打包成的包名
  • Library handing:
    Extract required libraries into generated JAR:将依赖的jar解压出来变成class丢进你生成的jar里面;
    Package required libraries into generated JAR:将依赖的jar不解压,直接放进你生成的jar里面;
    Copy required libraries into a sub-folder next to the generated JAR:将依赖的jar放到你生成jar的同级目录下的”xxx_lib”文件夹里面。
    我选的是第三个.
  • 完成Finish

执行完H:\utils\目录下生成的文件

txt2excel_lib
        dom4j-1.6.1.jar
        poi-3.9.jar
        poi-ooxml-3.9.jar
        poi-ooxml-schemas-3.9.jar
        xmlbeans-2.3.0.jar
txt2excel.jar

将需要解析的文本文件src.txt放入到H:\utils\目录下,这里工具里面写死了,只会读取src.txt文件

  • win+r–>cmd:
  • java -jar txt2excel.jar

会生成目标文件dest.xlsx,查看日志方便多了,

DOS脚本

但是每次都使用dos命令操作,还是有点麻烦,这里就写一个DOS脚本文件.之后双击它就可以了
H:\utils\目录下新建txt2excel.bat,文本方式编辑,保存,内容如下:

@echo off
rem 这是注释
rem @echo off 第一行的意思是不显示后续命令行及当前命令行

rem title 名称    这个名称会显示在窗口的左上角,打开多个dos窗口时,这个就有用了
title txt2excel

rem echo 在dos窗口中输入一行内容
echo txt2excel Starting......

rem 执行我们要运行的命令
java -jar txt2excel.jar

echo txt2excel end......
rem pause 暂停,等待按键继续,这个方便我们在报错后查看报错信息,不写这个的话,dos窗口一闪即逝,没法看
pause

猜你喜欢

转载自blog.csdn.net/weixin_43059824/article/details/82531421