Как читать данные Из файла *.CSV с помощью javascript?

Мои данные csv выглядят следующим образом:

Заголовок1, Заголовок 2, heading3, heading4, heading5, value1_1, value2_1, value3_1, value4_1, value5_1, value1_2, value2_2, value3_2, value4_2, value5_2....

Как вы читаете эти данные и конвертируете их в такой массив, используя Javascript?:

[рубрика1: значение1_1, заголовок2: значение2_1, заголовок3: значение3_1, заголовок4: value4_1, heading5: value5_1], [heading1: value1_2, heading2: value2_2, heading3: value3_2, heading4: value4_2, heading5: value5_2]....

Я пробовал этот код, но не повезло!:

<script type="text/javascript">
    var allText =[];
    var allTextLines = [];
    var Lines = [];

    var txtFile = new XMLHttpRequest();
    txtFile.open("GET", "file://d:/data.txt", true);
    txtFile.onreadystatechange = function()
    {
        allText = txtFile.responseText;
        allTextLines = allText.split(/\r\n|\n/);
    };

    document.write(allTextLines);<br>
    document.write(allText);<br>
    document.write(txtFile);<br>
</script>

Ответ 1

ПРИМЕЧАНИЕ. Я придумал это решение, прежде чем мне напомнили обо всех "особых случаях", которые могут возникать в действительном файле CSV, например, в экранированных кавычках. Я оставляю свой ответ тем, кто хочет что-то быстро и грязно, но я рекомендую Evan answer для точности.


Этот код будет работать, если ваш файл data.txt представляет собой одну длинную строку разделенных запятыми записей без новых строк:

data.txt:

 heading1,heading2,heading3,heading4,heading5,value1_1,...,value5_2

JavaScript:

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(allText) {
    var record_num = 5;  // or however many elements there are in each row
    var allTextLines = allText.split(/\r\n|\n/);
    var entries = allTextLines[0].split(',');
    var lines = [];

    var headings = entries.splice(0,record_num);
    while (entries.length>0) {
        var tarr = [];
        for (var j=0; j<record_num; j++) {
            tarr.push(headings[j]+":"+entries.shift());
        }
        lines.push(tarr);
    }
    // alert(lines);
}

Следующий код будет работать с "истинным" CSV файлом с разрывами строк между каждым набором записей:

data.txt:

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

JavaScript:

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(allText) {
    var allTextLines = allText.split(/\r\n|\n/);
    var headers = allTextLines[0].split(',');
    var lines = [];

    for (var i=1; i<allTextLines.length; i++) {
        var data = allTextLines[i].split(',');
        if (data.length == headers.length) {

            var tarr = [];
            for (var j=0; j<headers.length; j++) {
                tarr.push(headers[j]+":"+data[j]);
            }
            lines.push(tarr);
        }
    }
    // alert(lines);
}

http://jsfiddle.net/mblase75/dcqxr/

Ответ 2

Не нужно писать свои собственные...

Библиотека jQuery-CSV имеет функцию $.csv.toObjects(csv), которая автоматически выполняет сопоставление.

Примечание. Библиотека предназначена для обработки любых CSV-данных, которые RFC 4180 совместимы, включая все неприятные случаи кросс, которые наиболее "простые" 'решения не видят.

Как уже говорилось в @Blazemonger, сначала вам нужно добавить разрывы строк, чтобы данные были достоверными CSV.

Используя следующий набор данных:

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

Используйте код:

var data = $.csv.toObjects(csv):

Выход, сохраненный в 'data', будет выглядеть следующим образом:

[
  { heading1:"value1_1",heading2:"value2_1",heading3:"value3_1",heading4:"value4_1",heading5:"value5_1" } 
  { heading1:"value1_2",heading2:"value2_2",heading3:"value3_2",heading4:"value4_2",heading5:"value5_2" }
]

Примечание. Технически, способ, которым вы написали сопоставление значения ключа, является недопустимым JavaScript. Объекты, содержащие пары ключ-значение, должны быть заключены в скобки.

Если вы хотите попробовать это для себя, я предлагаю вам взглянуть на демонстрацию основного использования в разделе 'toObjects()' вкладка.

