...

Создание текстовых UTF-8 файлов

Тема в разделе "Примеры сценариев", создана пользователем kamyshev, 28 сен 2022.

  1. kamyshev

    kamyshev Активный участник

    Задача: сгенерировать csv-файл в кодировке UTF-8 с BOM-флагом и положить его в контекстную переменную типа Файл.

    На просторах github был найден и адаптирован следующий скрипт:
    Код:
    
    async function createCSVFile(): Promise<void> {
        
    let test_string:string
        test_string 
    'Заголовок первого поля;'
        
    // Если нужен Unix-стиль переносов - используем просто \n
        
    test_string += 'Значение первого поля\r\n'

        
    try{
            
    Context.data.file await Context.fields.file.create('file.csv',toUTF8(test_string))
        }
        catch(
    e){
            
    Context.data.debug e.message
        
    }
    }

    function 
    toUTF8(str:string):ArrayBuffer {
        
    let utf8:number[] = []
        
    // BOM-флаг, если не требуется - можно закомментировать
        
    utf8.push(0xef0xbb0xbf)
        for (var 
    i=0str.lengthi++) {
            
    let charcode str.charCodeAt(i)
            if (
    charcode 0x80utf8.push(charcode)
            else if (
    charcode 0x800) {
                
    utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode 0x3f))
            }
            else if (
    charcode 0xd800 || charcode >= 0xe000) {
                
    utf8.push(0xe0 | (charcode >> 12),
                          
    0x80 | ((charcode>>6) & 0x3f),
                          
    0x80 | (charcode 0x3f));
            }
            
    // surrogate pair
            
    else {
                
    i++;
                
    charcode = ((charcode&0x3ff)<<10)|(str.charCodeAt(i)&0x3ff)
                
    utf8.push(0xf0 | (charcode >>18),
                          
    0x80 | ((charcode>>12) & 0x3f),
                          
    0x80 | ((charcode>>6) & 0x3f),
                          
    0x80 | (charcode 0x3f))
            }
        }
        return new 
    Uint16Array(utf8)
    }
  2. aa_dovgal

    aa_dovgal Новичок

    Добрый день!
    Воспроизвела ваш код, но возникает ошибка на этапе создания файла:
    e.message = [{"path":"/name","desc":"required","level":"error"}]: invalid argument

    Не подскажете, как это можно решить?
  3. kamyshev

    kamyshev Активный участник

    Кроме кода необходимо создать также и указанные контекстные переменные. Проверил в SaaS этот же пример, всё по-прежнему работает. Можете сюда прикрепить свой код?
  4. alekc_bpm87

    alekc_bpm87 Эксперт

    Может кому пригодится: собрали интересный кейс, с хранением большого json (несколько мегабайт) в элмовском файле для дальнейшего использования например в табуляторе, т.к. при хранении такого json в строке - элма загибалась с ошибкой resource exhausted.
    Создание элмовского файла из json:
    Код:
    
    let str JSON.stringify(item_json);
        var 
    buf = new ArrayBuffer(str.length*2);
        var 
    bufView = new Uint16Array(buf);
        for (var 
    i=0strLen=str.lengthi<strLeni++) {
            
    bufView[i] = str.charCodeAt(i);
        }
        
    Context.data.json_file await Context.fields.json_file.create("json.txt"buf);
    Извлечение из файла - json (работает стабильно на объеме до 100 МБ! и при этом - в 20 раз! быстрее чем с Blob):
    Код:
    
    let file_link await Context.data.json_file.getDownloadUrl();
            
    let fileRq await fetch(file_link);
            
    let buf await fileRq.arrayBuffer();
           var 
    bufView = new Uint16Array(buf);
                var 
    length bufView.length;
                var 
    result '';
                var 
    addition Math.pow(2,16)-1;
                for(var 
    0;i<length;i+=addition){

                    if(
    addition length){
                        
    addition length i;
                    }
                    
    result += String.fromCharCode.apply(nullbufView.subarray(i,i+addition));
                }
           
    let json_obj JSON.parse(result);
    Context.data.json_file - переменная типа Файл