2016-06-07 13 views
1

Ich möchte einen benutzerdefinierten Download (JavaScript-generierte JSON-Datei) von einem SVG-Element erstellen (in my application Schnittstelle ist in SVG). Während ich es für einfaches HTML (vide Force download of 'data:text/plain' URL) tun kann, funktioniert es nicht für SVG.Link zur generierten Download-Datei von SVG

Ein Beispiel (https://jsfiddle.net/stared/qzn7Ldme/):

HTML:

<a id="link_html" download="file.txt">download file (from HTML)</a> 
<br/> 
<svg height="100" width="300"> 
    <a id="link_svg" download="file.txt"> 
    <text x="0" y="50">download file (from SVG)</text> 
    </a> 
</svg> 

JS:

var conent = "This is the file content."; 
var header = "data:text/plain;charset=utf-8," 
var payload = header + encodeURIComponent(conent); 

// works 
d3.select("#link_html").on("click", function() { 
    this.href = payload; 
}); 

// does not work as intended 
d3.select("#link_svg").on("click", function() { 
    //// line below does nothing: 
    // this["xlink:href"] = payload; 

    // opens file in the same window, not as a downloaded file! 
    d3.select("#link_svg").attr("xlink:href", payload); 
}); 

Wenn es darauf ankommt, verwende ich D3.js (3.x).

Gibt es eine bekannte Lösung?

+0

Wie ich jetzt sehe, kann die Verwendung von 'Blob' und' createObjectURL' eine Lösung sein - vide [Blob createObjectURL download funktioniert nicht in Firefox (funktioniert aber beim Debuggen)] (http://stackoverflow.com/questions/30694453/blob- createobjecturl-download-nicht-arbeiten-in-firefox-aber-funktioniert-wenn-Debuggen). –

Antwort

0

I @ Fraser Antwort kopiert, aber verwendet FileSaver.js macht dies eine einfache Aufgabe:

var content = "This is the file content."; 
 
var blob = new Blob([content]); 
 

 
d3.select("#link_svg").on("click", function() { 
 
    saveAs(blob, "file.txt"); 
 
});
<script src="https://cdn.rawgit.com/eligrey/FileSaver.js/master/FileSaver.min.js"></script> 
 
<script src="https://d3js.org/d3.v3.js"></script> 
 

 
<svg height="100" width="300"> 
 
    <a id="link_svg"> 
 
    <text x="0" y="50">download file (from SVG)</text> 
 
    </a> 
 
</svg>

+0

Funktioniert einwandfrei. In jedem Fall - ist "Header" wichtig? Mit '{type: 'text/plain; charset = utf-8'}' funktioniert es auch gut (und es ist in den Beispielen dieser Bibliothek - https://github.com/eligrey/FileSaver.js/). –

+0

Der Typ sollte nicht so wichtig sein, da der Typ nur verwendet wird, um dem Browser zu helfen, den Typ der empfangenen Datei zu verstehen – Endless

0

könnten Sie Daten ändern:

data:application/octet-stream 

Download zu erzwingen. Aber download Tag ist es für HTML nicht für SVG Markup. Sie können filename.ext also nicht vor dem Download zuweisen.

<a id="link_html" download="file.txt">download file (from HTML)</a> 
<br/> 
<svg height="100" width="300"> 
    <a id="link_svg" download="file.txt" xlink:href=""> 
    <text x="0" y="50">download file (from SVG)</text> 
    </a> 
</svg> 

<script> 
     var conent = "This is the file content."; 
     var header = 'data:application/octet-stream;charset=utf-8,' 
     var payload = header + encodeURIComponent(conent); 

     // works 
     d3.select("#link_html").on("click", function() { 
      this.href = payload; 
     }); 

     d3.select("#link_svg").attr("xlink:href", payload) 
</script> 

brauchen eine Dienstprogrammfunktion, das zu tun. Werfen Sie einen Blick here .-

+0

zur nächsten Version der SVG-Spezifikation hinzugefügt wird. Nachdem ich geklickt habe, bekomme ich: '{" error ": "Bitte verwenden Sie die POST-Anfrage"} 'mit Chrome (aber ein korrekter Download-Dialog für Firefox). –

+0

Ja, es ist jsfidlle Rahmen. Es funktioniert auf einer HTML-Datei.- – Klaujesi

1

Sie können einfach eine Dienstprogrammfunktion verwenden, um einen Link zu erstellen, der sich wie gewünscht verhält. z.B.

SVG

<svg height="100" width="300"> 
    <a id="link_svg" download="file.txt"> 
    <text x="0" y="50">download file (from SVG)</text> 
    </a> 
</svg> 

JS

var content = "This is the file content."; 

d3.select("#link_svg").on("click", function() { 
    downloadFile("file.txt", content); 
}); 

var downloadFile = function(filename, content) { 
    var blob = new Blob([content]); 
    var event = new MouseEvent('click', { 
    'view': window, 
    'bubbles': true, 
    'cancelable': true 
    }); 
    var a = document.createElement("a"); 
    a.download = filename; 
    a.href = URL.createObjectURL(blob); 
    a.dispatchEvent(event); 
}; 
+0

Ich habe es hochgeladen: https://jsfiddle.net/stared/f8sxa95f/. Funktioniert in Chrome, nicht in Firefox ('TypeError: Nicht genug Argumente für Event.initEvent.'). –

+0

Als ich das in deiner Geige probierte, ist der Dateiinhalt einfach falsch ... – Endless

+0

@Endless - Ah ja mein Schlechter, siehe den bearbeiteten Code. – Fraser

Verwandte Themen