Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

Вопрос Как победить javascript на download сформированного *.csv размером более 2-х мегабайт?

Тема в разделе "Прочее", создана пользователем pvvx, 18 апр 2019.

Статус темы:
Закрыта.
  1. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Как победить javascript на download сформированного *.csv размером более 2-х мегабайт?

    Имеется:
    Web-сервер на устройстве... Он отдает данные в Json с датчиков в виде 32 float значений в несколько ms.
    Json опрашивается-принимается AJAX-ом и на HTML странице (загруженной с устройства, c его web) в работающем javascript отрисовываются графики... происходит накопление до 5000 пачек в виде 32 float + флаги...
    На HTML описана кнопка сохранения данных в CSV формате и javascript примерно такого содержания:
    Код (Javascript):
    1. $("butSave").onclick =  function() {
    2.     console.log('Dbase length: '+dbase.length);
    3.     var data = 'data:text/csv;charset=windows-1251,'+UnicodeToWin1251(dev.cfg.txt.flags.join(';'))+';'+UnicodeToWin1251(dev.cfg.txt.params.join(';'))+ "\n";
    4.     dbase.forEach(function(it, idx){data+=it.t.toISOString()+';'+it.tt+';'+it.mode+';'+UnicodeToWin1251(it.flg.join(';'))+';'+UnicodeToWin1251(it.f.join(';'))+'\n';});
    5.     var link = document.createElement('a');
    6.     link.setAttribute('href', data);
    7.     link.setAttribute('download',"data.csv");
    8.     console.log('CSVData length: '+data.length);
    9.     link.click();
    10. }
    11.  
    По мере накопления данных размер CSV для сохранения увеличивается...
    При размере сформированных данных CSV менее 2-х мегабайт файл успешно сохраняетcя в Chrome (для Firefox пишут, что ограничение до 1 040 000 байт). Далее кнопка ‘butSave’ на форме ничего не делает :(
    При 5000 пачек замеров console log пишет:
    Dbase length: 5000
    CSVData length: 3230703

    и $("butSave").onclick = function() не сохраняет файл и вообще ничего делает, кроме печати отмеченного в console log :eek:
     
  2. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    535
    Симпатии:
    63
    Шесть мегов хватит? Проверил на фф хроме ие11
    Код (Text):
    1.  
    2. <!doctype html>
    3. <body onload="on_load();"></body>
    4. <script type="text/javascript">
    5.  
    6.    function download(data, filename, type) {
    7.        var file = new Blob([data], {type: type});
    8.        if (window.navigator.msSaveOrOpenBlob) { // ie10+
    9.            window.navigator.msSaveOrOpenBlob(file, filename);
    10.        } else { // ff, chrome
    11.            url = URL.createObjectURL(file);
    12.            var a = document.createElement("a");
    13.            a.href = url;
    14.            a.download = filename;
    15.            document.body.appendChild(a);
    16.            a.click();
    17.            setTimeout(function() {document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 0);
    18.        }
    19.    }
    20.  
    21.    function on_load() {
    22.        var data = '';
    23.        while (data.length < 6000000) {
    24.            data += '1.23;4.56;7.89;0;0;0;0;0;0;0;0;0;0;0;0\r\n';
    25.        }
    26.        download(data, 'test.csv', 'text/csv');
    27.    }
    28. </script>
    29.  
     
    pvvx нравится это.
  3. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    ie11 вообще требует другого обращения и на него не ставится, т.к. не популярен. На мобилках его нет.
    И проблем. там в том, что заголовок и формат данных 'data:text/csv;charset=windows-1251,' идет в начале всей строки, а такой компонент ограничен где-то в нутрах эксплореров.
    Нужен другой метод сохранения данных.
     
  4. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    535
    Симпатии:
    63
    Перечитал ещё раз первый пост, про мобилки не ничего не заметил.
    Проверял фф и хром на ПК с убунтой, ие11 на гостевом с виндовс8.
    Доеду до дома, на андроиде проверю.
     
  5. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    var aBlob = new Blob( array, options ); где: array - массив Array из объектов ArrayBuffer, ArrayBufferView, Blob, DOMString, или смесь любых из подобных объектов, которая может быть размещена внутри Blob. DOMStrings представлены в кодировке UTF-8. А для Exel надо charset=windows-1251.
    Где там перекодировку впихнуть? Иначе текст в файле выдает в %xx
     
  6. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    535
    Симпатии:
    63
    Насколько я понял, csv текстовый файл, содержит значения накопленных данных, флоатов и флагов, я полагал что это цифры точки запятые и всякие true false.
    У вас передается что то ещё локализованное?
     
  7. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    К примеру рус.Exel читает числа в формате с ',' , а не с '.'. Надо перекодировать точку в запятую у чисел.
    Так-же Exel в csv жрет и такое:
    Код (Javascript):
    1.     var data = '';
    2.     var i = 1;
    3.     while (data.length < 6000000) {
    4.         data += new Date().toISOString()+';"=ДАТАЗНАЧ(ПСТР(A'+i+';1;10))+ВРЕМЗНАЧ(ПСТР(A'+i+';12;8))";'+(((i&2)==0)?'Включено':'Выключено')+';1,23;4,56;7,89;0;0;0;0;0;0;0;0;0;0;0;0\n';
    5.         i++;
    6.     }
    7.  
    В итоге, в Exel, получится преобразованное время в его формат во втором столбце. Ну и т.д. :)
    Хотя вопрос с размером data при раскидывании на теги решился, но локализация всегда нужна...
     
  8. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    535
    Симпатии:
    63
    На андроеде, фф версия 66.0 и хром версия 73.0 сохраняют 6 мегов не локализованного csv и этот csv открываются wps офисом почему то.
    Попробую добавить кириллицу.
     
  9. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Да, ещё - обычно в csv в первой строке заголовки и их надо как-то 'кириллизовать' или "китайнизировать' :)
    Мы же локально сохраняем файл csv, а не в глобалку...
     
  10. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Нашел вариант:
    Код (Javascript):
    1.     var str = data.toString('windows-1251', 0, data.length)
    2.     download(str, 'test.csv', 'text/csv;charset=windows-1251');
    Ну и далее уже по подобию...
     
  11. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    535
    Симпатии:
    63
    А если не utf-8, а windows-1251, то что должно происходить?
    Добавил перекодировку, вроде в таблице не напутал.
    Типа сохраняется в вин-1251 и открывается либреофисом и wps офисом.
    пример (раскрыть)
    Код (HTML5):
    1.  
    2. <!doctype html>
    3. <html lang="ru">
    4. <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    5. </head>
    6. <body onload="on_load();"></body>
    7. <script type="text/javascript">
    8.  
    9.    function download(data, filename, type) {
    10.        var uint8 = new Uint8Array(data.length);
    11.        for(var i = 0; i < data.length; i++) {
    12.           x = data.charCodeAt(i);
    13.           if (x >= 1040 && x <= 1103) { // А..Яа..я
    14.               x -= 848;
    15.            } else if (x == 1025) {   // Ё
    16.                x = 168;
    17.            } else if (x == 1105) {   // ё
    18.                x = 184;
    19.            }
    20.            uint8[i] = x;
    21.        }
    22.        var file = new Blob([uint8], {type: type});
    23.        if (window.navigator.msSaveOrOpenBlob) { // ie10+
    24.            window.navigator.msSaveOrOpenBlob(file, filename);
    25.        } else { // ff, chrome
    26.            var url = URL.createObjectURL(file);
    27.            var a = document.createElement("a");
    28.            a.href = url;
    29.            a.download = filename;
    30.            document.body.appendChild(a);
    31.            a.click();
    32.            setTimeout(function() {document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 0);
    33.        }
    34.    }
    35.  
    36.    function on_load() {
    37.        var data = '';
    38.        for (var i = 1; data.length < 6000000; i++) {
    39.           data += 'Строка ' + i + ';1,23;4,56;7,89;0;0;0;0;0;0;0;0;0;0;0;0' + '\r\n';
    40.       }
    41.       download(data, 'test.csv', 'text/csv');
    42.   }
    43.  
    44. </html>
    45.  
     
  12. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Exel жрет utf-8. Для этого надо прописать в начало csv файла 3 байта: 0xef,0xbb,0xbf. Тогда перекодировать ничего не требуется. Но сделать это не удалось. Не знаю как в javascript вставить спец символы в string.
    Такие варианты не пройдут - у нас система другая... :)
     
  13. Сергей_Ф

    Сергей_Ф Moderator Команда форума

    Сообщения:
    2.148
    Симпатии:
    226
  14. fps

    fps Читатель

    Сообщения:
    55
    Симпатии:
    13
    Вообще, в JS вот так очень не рекомендуется (медленно и память жрет), особенно при большой длине:
    Код (Javascript):
    1.  var data = '';
    2.     var i = 1;
    3.     while (data.length < 600000) {
    4.         data += new Date().toString()+'\n';
    5.         i++;
    6.     }
    7.  
    Лучше push в массив и в конце join его в строку. Типа такого:
    Код (Javascript):
    1.  var data = [];
    2.     while (data.length < 60000) {
    3.         data.push(new Date().toString());
    4.     }
    5. data=data.join('\n')
    6.  
     
  15. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    535
    Симпатии:
    63
    Да зачем же всё в стринг засовывать, ничего полезного из этого не получается.
    Именно по этому, я и преобразую коды символов, представленных как интеджер, и сохраняю в типизированный массив беззнаковых 8-ми битных интеджеров - Uint8Array, от него же и блоб строю.
    Фактически данные в блоб-е произвольные, текст, изображения, архив и т.п.
    Сейчас сохраняю в вин-1251, при открытии файла, либреофис предлагает выбрать кодировку для файла. На смартфоне, wps офис открывает сразу, про кодировку не спрашивая.
    Мой пример у вас не заработал?
    П.С.
    На excel пока денег жалко.
     
  16. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Подумав, поразмыслив, и по вашему первому вопросу - если можно ничего не перекодировать, то и незачем это делать. Если жрут utf-8 все, включая разные программы что нашел, то так и выходит проще.
    Да. Спасибо. Я всё учитываю и накапливаю...
    Он у меня, как и win официальная, оплаченная. Как в конторе иначе, если и на домашнем компе работаю?
     
  17. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Памяти не жалко и производительности так-же. Приложение, в котором участвует данная система рассчитано на единичные сохранения в случае обнаружения каких-либо глюков в системе и для передачи специалистам. А графическая информация (графики) и прочее для диспетчера или другого пользователя отображается и обрабатывается другой частью (тоже на javascript) совместно web-серваком и виртуальным устройством встроенным в систему на Linux...
    Это как дамп при сбое...
     
  18. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    Концепция вышла такая: на пользователе запускается типа драйвер на javascript. Он обеспечивает вязь с сервером и разгребает полученные данные и описания к ним по сложным шаблонам. Графики так-же запрашивают у него данные для построения... Сам HTML при этом пишет кто угодно, вплоть до нанятого дизайнера. Но надо обеспечить минимальную функциональность - в данном случае кнопку сохранения данных в csv для сложных случаев поведения самого контролируемого объекта. И тут чем инфы больше, тем лучше. От этого csv и выходит мегабайтный...
     
  19. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    (Поведение виртуального устройства и что ему отдавать в Json или в XLS и типа описывается особым скриптом. Как принимать данные от источников и их обрабатывать - аналогично. Расчет всего на то, что можно описать практически любое устройство с накоплением данных.)
     
  20. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.485
    Симпатии:
    1.275
    И т.к. контролируемые устройства не строго одинаковые, а отличаются, то битики превращаются в названия и они на русском языке. А это уже стринг. В таком виде и может выходить csv. Ну типа "включено/выключено" "Старт/Стоп/Ожидает" и т.д. , а не "1"/"0" в которых потом никто не разберется, т.к. данных с устройств поступает много и это не Arduino - на каждый бит или значение должны быть: оценка качества сигнала, вкл.откл. обработка и т.д. Как на атомной станции :).
     
Статус темы:
Закрыта.

Поделиться этой страницей