美文网首页程序员
使用Node.js 将txt文件转为Excel文件

使用Node.js 将txt文件转为Excel文件

作者: 吃土的小此方 | 来源:发表于2017-07-05 10:56 被阅读0次

    最近同事需要对一份报告进行整理,一共有80个报告约9000多行放在一个txt文件中。虽然每份报告的格式比较类似,但其中部分字段对应的数量依旧会有差别。所以真要靠人工来做,无疑会是一件费时费力的并且是很枯燥的工作。据说如果有了这个程序,可以减少60%的工作量!那么为了我以后的下午茶,自然应该去尝试一下不是么?

    不过既然是费时费力又枯燥的工作,自然就应该交给代码去解决。毕竟,我坚信任何的科学技术就是为了让人类偷懒而存在的。那么就先切入正题,先上GitHub的项目地址。欢迎批评指点。

    GitHub项目:report-maker

    项目分析

    既然准备要上代码了,作为一个狂热的前端爱好者,自然首选Node.js了。这一个项目主要的目的就是将txt文件中的内容按照一定的规则转化为固定格式的表格并导出为Excel。那么重点就可以分为下面两步了。

    1. Excel文件的生成
    2. txt内容的整理
    1. Excel文件的生成

    Excel文件自然是寻找可以依赖的模块了(毕竟我自己写不出来)。找了一圈,发现js-xlsx这一个模块。虽然看起来很复杂,但其实只要提供好表头和内容就可以,其余只是对于内容数据整理的固定模板。
    相关教程可以参考下面这篇,讲的比较详细所以这里就不多做赘述了。
    参考教程使用node-xlsx进行excel文件的读写

    2. txt内容的整理

    解决了Excel导出的问题(不然就得换Py了呢),文档内容的整理便是这个项目最重要的问题了。最终整理的表格样式以及需要抽出的项目内容已经和同事确认过了。那么接下来就是如何整理了一个有着80个长短不一报告的文件了。

    首先来看看文件的格式,整个文件的格式类似于下面这样。

      Policy Name:       policyName1
      ……省略中间内容……
      Policy Type:       Standard (0)
      ……省略中间内容……
      Client/HW/OS/Pri/CIT:  Client1
      Client/HW/OS/Pri/CIT:  Client2
      Client/HW/OS/Pri/CIT:  Client3
      Client/HW/OS/Pri/CIT:  Client4
      ……省略多个Client
      Include:           /dir1
      Include:           /dir2
      Include:           /dir3
      ……省略多个Include
      Schedule:              Schedule1
          Type:
          ……
      Schedule:              Schedule2
          Type:
          ……
      ……省略多个Schedule
    
      Policy Name:       policyName2
      ……省略中间内容……
      ……
    

    可以看出,每一个段落是以Policy Name为分界的。那么,利用fs.readFile将完整的文件读取进来,作为一个字符串使用split方法进行切割。具体代码如下:

    fs.readFile(filePath, 'UTF-8', function (err, data) {
      if (err) throw err;
      // 对文件读取的数据进行处理,首先用 policyName 进行切割
      var policyLists = data.split(config.splitRules.policyName);
      if (policyLists[0] === '\r\n') {
        policyLists.shift();
      };
    

    然后针对数组中每一个元素(一个段落)根据之前文件中所需要项目,使用正则表达式切提取出所需要的内容,然后将提取出的内容组成所需要的数据结构,具体代码如下。其中schedule项目中内容也并非在一行中,所以也同样使用上面的方法进行切割。而对于其他的项目,则通过正则表达式来进行内容的获取。

      policyLists.forEach(function (policy) {
        var policyData = policyFormatter(config.splitRules.policyName + policy);
        excelData.push(policyData);
      });
    
    /**
     * 对每一个policy进行整理 使其符合表格插入的形式
     * @param {*} policy 
     * {
     *  policyName: String
     *  client: []]
     *  policyType: String
     *  include: []
     *  schedule[]
     *  scheduleResidence: String
     * }
     * 
     */
    function policyFormatter(policy) {
    
      var policyNameMatcher = new RegExp(config.splitRules.policyName + "([\\s\\w\\d\\-]*)\\r\\n"),
        clientMatcher = new RegExp(config.splitRules.client + "([\\s\\w\\d\\?\\-\\.]*)\\r\\n", "g"),
        policyTypeMatcher = new RegExp(config.splitRules.policyType + "([\\s\\w\\d\\(\\)\\-]*)\\r\\n"),
        includeMatcher = new RegExp(config.splitRules.include + "([\\s/\\w\\.\\\\:_\\?=\\\"\\*]*)\\r\\n", "g");
    
      var scheduleLists = policy.split(config.splitRules.schedule).slice(1),
        scheduleFormatLists = [],
        scheduleResidenceMatcher = new RegExp(config.splitRules.scheduleResidence + "([\\s\\w\\d\\-\\(\\)]*)\\r\\n");
    
      scheduleLists.forEach(function (schedule) {
        var scheduleFormat = config.splitRules.schedule + schedule;
        scheduleFormatLists.push(scheduleFormat);
      });
    
      // console.log(scheduleFormatLists);
    
      var results = {
        policyName: policy.match(policyNameMatcher)[1].trim(),
        client: policy.match(clientMatcher) ? policy.match(clientMatcher).join('').trim() : '',
        policyType: policy.match(policyTypeMatcher)[1].trim(),
        include: policy.match(includeMatcher).join('').trim(),
        schedule: scheduleFormatLists.join('').trim(),
        scheduleResidence: scheduleLists[0].match(scheduleResidenceMatcher)[1].trim()
      };
    
      // console.dir(results);
      return results;
    }
    

    主要逻辑处理完以后,把收集到的内容传给excel处理模块,导出成文件就能解决问题了。
    不过似乎最终如果能导出为Word,似乎更好。看来还有新的改进空间还留着呢。

    相关文章

      网友评论

        本文标题:使用Node.js 将txt文件转为Excel文件

        本文链接:https://www.haomeiwen.com/subject/qgwxhxtx.html