Javascript: преобразовать массив в формат CSV и скопировать в буфер обмена

Я пытаюсь преобразовать массив в строки, которые можно вставить в файл Excel CSV. В приведенном ниже коде я могу отформатировать содержимое массива так, как я хочу (в строке // return csvFile;). Сразу после этого я пытаюсь создать скрытый ввод, добавить к нему содержимое csvFile, выделить текст в элементе и скопировать, но он не работает. Вот мой код:

var array = [
    [0,1,1,0],
    [1,0,0,1],
    [1,0,0,1],
    [0,1,1,0]
];
var string = copyCsv(array);
console.info(string);

function copyCsv(rows) {
    var processRow = function (row) {
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0)
                result = '"' + result + '"';
            if (j > 0)
                finalVal += ',';
            finalVal += result;
        }
        return finalVal + '\n';
    };

    var csvFile = "\ufeff"+'';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }
    //return csvFile;
    var $temp = $("<input>");
    csvFile.append($temp);
    $temp.val($(element).text()).select();
    document.execCommand("copy");
    $temp.remove();
}

Вы можете найти мой JsFiddle здесь: https://jsfiddle.net/xpvt214o/464368/

Спасибо,

Привет, @Creek, Барбара, ты можешь быть более конкретным? Что не работает в вашем коде - контент не форматируется в формате CSV или контент не копируется?

CuriousMind 23.07.2018 06:07

Вы не можете сохранить файл на сервере с помощью клиентского JavaScript, если вы этого хотите.

StackSlave 23.07.2018 06:08

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

Creek Barbara 23.07.2018 06:09

@PHPglue Я не пытаюсь сохранить файл. Я пытаюсь скопировать строку. Мое плохое, неправильное имя моих переменных, я повторно использую тот же код, который использовал для сохранения файла CSV.

Creek Barbara 23.07.2018 06:10

Проверьте свою консоль. У вас много ошибок типа и ссылок. После исправления, вы столкнетесь с проблемой, что execCommand('cut'/'copy') должен быть инициирован жестом пользователя (поэтому будет работать только нажатие кнопки «от»). В зависимости от размера данных, которые вы пытаетесь сгенерировать, вы также можете попасть в Эта проблема.

Kaiido 23.07.2018 06:13

Привет, Крик, Барбара, проблема в том, что мы не можем выбрать скрытый элемент HTML. использование не скрытого ввода (с использованием вашей стратегии) ​​работает jsfiddle.net/t8raz47c/5

D. Seah 23.07.2018 06:24

@ D.Seah Круто, это работает. Почему не работает, когда я перемещаю Javascript в окно javascript, а не в тег скрипта?

Creek Barbara 23.07.2018 06:35

@ Крик Барбара, ты можешь мне сказать, о чем идет речь в csvFile.append ($ temp)? Спасибо

D. Seah 23.07.2018 16:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
8
2 072
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если я правильно понял ваш вопрос. Вы хотите добавить свой формат CSV в скрытое поле ввода.

Я немного изменил ваш код

