5

I am having trouble exporting the contents of a div into a .docx file. I am using FileSaver.js which can be found here: https://github.com/eligrey/FileSaver.js/.

My JavaScript Function:

function exportNote(){
   var blob = new Blob([document.getElementById('editor').innerHTML], {
      type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8"
   });
   saveAs(blob, "note.docx");
}

I get a download that appears to be a word file but when I open it I get the following error:

The Open XML file note.docx cannot be opened because there are problems with the contents or the file name might contain invalid characters (for example. /).

Details: The file is corrupt and cannot be opened.

For graphical purposes:

enter image description here

The text area is the area I am trying to export into a word document which is under <div id="editor"></div>.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
btald1331
  • 537
  • 3
  • 8
  • 23
  • 1
    You cannot just save a random text string with the extension .docx and expect it to work. OOXML files are ZIP archives, for starters, so the file will immediately be found out to be corrupt since it isn't one. You'll need a library that can write OOXML and finding one is the job for a search engine. – Sami Kuhmonen Apr 12 '16 at 13:43
  • saveAs(blob, "note.doc"); try this one may help you – Zubair sadiq Apr 12 '16 at 14:24

3 Answers3

4

jsfiddle

Html

<div id="main">
 this is content of div
</div>

JavaScript

function downloadInnerHtml(filename, elId) {
 var elHtml = document.getElementById(elId).innerHTML;
 var link = document.createElement('a');
 link.setAttribute('download', filename);   
 link.setAttribute('href', 'data:' + 'text/doc' + ';charset=utf-8,' + encodeURIComponent(elHtml));
 link.click(); 
}
var fileName =  'tags.doc'; // You can use the .txt extension if you want
downloadInnerHtml(fileName, 'main');
Zubair sadiq
  • 500
  • 6
  • 23
  • 1
    Exactly what I was looking for. To download as docx, just change doc to docx. This should be the accepted answer. – Ron Daulagupu May 25 '19 at 12:39
  • 1
    @RonDaulagupu how did this script function with `docx` because when I change extention from `doc` to `docx` and opened file . It shows this message " the file cannot be opened because there are problems with the contents." the `docx` is not working so how did you make it work ? – ZACK_G Jun 20 '19 at 12:18
  • 1
    @ZACK_G I just changed text/doc to text/docx and filename to eg. tags.docx. is your data content corrupted. Check whether you are saving correctly. – Ron Daulagupu Jun 21 '19 at 05:44
  • 1
    @RonDaulagupu I am really grateful for your help but the script export plain text only not html as you can see [jsfiddle](http://jsfiddle.net/talabe/fhazmL06/2/) and I already found a solution on internet the export html text with original fomatting [script](https://www.w3schools.com/code/tryit.asp?filename=G59ZWYISOV4O) but the problem the `doc` file is in `webpage layout` so how can I combine both solution to export html text is original formatting and with portrait orentation and A4 size .Or there is any solution that can do it all ? and thanks for your help . – ZACK_G Jun 21 '19 at 11:32
  • 2
    This was close, but I got the error in Word about corrupted file. It looks like we need some special tags before and after the main content. var preHtml = "Export HTML To Doc"; var postHtml = ""; var html = preHtml+document.getElementById(element).innerHTML+postHtml; Found a working example: https://www.codexworld.com/export-html-to-word-doc-docx-using-javascript/ – Ken Forslund Jul 03 '21 at 14:15
  • 1
    @KenForslund I tried that but the file is still corrupted. – formicini Jul 28 '21 at 10:04
  • Since we know we're really making an html file, have you examined it in notepad to make sure it has the proper pre and post tagging before the main content? I got it to work pretty easily from that URL in my prior answer. If I get time later today, I'll try to collect my code and make a proper answer so you have the whole thing. – Ken Forslund Jul 29 '21 at 15:46
  • This works but for anyone using an external editor library like tinymce (looks like you are) it is loaded in an iframe and you do not have access to the innerHTML. Simply change var elHtml = editorRef.current.getContent(); gives you the HTML content and download the file as usual. – lisen kaci Apr 19 '23 at 17:40
1

There is another solution to this problem using an open source library on github under the MIT license: https://github.com/evidenceprime/html-docx-js.

My solution:

function exportNote(contentId){
   var filename = 'note.html'
   var htmlDoc = document.getElementById(contentId).innerHTML;
   var converted = htmlDocx.asBlob(htmlDoc);
   saveAs(converted, "notes.docx");
}
btald1331
  • 537
  • 3
  • 8
  • 23
1

Since somebody had a problem in the comments, I'm pasting in what I am actively using. The function I pasted here is darn near verbatim from this site: https://www.codexworld.com/export-html-to-word-doc-docx-using-javascript/

So credit to them. The key to this is that saving the contents of a div to a file is not a proper HTML document, and that causes Word to balk. It needs a BODY, HTML and some of that xmlns attributing. This function gets the innerHtml and wraps it with that, before doing the actual save.

Simply call Export2Word() with the name of the element that holds the content you want to save and the filename:

Export2Word('divMyContent','MyFileNameWithoutExtension');

function Export2Word(element, filename = ''){
    var preHtml = "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Export HTML To Doc</title></head><body>";
    var postHtml = "</body></html>";
    
    var content = document.getElementById(element).innerHTML;

    var html = preHtml+content+postHtml;

    var blob = new Blob(['\ufeff', html], {
        type: 'application/msword'
    });
    
    // Specify link url
    var url = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(html);
    
    // Specify file name
    filename = filename?filename+'.docx':'document.docx';
    
    // Create download link element
    var downloadLink = document.createElement("a");

    document.body.appendChild(downloadLink);
    
    if(navigator.msSaveOrOpenBlob ){
        navigator.msSaveOrOpenBlob(blob, filename);
    }else{
        // Create a link to the file
        downloadLink.href = url;
        
        // Setting the file name
        downloadLink.download = filename;
        
        //triggering the function
        downloadLink.click();
    }
    
    document.body.removeChild(downloadLink);
}
Ken Forslund
  • 340
  • 2
  • 9