JavaScript: создание и сохранение файла

У меня есть данные, которые я хочу записать в файл, и откройте диалоговое окно файла, чтобы пользователь мог выбрать, где сохранить файл. Было бы здорово, если бы он работал во всех браузерах, но он должен работать в Chrome. Я хочу сделать это на стороне клиента.

В принципе, я хочу знать, что положить в эту функцию:

saveFile: function(data)
{
}

Если функция принимает данные, пользователь выбирает местоположение для сохранения файла и создает файл в этом месте с этими данными.

Использование HTML тоже хорошо, если это помогает.

Ответ 1

Очень незначительное улучшение кода Awesomeness01 (нет необходимости в привязном теге) с добавлением, предложенным trueimage (поддержка IE):

// Function to download data to a file
function download(data, filename, type) {
    var file = new Blob([data], {type: type});
    if (window.navigator.msSaveOrOpenBlob) // IE10+
        window.navigator.msSaveOrOpenBlob(file, filename);
    else { // Others
        var a = document.createElement("a"),
                url = URL.createObjectURL(file);
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        setTimeout(function() {
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);  
        }, 0); 
    }
}

Протестировано для правильной работы в Chrome, FireFox и IE10.

В Safari данные будут открываться на новой вкладке, и вам придется вручную сохранить этот файл.

Ответ 3

function download(text, name, type) {
  var a = document.getElementById("a");
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}
<a href="" id="a">click here to download your file</a>
<button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>

Ответ 4

Выбор местоположения для сохранения файла перед его созданием невозможен. Но возможно, по крайней мере в Chrome, генерировать файлы, используя только JavaScript. Вот старый пример создания CSV файла. Пользователю будет предложено загрузить его. Это, к сожалению, плохо работает в других браузерах, особенно в IE.

<!DOCTYPE html>
<html>
<head>
    <title>JS CSV</title>
</head>
<body>
    <button id="b">export to CSV</button>
    <script type="text/javascript">
        function exportToCsv() {
            var myCsv = "Col1,Col2,Col3\nval1,val2,val3";

            window.open('data:text/csv;charset=utf-8,' + escape(myCsv));
        }

        var button = document.getElementById('b');
        button.addEventListener('click', exportToCsv);
    </script>
</body>
</html>

Ответ 5

setTimeout("create('Hello world!', 'myfile.txt', 'text/plain')");
function create(text, name, type) {
  var dlbtn = document.getElementById("dlbtn");
  var file = new Blob([text], {type: type});
  dlbtn.href = URL.createObjectURL(file);
  dlbtn.download = name;
}
<a href="javascript:void(0)" id="dlbtn"><button>click here to download your file</button></a>

Ответ 6

Для последнего браузера, такого как Chrome, вы можете использовать File API, как в этом уроке:

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTENT, 5*1024*1024 /*5MB*/, saveFile, errorHandler);

Ответ 7

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

function download(text, name, type) {
  var a = document.getElementById("a");
  a.style.display = "block";
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}
#a { display: none; }
<a href="" id="a" download>click here to download your file</a>
<button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>

Ответ 8

Пробовал это в консоли, и он работает.

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // the blob
window.open(URL.createObjectURL(oMyBlob));

Ответ 9

Вы не можете сделать это исключительно в Javascript. Javascript, работающий в браузерах, еще не имеет разрешения (были предложения) из-за соображений безопасности.

Вместо этого я бы рекомендовал использовать Downloadify:

Небольшая библиотека javascript + Flash, которая позволяет создавать и загружать текстовые файлы без взаимодействия с сервером.

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

Ответ 10

Для Chrome и Firefox я использую метод исключительно JavaScript.

(Мое приложение не может использовать такой пакет, как Blob.js, потому что он обслуживается специальным движком: DSP с сервером WWW, набитым и маленьким для чего-либо вообще.)

function FileSave(sourceText, fileIdentity) {
    var workElement = document.createElement("a");
    if ('download' in workElement) {
        workElement.href = "data:" + 'text/plain' + "charset=utf-8," + escape(sourceText);
        workElement.setAttribute("download", fileIdentity);
        document.body.appendChild(workElement);
        var eventMouse = document.createEvent("MouseEvents");
        eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        workElement.dispatchEvent(eventMouse);
        document.body.removeChild(workElement);
    } else throw 'File saving not supported for this browser';
}

Примечания, оговорки и ласковые слова:

  • У меня был успех с этим кодом как у клиентов Chrome, так и у Firefox, работающих в средах Linux (Maipo) и Windows (7 и 10).
  • Однако, если sourceText больше, чем МБ, Chrome иногда (только иногда) застревает в своей собственной загрузке без указания отказа; До сих пор Firefox не демонстрировал такого поведения. Причиной может быть некоторое ограничение blob в Chrome. Честно говоря, я просто не знаю; если у кого-нибудь есть идеи по исправлению (или, по крайней мере, обнаружению), отправьте сообщение. Если возникает аномалия загрузки, когда браузер Chrome закрыт, он генерирует диагностику, такую ​​как Диагностика браузера Chrome
  • Этот код несовместим с Edge или Internet Explorer; Я не пробовал Opera или Safari.

Ответ 11

Javascript имеет API файловой системы. Если вы можете иметь дело с тем, что функция работает только в Chrome, хорошей отправной точкой будет: http://www.html5rocks.com/en/tutorials/file/filesystem/.

Ответ 12

StreamSaver - это альтернатива для сохранения очень больших файлов без необходимости хранить все данные в памяти.
Фактически он эмулирует все, что требует сервер при сохранении файла, но всю клиентскую часть с обслуживающим работником.

Вы можете либо получить программу записи и вручную записать в нее Uint8Array, либо передать двоичный файл readableStream в поток записи

Существует несколько примеров демонстрации:

  • Как сохранить несколько файлов в формате ZIP
  • передача readableStream, например, из Response или blob.stream() в StreamSaver
  • запись вручную в поток записи при вводе чего-либо
  • или перекодировать видео/аудио

Вот пример в простейшем виде:

const fileStream = streamSaver.createWriteStream('filename.txt')

new Response('StreamSaver is awesome').body
  .pipeTo(fileStream)
  .then(success, error)

Если вы хотите сохранить большой двоичный объект, просто преобразуйте его в readableStream

new Response(blob).body.pipeTo(...) // response hack
blob.stream().pipeTo(...) // feature reference

Ответ 13

function SaveBlobAs(blob,file_name){
if(typeof navigator.msSaveBlob=="function")return navigator.msSaveBlob(blob,file_name);
var saver=document.createElementNS("http://www.w3.org/1999/xhtml","a");
saver.download=file_name;
var blurl=saver.href=URL.createObjectURL(blob),bdy=document.body;
bdy.appendChild(saver);
saver.dispatchEvent(new MouseEvent("click"));
bdy.removeChild(saver);
URL.revokeObjectURL(blurl);
}