Отказ от ответственности: я являюсь оригинальным автором jQuery-CSV.

Update:

Отредактировано для использования набора данных, предоставленного оператором, и содержит ссылку на демонстрационную версию, где данные могут быть проверены на достоверность.

Update2:

Из-за затвора кода Google. jquery-csv переместился в GitHub

Ответ 3

Не разделяйте запятыми - это не сработает для большинства файлов CSV, и этот вопрос имеет слишком много просмотров для типа запросов для ввода данных для всех. Разбор CSV выглядит пугающе, так как нет действительно официального стандарта, и множество текстовых редакторов с разделителями не рассматривают случаи ребер.

Этот вопрос старый, но я считаю, что теперь есть лучшее решение, которое доступно

(Обновление:). В Papa Parse 4 тот же файл занимает около 30 секунд в Firefox. Теперь Papa Parse 4 наиболее быстрый CSV-анализатор для браузера.)

Анализ текста очень прост:

var data = Papa.parse(csvString);

Разбор файлов также прост:

Papa.parse(file, {
    complete: function(results) {
        console.log(results);
    }
});

Потоковые файлы похожи (здесь пример, который передает удаленный файл):

Papa.parse("http://example.com/bigfoo.csv", {
    download: true,
    step: function(row) {
        console.log("Row:", row.data);
    },
    complete: function() {
        console.log("All done!");
    }
});

Если ваша веб-страница блокируется во время разбора, Papa может использовать веб-работников, чтобы ваш веб-сайт реагировал.

Папа может автоматически обнаруживать разделители и сопоставлять значения с колонками заголовков, если присутствует строка заголовка. Он также может превращать числовые значения в фактические типы номеров. Он надлежащим образом разбирает разрывы строк и цитаты и другие странные ситуации и даже обрабатывает искаженный ввод как можно более надежно. Я нарисовал вдохновение из существующих библиотек, чтобы сделать Papa, поэтому поддерживает другие реализации JS.

Ответ 4

Я использую d3.js для разбора csv файла. Очень проста в использовании. Вот документы.

шаги:

  • npm install d3-request

Использование Es6;

import { csv } from 'd3-request';
import url from 'path/to/data.csv';

csv(url, function(err, data) {
 console.log(data);
})

Подробнее см. В документах.

Ответ 5

Здесь функция JavaScript, которая анализирует данные CSV, с учетом запятых, найденных внутри кавычек.

// Parse a CSV row, accounting for commas inside quotes                   
function parse(row){
  var insideQuote = false,                                             
      entries = [],                                                    
      entry = [];
  row.split('').forEach(function (character) {                         
    if(character === '"') {
      insideQuote = !insideQuote;                                      
    } else {
      if(character == "," && !insideQuote) {                           
        entries.push(entry.join(''));                                  
        entry = [];                                                    
      } else {
        entry.push(character);                                         
      }                                                                
    }                                                                  
  });
  entries.push(entry.join(''));                                        
  return entries;                                                      
}

Пример использования функции для разбора CSV файла, который выглядит следующим образом:

"foo, the column",bar
2,3
"4, the value",5

в массивы:

// csv could contain the content read from a csv file
var csv = '"foo, the column",bar\n2,3\n"4, the value",5',

    // Split the input into lines
    lines = csv.split('\n'),

    // Extract column names from the first line
    columnNamesLine = lines[0],
    columnNames = parse(columnNamesLine),

    // Extract data from subsequent lines
    dataLines = lines.slice(1),
    data = dataLines.map(parse);

// Prints ["foo, the column","bar"]
console.log(JSON.stringify(columnNames));

// Prints [["2","3"],["4, the value","5"]]
console.log(JSON.stringify(data));

Здесь вы можете преобразовать данные в объекты, например D3 csv parser (это твердое стороннее решение):

var dataObjects = data.map(function (arr) {
  var dataObject = {};
  columnNames.forEach(function(columnName, i){
    dataObject[columnName] = arr[i];
  });
  return dataObject;
});

