使用papa解析大csv文件

时间:2016-06-29 12:46:51

标签: jquery csv papaparse

我正在尝试加载一个大约有100k行的文件,到目前为止浏览器已经崩溃(本地)。我在互联网上看到,看到Papa Parse似乎处理大文件。现在它减少到大约3-4分钟加载到textarea。一旦文件被加载,我就想做更多的jQuery来做计数和事情,所以这个过程需要一段时间。有没有办法让csv加载更快?我正确使用该程序吗?

<div id="tabs">
<ul>
  <li><a href="#tabs-4">Generate a Report</a></li>
</ul>
<div id="tabs-4">
  <h2>Generating a CSV report</h2>
  <h4>Input Data:</h4>      
  <input id="myFile" type="file" name="files" value="Load File" />
  <button onclick="loadFileAsText()">Load Selected File</button>
  <form action="./" method="post">
  <textarea id="input3" style="height:150px;"></textarea>

  <input id="run3" type="button" value="Run" />
  <input id="runSplit" type="button" value="Run Split" />
  <input id="downloadLink" type="button" value="Download" />
  </form>
</div>
</div>

$(function () {
    $("#tabs").tabs();
});

var data = $('#input3').val();

function handleFileSelect(evt) {
    var file = evt.target.files[0];

Papa.parse(file, {
    header: true,
    dynamicTyping: true,
    complete: function (results) {
        data = results;
    }
});
}

$(document).ready(function () {

    $('#myFile').change(function(handleFileSelect){

    });
});


function loadFileAsText() {
    var fileToLoad = document.getElementById("myFile").files[0];

    var fileReader = new FileReader();
    fileReader.onload = function (fileLoadedEvent) {
        var textFromFileLoaded = fileLoadedEvent.target.result;
        document.getElementById("input3").value = textFromFileLoaded;
    };
    fileReader.readAsText(fileToLoad, "UTF-8");
}

2 个答案:

答案 0 :(得分:6)

您可能正确使用它,只是程序需要一些时间来解析所有100k行!

这可能是Web Workers的一个很好的用例场景。

如果您之前从未使用过它们,this site会给出一个不错的破坏,但关键部分是:

  

Web Workers模仿多线程,允许在后台运行密集脚本,因此它们不会阻止其他脚本运行。非常适合在保持UI响应的同时执行处理器密集型功能。

Browser coverage也相当不错,IE10及以下是唯一不支持它的半现代浏览器。

Mozilla有一个很好的视频,shows how web workers也可以提高网页的帧速率。

我会尝试为您提供一个网络工作者的工作示例,但请注意,这不会加快脚本速度,只是让它以异步方式进行处理,以便您的网页保持响应速度

修改

注意:如果要在工作程序中解析CSV,您可能需要使用<!doctype html> <html> <head> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.2/papaparse.js"></script> </head> <body> <input id="myFile" type="file" name="files" value="Load File" /> <br> <button class="load-file">Load and Parse Selected CSV File</button> <div id="report"></div> <script> // initialize our parsed_csv to be used wherever we want var parsed_csv; var start_time, end_time; // document.ready $(function() { $('.load-file').on('click', function(e) { start_time = performance.now(); $('#report').text('Processing...'); console.log('initialize worker'); var worker = new Worker('worker.js'); worker.addEventListener('message', function(ev) { console.log('received raw CSV, now parsing...'); // Parse our CSV raw text Papa.parse(ev.data, { header: true, dynamicTyping: true, complete: function (results) { // Save result in a globally accessible var parsed_csv = results; console.log('parsed CSV!'); console.log(parsed_csv); $('#report').text(parsed_csv.data.length + ' rows processed'); end_time = performance.now(); console.log('Took ' + (end_time - start_time) + " milliseconds to load and process the CSV file.") } }); // Terminate our worker worker.terminate(); }, false); // Submit our file to load var file_to_load = document.getElementById("myFile").files[0]; console.log('call our worker'); worker.postMessage({file: file_to_load}); }); }); </script> </body> </html> 函数在worker.js中导入Papa Parser脚本(这是在工作线程中全局定义的。有关详细信息,请参阅MDN page。)

以下是我的工作示例:

csv.html

self.addEventListener('message', function(e) {
    console.log('worker is running');

    var file = e.data.file;
    var reader = new FileReader();

    reader.onload = function (fileLoadedEvent) {
        console.log('file loaded, posting back from worker');

        var textFromFileLoaded = fileLoadedEvent.target.result;

        // Post our text file back from the worker
        self.postMessage(textFromFileLoaded);
    };

    // Actually load the text file
    reader.readAsText(file, "UTF-8");
}, false);

worker.js

switch (n)
{
case 0:
  return 1;
case 1:
  return x;
case 8:
  x*= x;
case 4:
  x*= x;
case 2:
  return x * x;
case 6:
  x*= x;
case 3:
  return x * x * x;
case 5:
  y= x * x; return x * y * y;
case 7:
  y= x * x * x; return x * y * y;
...
};

它处理的GIF,只需不到一秒钟(全部在本地运行)

GIF of working example

答案 1 :(得分:0)

从v5开始,PapaParse现在拥有baked in WebWorkers。如果您拥有自己的PP工人,则无需重新实现,但对于将来的项目,有些人可能会发现使用PapaParse的解决方案更容易。