Javascript: загрузка данных в файл из контента на странице - PullRequest
21 голосов
/ 15 ноября 2010
Значение

следующее: у меня есть домашняя страница, на которой я отображаю диаграмму, построенную с использованием значений, разделенных запятыми, внутри страницы.Я хотел бы дать пользователям возможность загружать данные в виде cvs-файла без повторного обращения к серверу.(поскольку данные уже есть) Это как-то возможно?Я бы предпочел чистое решение JavaScript.

Пока что я обнаружил: http://pixelgraphics.us/downloadify/test.html, но оно включает в себя флэш, которого я бы хотел избежать.представьте себе, что этот вопрос еще не задавался.Извините за двойной пост, но, похоже, я использовал неправильные ключевые слова или что-то в этом роде - я не нашел решения на этих форумах.

Ответы [ 8 ]

28 голосов
/ 16 сентября 2011

Проверено на Safari 5, Firefox 6, Opera 12, Chrome 26.

<a id='a'>Download CSV</a>
<script>
    var csv = 'a,b,c\n1,2,3\n';
    var a = document.getElementById('a');
    a.href='data:text/csv;base64,' + btoa(csv);
</script>

HTML5

<a id='a' download='Download.csv' type='text/csv'>Download CSV</a>
<script>
    var csv = 'a,b,c\n1,2,3\n';
    var data = new Blob([csv]);
    var a = document.getElementById('a');
    a.href = URL.createObjectURL(data);
</script>
17 голосов
/ 07 октября 2013

Простое решение:

function download(content, filename, contentType)
{
    if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
}

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

download("csv_data_here", "filename.csv", "text/csv");
8 голосов
/ 15 ноября 2010

Обновление :

Время определенно меняет вещи ;-) Когда я впервые ответил на этот вопрос IE8 был последним браузером IE, доступным (ноябрь 2010), и поэтомуне было никакого кросс-браузерного способа сделать это без обращения к серверу или использования инструмента, требующего Flash.

@ Ответ Zectburno даст вам то, что вам нужно сейчас, однако для исторического контекстазнать, какие браузеры IE поддерживают какую функцию.

  • btoa () не определен в IE8 и IE9
  • BLOB-объект доступен в IE10 +

Убедитесь, чтоДля тестирования в браузерах вам необходимо поддерживать.Несмотря на то, что пример Blob в другом ответе должен работать в IE10 +, он не работает для меня, просто нажав на ссылку (браузер ничего не делает, без ошибок) ... только если я щелкну правой кнопкой мыши и сохраню цель как "file.csv", топерейдите к файлу и дважды щелкните его, чтобы открыть файл.

Проверьте оба подхода (btoa / Blob) в этом JSFiddle. (вот код)

<!doctype html>
<html>
<head>
</head>
<body>
  <a id="a" target="_blank">Download CSV (via btoa)</a>
  <script>
    var csv = "a,b,c\n1,2,3\n";
    var a = document.getElementById("a");
    a.href = "data:text/csv;base64," + btoa(csv);
  </script>
  <hr/>
  <a id="a2" download="Download.csv" type="text/csv">Download CSV (via Blob)</a>
  <script>
    var csv = "a,b,c\n1,2,3\n";
    var data = new Blob([csv]);
    var a2 = document.getElementById("a2");
    a2.href = URL.createObjectURL(data);
  </script>
</body>
</html>

Оригинальный ответ :

Не думаю, что для этого есть опция.

Я бы просто изменил ваш код так, чтобы, если Flash 10+ былобнаружено ( 93% насыщения по состоянию на сентябрь 2009 г. ) в системе пользователя, укажите параметр Downloadify, в противном случае откройте запрос на стороне сервера.

3 голосов
/ 15 ноября 2010
function export(exportAs) {
    var csvText = tableRowsToCSV(this.headTable.rows);­
    csvText += tableRowsToCSV(this.bodyTable.rows);­
    //open the iframe doc for writing
    var expIFrame;
    if (strBrowser == "MSIE") expIFrame = document.exportiframe;
    else expIFrame = window.framesexportiframe;
    var doc = expIFrame.document;
    doc.open('text/plain', 'replace');
    doc.charset = "utf-8";
    doc.write(csvText);
    doc.close();
    var fileName = exportAs + ".txt";
    doc.execCommand("SaveAs", null, fileName);
}

function tableRowsToCSV(theRows) {
    var csv = "";
    var csvRow = "";
    var theCells;
    var cellData = "";
    for (var r = 0; r < theRows.length; r++) {
        theCells = theRows.item(r).cells;
        for (var c = 0; c < theCells.length; c++) {
            cellData = "";
            cellData = theCells.item(c).innerText;
            if (cellData.indexOf(",") != -1) cellData = "'" + cellData + "'";
            if (cellData != "") csvRow += "," + cellData;
        }
        if (csvRow != "") csvRow = csvRow.substring(1, csvRow.length);­
        csv += csvRow + "\n";
        csvRow = "";
    }
    return csv;
}

Я нашел этот код в другом месте, здесь , ранее

3 голосов
/ 15 ноября 2010

Насколько я знаю, это невозможно: вот почему был создан Downloadify.

Вы можете попробовать связать с data:URL, содержащим данные CSV, но возникнут проблемы с кроссбраузерностью.

2 голосов
/ 01 октября 2014

Самое комплексное решение, с которым я столкнулся, - это использование FileSaver.js , которое решает многие потенциальные проблемы с кросс-браузерными операциями с помощью откатов.

Оно использует объект Blobкак и другие авторы, создатель даже создает полифилл Blob.js на тот случай, если вам потребуется поддержка версий браузера, которые не поддерживают Blob

2 голосов
/ 25 апреля 2013

Если у ваших пользователей установлены новейшие браузеры, вам может помочь новый объект Blob.

На основе приведенного здесь примера https://developer.mozilla.org/en/docs/DOM/Blob («Пример использования конструктора BLOB-объектов») вы можете сделать что-то вроде следующего:

var typedArray = "123,abc,456"; //your csv as a string
var blob = new Blob([typedArray], {type: "text/csv"});
var url = URL.createObjectURL(blob);
var a = document.querySelector("#linktocsv"); // the id of the <a> element where you will render the download link
a.href = url;
a.download = "file.csv";
0 голосов
/ 19 июня 2013

HTML:

<a href="javascript:onDownload();">Download</a>

JavaScript:

function onDownload() {
    document.location = 'data:Application/octet-stream,' +
                         encodeURIComponent(dataToDownload);
}

Взято из Как загрузить данные в виде файла из JavaScript

...