function copyCsv(rows) {
        var processRow = function (row) {
            var finalVal = '';
            for (var j = 0; j < row.length; j++) {
                var innerValue = row[j] === null ? '' : row[j].toString();
                if (row[j] instanceof Date) {
                    innerValue = row[j].toLocaleString();
                };
                var result = innerValue.replace(/"/g, '""');
                if (result.search(/("|,|\n)/g) >= 0)
                    result = '"' + result + '"';
                if (j > 0)
                    finalVal += ',';
                finalVal += result;
            }
            return finalVal + '\n';
        };

        var csvFile = "\ufeff"+'';
        for (var i = 0; i < rows.length; i++) {
            csvFile += processRow(rows[i]);
        }
        //return csvFile;
        console.info(csvFile);

       var x = document.createElement("INPUT");
      x.setAttribute("type", "hidden");
      x.setAttribute("id", "myHiddenData");
      document.body.appendChild(x);
      document.getElementById("myHiddenData").value = csvFile;

        document.execCommand("copy");

        var copyText = document.getElementById("myHiddenData");

    document.execCommand("copy");

    copyText.select();

    /* Copy the text inside the text field */
    document.execCommand("copy");

    alert("Copied the text: " + copyText.value);

  }

Рабочий Скрипка

Моя основная цель - скопировать содержимое csvFile в буфер обмена. Спасибо за вашу помощь, но код возвращает эту ошибку "Uncaught ReferenceError: copyCsv не определен в HTMLButtonElement.onclick"

Creek Barbara 23.07.2018 06:18

@CreekBarbara это потому, что jsfiddle настроен на перенос ваших js в функцию onload и что вы прикрепили обработчик кликов как атрибут onclick => он ищет window.copyCsv, которого не существует. Установка параметра скрипки на без обертывания в теле заставит этот код работать при щелчке мышью (но он не будет сначала вызывать, потому что execCommand требует пользовательского жеста)

Kaiido 23.07.2018 06:20

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

Creek Barbara 23.07.2018 06:26
Ответ принят как подходящий

.select() должен быть выполнен с элементом, добавленным в DOM, чтобы execCommand() скопировал его.

Кроме того, современные браузеры не позволяют копировать в буфер обмена, если пользователь не щелкнет для ее запуска.

Я использовал элемент textarea, так как там несколько строк ....

Это работает:

console.clear();
var array = [
  [0,1,1,0],
  [1,0,0,1],
  [1,0,0,1],
  [0,1,1,0]
];

// A button to trigger the copy action.
$("#copy").on("click",function(){
  var string = copyCsv(array);
  console.info(string);
});

function copyCsv(rows) {
  var processRow = function (row) {
    var finalVal = '';
    for (var j = 0; j < row.length; j++) {
      var innerValue = row[j] === null ? '' : row[j].toString();
      if (row[j] instanceof Date) {
        innerValue = row[j].toLocaleString();
      };
      var result = innerValue.replace(/"/g, '""');
      if (result.search(/("|,|\n)/g) >= 0)
        result = '"' + result + '"';
      if (j > 0)
        finalVal += ',';
      finalVal += result;
    }
    return finalVal + '\n';
  };

  var csvFile = "\ufeff"+'';
  for (var i = 0; i < rows.length; i++) {
    csvFile += processRow(rows[i]);
  }
  console.info(csvFile);

  //return csvFile;
  var $temp = $("<textarea id='temp'>").text(csvFile);
  $("body").append($temp)
  $("#temp").select();
  var result = document.execCommand("copy");
  $("#temp").remove();
  return result?"Copied to clipboard":"Clipboard failed...";
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id = "copy">Copy</button>

Это не так:

console.clear();
var array = [
  [0,1,1,0],
  [1,0,0,1],
  [1,0,0,1],
  [0,1,1,0]
];

var string = copyCsv(array);
console.info(string);

function copyCsv(rows) {
  var processRow = function (row) {
    var finalVal = '';
    for (var j = 0; j < row.length; j++) {
      var innerValue = row[j] === null ? '' : row[j].toString();
      if (row[j] instanceof Date) {
        innerValue = row[j].toLocaleString();
      };
      var result = innerValue.replace(/"/g, '""');
      if (result.search(/("|,|\n)/g) >= 0)
        result = '"' + result + '"';
      if (j > 0)
        finalVal += ',';
      finalVal += result;
    }
    return finalVal + '\n';
  };

  var csvFile = "\ufeff"+'';
  for (var i = 0; i < rows.length; i++) {
    csvFile += processRow(rows[i]);
  }
  console.info(csvFile);

  //return csvFile;
  var $temp = $("<textarea id='temp'>").text(csvFile);
  $("body").append($temp)
  $("#temp").select();
  var result = document.execCommand("copy");
  $("#temp").remove();
  return result?"Copied to clipboard":"Clipboard failed...";
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Спасибо, это отлично работает, но мне трудно понять, что «.select () нужно сделать для элемента, добавленного в DOM, чтобы execCommand () скопировал его», извините, я новичок. Что я делал не так? ожидайте ввода вместо текстовой области.

Creek Barbara 23.07.2018 07:16

Фактически, первая попытка скопировать берет то, что есть в моем существующем текстовом поле. Мне нужно дважды нажать кнопку, чтобы скопировать нужную информацию

Creek Barbara 23.07.2018 07:28

Текст для копирования должен быть сфокусирован ... Или выделен .select(). Если это только объект jQuery, не добавленный в DOM ... Копия терпит неудачу, в то время как она странным образом возвращает истину ... Но, судя по моим тестам в Chrome, это не удается.

Louys Patrice Bessette 23.07.2018 07:39

Мне это не совсем понятно, но моя главная проблема сейчас в том, что я дважды нажимаю кнопку, чтобы скопировать контент. Что здесь не так?

Creek Barbara 23.07.2018 07:41

Я не знаю насчет 2 кликов ... В приведенном здесь фрагменте требуется только 1.

Louys Patrice Bessette 23.07.2018 07:42

Я сделал CodePen, если вы хотите поиграть с ним ...

Louys Patrice Bessette 23.07.2018 07:45

Да, это работает в вашем примере, но когда я интегрирую его в свой код, я дважды нажимаю кнопку, чтобы скопировать контент в буфер обмена. Посмотрите на другие комментарии и ответы на жест пользователя. Я этого не понимаю.

Creek Barbara 23.07.2018 07:49

Позвольте нам продолжить обсуждение в чате.

Louys Patrice Bessette 23.07.2018 07:50

Другие вопросы по теме