2

I have an svg that is generated in a page, I am not bringing it in from an outside source. I want this svg to be downloadable for printing. Is there a way (using client side Javascript) to download a dom node as a text file? I am limited to dojo and d3 libraries for this project.

AdamSpurgin
  • 911
  • 2
  • 8
  • 27
  • Since I haven't had the time to complete my answer, here are links for further information: [File API: Writer, FileSaver Interface](http://www.w3.org/TR/file-writer-api/#the-filesaver-interface), [Sample code of an answer here](http://stackoverflow.com/questions/7160720/create-a-file-using-javascript-in-chrome-on-client-side/7160827#7160827). Note that the neccessary feature aren't implemented in all browsers (e.g. no IE 10) support because they're still a draft. See also here: [Can I use: Fileystem](http://caniuse.com/#feat=filesystem). – ComFreek Jan 31 '13 at 18:33

1 Answers1

4

Assuming the client is using a HTML5 web browser, this can be achieved pretty easily using <a>s download attribute. You will need to simulate a click with a MouseEvent on this element if you want the behaviour to be invoked by some other means, but the node does not have to be appended to the document. I've answered a similar question about this before, but here, set the <a>s href to the svg's file location unless it is created dynamically ‒ in that case you would encode the text describing it to create a data URI.

XML text describing a SVG can be obtained from it's SVGSVGElement node using XMLSerializer.

var serializer = new XMLSerializer();
serializer.serializeToString(svg); // xml string for `svg` (your node)

Please note that any "Save As" dialogue will depend on the client's configuration.

// assuming var `svg` for your SVG node
var a = document.createElement('a'), xml, ev;
a.download = 'my_svg.svg'; // file name
xml = (new XMLSerializer()).serializeToString(svg); // convert node to xml string
a.href = 'data:application/octet-stream;base64,' + btoa(xml); // create data uri
// <a> constructed, simulate mouse click on it
ev = document.createEvent("MouseEvents");
ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(ev);
Community
  • 1
  • 1
Paul S.
  • 58,277
  • 8
  • 106
  • 120
  • The SVG I am trying to make downloadable is not in a file, it is generated in the browser using d3.js. I have no outside file to reference, just a domNode. – AdamSpurgin Jan 31 '13 at 18:22
  • So you want to know how to get the string describing it from the SVGSVGElement? Edited in how to do that too, now. – Paul S. Jan 31 '13 at 18:30
  • @AdamSpurgin also, the data URI doesn't really need to be in base64 as the XML is a string, but safety first! Changing the MIME should be okay, too. I chose _application/octet-stream_ because it should start a download even if the browser doesn't understand a _download_ attribute (although you usually end up with a hash as a file name). – Paul S. Jan 31 '13 at 18:48
  • Is there any way to specify a filename otherwise? From firefox all i get is a hash name, not really an option for me. – AdamSpurgin Feb 02 '13 at 00:52
  • The [MDN page about it](https://developer.mozilla.org/en-US/docs/HTML/Element/a#attr-download) suggests that it might be some same-origin stuff making it break in FireFox? Maybe file a bug on bugzilla. – Paul S. Feb 02 '13 at 01:22