Значения заголовка повторяются в каждой строке при создании файла CSV - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь создать CSV.Поскольку данные огромны, я хотел продолжать добавлять данные в файл, а не сохранять записи в массиве, а затем выгружать все данные сразу в CSV.Поэтому я написал следующий код, который имитирует то, что я хочу сделать.50 случайных записей создаются и добавляются в файл каждую секунду.Код работает нормально, но проблема в окончательном CSV.Это выглядит следующим образом:

"id","value""value","id"
3226,"3653aab688be4934""value","id"
4070,"9de2be11958fa207""value","id"
2061,"b754b9164146d37f""value","id"
6216,"ac85aa653bfc845d""value","id"
48,"caf5f55c49fde7bf""value","id"
4330,"2c33ae658de7a3eb""value","id"
1997,"34caef7b4ae96edd""value","id"

Я не мог понять причину этого.Я также прочитал соответствующий пост SO , но это тоже не помогло.

const json2csv = require('json2csv').parse;
const fs = require('fs');

Promise = require('bluebird');

let plist = [];
let count = 0;
let intvl = null;

let fields = ['id', 'value'];

function start() {

    if(count++ > 50) {
            Promise.all(plist)
                    .then(r => {
                            clearInterval(intvl);
                            console.log('file created');
                            process.exit(0);
                    })
                    .catch(err => {
                            console.log(err);
                            process.exit(-1);
                    })
    }

    let data = [{
            value: Math.floor(Math.random() * 9999),
            id: require('crypto').randomBytes(8).toString('hex')
    }];

    plist.push(append(json2csv(data)));

}


function append(data) {

    return new Promise((resolve, reject) => {

            fs.appendFile('./stream.csv', data, (err, resp) => {
                    if(err) reject(err);
                    else resolve();
            });
    });
}


function init() {

    fs.stat('./stream.csv', (err, resp) => {
            if(err) {
                    fs.writeFileSync('./stream.csv', json2csv([], {fields}));
            }
            intvl = setInterval(() => {
                    start();
            }, 1100);
    })
}

init();

Что мне не хватает?Сначала код проверяет, существует ли файл.Если этого не произойдет, создается файл только с заголовками, а затем следует обычный процесс записи.Я попытался удалить часть, где написаны только заголовки.Это помогает удалить дубликаты заголовков в верхней части, но не помогает повторять заголовки в каждом ряду.Как это можно предотвратить?

1 Ответ

0 голосов
/ 08 июня 2018

Я думаю, что проблема связана с несколькими циклами вашего кода.Каждый цикл добавляет fields заголовок («значение», «id») к последней строке так:

Первый цикл у нас есть

"id","value""value","id"
 3405,"6874eb66f714e717"

Второй цикл

 "id","value""value","id"
3405,"6874eb66f714e717""value","id" <-- "value","id" added
1436,"c91056b1207598bb"

и так далее.Вы должны добавить заголовок только в первый раз, используя fs.writeFileSync('./stream.csv', json2csv([], {fields})); и удалить дополнительный заголовок, возвращенный из json2csv, чтобы изолировать ваш data.

В настоящее время кажется невозможным передать пустой заголовок json2csv используя вызов как json2csv(data, {}).

Вот пример:

const json2csv = require('json2csv').parse;
const fs = require('fs');

Promise = require('bluebird');

let plist = [];
let count = 0;
let intvl = null;

let fields = ['id', 'value'];

function start() {

if(count++ > 50) {
    Promise.all(plist)
        .then(r => {
            clearInterval(intvl);
            console.log('file created');
            process.exit(0);
        })
        .catch(err => {
            console.log(err);
            process.exit(-1);
        })
}

let data = [{
    id: Math.floor(Math.random() * 9999), //id should be set in this way
    value: require('crypto').randomBytes(8).toString('hex')

}];

plist.push(append(json2csv(data).replace('"id","value"',''))); //remove header

}

function append(data) {

    return new Promise((resolve, reject) => {

    fs.appendFile('./stream.csv', data, (err, resp) => {
        if(err) reject(err);
        else resolve();
    });
});
}

function init() {

fs.stat('./stream.csv', (err, resp) => {
    if(err) {
        fs.writeFileSync('./stream.csv', json2csv([], {fields}));
       }
        intvl = setInterval(() => {
           start();
           }, 1100);
    })
}

init();

И сгенерированный выходной файл stream.csv:

"id","value"
2462,"7c9197ae6c101f27"
7714,"e1bbfa2dc9adba7a"
2728,"3ff6673cd22bb00b"
8686,"c1f61c138e7b9fdc"
6687,"01d006f74412459a"
7888,"7ccf8e40b9cc4192"
2892,"1672a034573d1be3"
6228,"d8d004148c59134b"
2273,"5028b14b40029d4c"
5114,"1e282fd1c9a84e25"
3636,"c2b7d2250e6fad1e"
8096,"9fb35e54f749417f"
8955,"f2ccc57eab5438a0"
3957,"b323e7addc967d29"
...