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

最近同事需要对一份报告进行整理,一共有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,似乎更好。看来还有新的改进空间还留着呢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,266评论 25 707
  • 文件格式(或文件类型)是指电脑为了存储信息而使用的对信息的特殊编码方式,是用于识别内部储存的资料。比如有的储...
    一只不靠谱的猿_阅读 3,614评论 0 10
  • 1.背景 最近工作中,常常遇到客户要求将系统内的数据导出到Excel文件中,供其进行核对或使用的需求。 用户要求的...
    两个人的麦埂阅读 1,046评论 0 2
  • 电话再甜美传真再安慰也不足以应付不能拥抱你的遥远 凌晨四点,突然醒来。窗外露出破晓前的微亮。一阵剧烈的孤单俶而从心...
    吕熹微阅读 587评论 10 9
  • 爱情就是一场催眠,你催眠了谁?谁又催眠了你? 01、 “你这完蛋孩子,谈个恋爱你都不会,上这么多年学都干嘛了?” ...
    临界冰阅读 1,864评论 20 56