js解析csv文件數(shù)據(jù)锰镀,轉(zhuǎn)換成數(shù)組

js導(dǎo)入csv文件娘侍,讀取文本
這里的關(guān)鍵就是 FileReader,是H5標準里的讀取文件的一個標準實現(xiàn)方式泳炉,IE10及以上版本以及chrome/firefox/safari等支持憾筏。調(diào)用方式方法也比較簡單,只需要傳入文件輸入框的DOM花鹅,設(shè)定讀取方式然后綁定回調(diào)函數(shù)就行了氧腰。這里使用的是 readAsText() 的方式,讀取為文本格式。
注意:readAsText()會自動把utf8文件的BOM頭(如果有的話)去除容贝,其它讀取方式要注意手動去除自脯。

var inputFile = document.querySelector("input[type='file']");
inputFile.onchange = (event) => {
  var file = inputFile.files[0];
  if( typeof(FileReader) !== 'undefined' ){    //H5
    var reader = new FileReader();
    reader.readAsText(file);            //以文本格式讀取
    reader.onload = function(evt){
      var data = evt.target.result;        //讀到的數(shù)據(jù)
      console.log(data);
    }
  }else{
      alert("IE9及以下瀏覽器不支持,請使用Chrome或Firefox瀏覽器");
  }
}

最簡單的方式導(dǎo)入csv文件斤富,中文解析會亂碼

JS導(dǎo)入CSV--文本解析插件PapaParse.js

var inputFile = document.querySelector("input[type='file']");
inputFile.onchange = (event) => {
  var file = inputFile.files[0];
  Papa.parse(file, {
      complete: function(results) {
            console.log("Finished:", results.data);
        }
  });
}

這個插件比較強大膏潮,解析上基本沒有什么大問題,但仍然不是十分完善满力。問題如下:

  1. 文件最末尾的空行沒有自動去除焕参,可能會導(dǎo)致表單填多一點空數(shù)據(jù);
  2. 不能自動識別UTF8與GBK油额,中文解析可能亂碼叠纷;
  3. UTF8編碼下, \r\n與\n混用時有可能會解析出問題潦嘶,這個是PapaParse解析的算法問題涩嚣,還請高手去其官方github提供修復(fù)。

(如果我們能識別編碼掂僵,這就好解決了)
JS導(dǎo)入CSV--編碼自動識別jschardet.js
查看FileReader文檔航厚,除了readAsText()讀取為字符串以外,還有readAsBinaryString()(并不是標準的H5讀取方法锰蓬,有些瀏覽器可能不支持)幔睬、readAsDataURL()
使用readAsDataURL()打印結(jié)果:

data:text/csv;base64,NiywzczYwPvM2KGksLIKMyzN0LDdtvLLuaGkx+0KOCy2xc3+oaS3xrDCxMkK

改文件再試多幾次,原來是這樣子的:前面的 data:text/csv;base64, 是固定字符串芹扭,僅對火狐麻顶,chrome和IE前面的是 data:;base64, ,后面的那一串是文件內(nèi)容經(jīng)過base64編碼而成舱卡。那么把后面這個一串解碼出來看看辅肾,IE>=10、火狐灼狰、chrome有原生的base64解碼函數(shù) atob()宛瞄。然后就得到了一個英文正常,中文全是亂碼的字符串了交胚,而且這個字符串的亂碼看起來不像UTF8也不像GBK份汗。那么很可能這就是十六進制碼了吧,用jschardet檢測一下蝴簇,成功了杯活!


image.png

總結(jié)整理
到這里,我們已經(jīng)用第三方的JS解決了最大的兩個難題熬词,編碼識別和CSV解析旁钧。那么就把這些整合一下吸重,封裝成一個更方便調(diào)用的方法吧

var inputFile = document.querySelector("input[type='file']");
inputFile.onchange = (event) => {
        // console.log(event);
        var file = inputFile.files[0];
        csv2arr(function(res){
          console.log(res)
        }, file);
}
function csv2arr(callback, file) {
      var fReader = new FileReader();
      fReader.readAsDataURL(file);

      // 顯示進度
      var progress = document.querySelector("progress");
      progress.max = file.size;
      progress.value = 0;
      fReader.onprogress = (event) => {
        progress.value = event.loaded;
      }

      fReader.onload = function (evt) {
        var data = evt.target.result;

        //        console.log( data );

        var encoding = checkEncoding(data);

        //        console.log(encoding);

        //轉(zhuǎn)換成二維數(shù)組,需要引入Papaparse.js

        Papa.parse(file, {
          encoding: encoding,
          complete: function (results) { // UTF8 \r\n與\n混用時有可能會出問題
            var res = results.data;
            if (res[res.length - 1] == "") { //去除最后的空行
              res.pop();
            }
            callback && callback(res);
          }

        });
      }
      fReader.onerror = function (evt) {
        //        console.log(evt);
        alert("文件已修改歪今,請重新選擇(Firefox)\nThe file has changed,please select again.(Firefox)");
      }

      //檢查編碼嚎幸,引用了 jschardet
      function checkEncoding(base64Str) {
        //這種方式得到的是一種二進制串
        var str = atob(base64Str.split(";base64,")[1]);
        //        console.log(str);
        //要用二進制格式
        var encoding = jschardet.detect(str);
        encoding = encoding.encoding;
        console.log( encoding );
        if (encoding == "windows-1252") { //有時會識別錯誤(如UTF8的中文二字)
          encoding = "ANSI";
        }
        return encoding;
      }
    }

借鑒原文

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市寄猩,隨后出現(xiàn)的幾起案子嫉晶,更是在濱河造成了極大的恐慌,老刑警劉巖田篇,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件替废,死亡現(xiàn)場離奇詭異,居然都是意外死亡泊柬,警方通過查閱死者的電腦和手機椎镣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兽赁,“玉大人状答,你說我怎么就攤上這事〉堆拢” “怎么了剪况?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蒲跨。 經(jīng)常有香客問我,道長授翻,這世上最難降的妖魔是什么或悲? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮堪唐,結(jié)果婚禮上巡语,老公的妹妹穿的比我還像新娘。我一直安慰自己淮菠,他們只是感情好男公,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著合陵,像睡著了一般枢赔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拥知,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天踏拜,我揣著相機與錄音,去河邊找鬼低剔。 笑死速梗,一個胖子當著我的面吹牛肮塞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姻锁,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼枕赵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了位隶?” 一聲冷哼從身側(cè)響起拷窜,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钓试,沒想到半個月后装黑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡弓熏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年恋谭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挽鞠。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡疚颊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出信认,到底是詐尸還是另有隱情材义,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布嫁赏,位于F島的核電站其掂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏潦蝇。R本人自食惡果不足惜款熬,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望攘乒。 院中可真熱鬧贤牛,春花似錦、人聲如沸则酝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沽讹。三九已至般卑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妥泉,已是汗流浹背椭微。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盲链,地道東北人蝇率。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓迟杂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親本慕。 傳聞我的和親對象是個殘疾皇子排拷,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容