// Prints [{"foo":"2","bar":"3"},{"foo":"4","bar":"5"}]
console.log(JSON.stringify(dataObjects));

Здесь рабочая скрипта этого кода.

Наслаждайтесь! - Curran

Ответ 6

В соответствии с принятым ответом ,

Я получил это для работы, изменив здесь 1 на 0:

for (var i=1; i<allTextLines.length; i++) {

изменено на

for (var i=0; i<allTextLines.length; i++) {

Он вычислит файл с одной непрерывной линией как имеющий allTextLines.length 1. Итак, если цикл начинается с 1 и работает до тех пор, пока он меньше 1, он никогда не запускается. Отсюда следует пустое поле оповещения.

Ответ 7

Вот еще один способ прочитать внешний CSV в Javascript (используя jQuery).

Это немного длиннее, но я чувствую, читая данные в массивы, вы можете точно следить за процессом и упростить поиск и устранение неисправностей.

Может помочь кому-то другому.

Пример файла данных:

Time,data1,data2,data2
08/11/2015 07:30:16,602,0.009,321

И вот код:

$(document).ready(function() {
 // AJAX in the data file
    $.ajax({
        type: "GET",
        url: "data.csv",
        dataType: "text",
        success: function(data) {processData(data);}
        });

    // Let process the data from the data file
    function processData(data) {
        var lines = data.split(/\r\n|\n/);

        //Set up the data arrays
        var time = [];
        var data1 = [];
        var data2 = [];
        var data3 = [];

        var headings = lines[0].split(','); // Splice up the first row to get the headings

        for (var j=1; j<lines.length; j++) {
        var values = lines[j].split(','); // Split up the comma seperated values
           // We read the key,1st, 2nd and 3rd rows 
           time.push(values[0]); // Read in as string
           // Recommended to read in as float, since we'll be doing some operations on this later.
           data1.push(parseFloat(values[1])); 
           data2.push(parseFloat(values[2]));
           data3.push(parseFloat(values[3]));

        }

    // For display
    var x= 0;
    console.log(headings[0]+" : "+time[x]+headings[1]+" : "+data1[x]+headings[2]+" : "+data2[x]+headings[4]+" : "+data2[x]);
    }
})

Надеюсь, это поможет кому-то в будущем!

Ответ 8

Вы можете использовать PapaParse, чтобы помочь. https://www.papaparse.com/

Вот CodePen. https://codepen.io/sandro-wiggers/pen/VxrxNJ

Papa.parse(e, {
            header:true,
            before: function(file, inputElem){ console.log('Attempting to Parse...')},
            error: function(err, file, inputElem, reason){ console.log(err); },
            complete: function(results, file){ $.PAYLOAD = results; }
        });

Ответ 9

function CSVParse(csvFile)
{
    this.rows = [];

    var fieldRegEx = new RegExp('(?:\s*"((?:""|[^"])*)"\s*|\s*((?:""|[^",\r\n])*(?:""|[^"\s,\r\n]))?\s*)(,|[\r\n]+|$)', "g");   
    var row = [];
    var currMatch = null;

    while (currMatch = fieldRegEx.exec(this.csvFile))
    {
        row.push([currMatch[1], currMatch[2]].join('')); // concatenate with potential nulls

        if (currMatch[3] != ',')
        {
            this.rows.push(row);
            row = [];
        }

        if (currMatch[3].length == 0)
            break;
    }
}

Мне нравится иметь регулярное выражение как можно больше. Это регулярное выражение обрабатывает все элементы как кавычки или без кавычек, за которыми следует либо разделитель столбцов, либо разделитель строк. Или конец текста.

Именно поэтому это последнее условие - без него было бы бесконечным циклом, поскольку шаблон может соответствовать полю нулевой длины (полностью действительный в csv). Но так как $является утверждением с нулевой длиной, оно не будет прогрессировать до несоответствия и закончить цикл.

И FYI, мне пришлось сделать вторую альтернативу исключать цитаты, окружающие значение; похоже, что он выполнялся до первой альтернативы на моем javascript-движке и рассматривал цитаты как часть некотируемого значения. Я не буду спрашивать - просто получил его на работу.