HTML DOCX

html-docx-js

Demo with TinyMCE v3.5
This is a very small library that is capable of converting HTML documents to DOCX format thatis used by Microsoft Word 2007 and onward. It manages to perform the conversion in the browser byusing a feature called 'altchunks'. In a nutshell, it allows embedding content in a different markuplanguage. We are using MHT document to ship the embedded content to Word as it allows to handle images.After Word opens such file, it converts the external content to Word Processing ML (this
is how the markup language of DOCX files is called) and replaces the reference.

Altchunks were not supported by Microsoft Word for Mac 2008 and are not supported by LibreOffice and Google Docs.

Download Link:

https://github.com/evidenceprime/html-docx-js

Demo:

http://evidenceprime.github.io/html-docx-js/

Uses TinyMCE Editor

PS :
It keeps showing message for "This domain is not registered with Tiny Cloud. Please see the quick start guide or create an account."
To have a stand alone verson, use TinyMCE version 3.0.4.1
Check TinyMCE Editor with PHP

Sample Code

sample.php ( save it in html-docx-js-master/test/)

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>HTML-DOCX test</title>
  <!--<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/4/tinymce.min.js"></script>-->
  <script src="http://<your-server>/tinyMCE/v3_5/tinymce_3.5.12/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
  <script src="vendor/FileSaver.js"></script>
  <script src="../dist/html-docx.js"></script>
</head>
<body>
Demo edited from downloaded <a href="https://github.com/evidenceprime/html-docx-js" target="_blank">htmldocx git</a>
  <p>Enter/paste your document here:</p>
  <textarea id="content" cols="60" rows="10">
    <p>We all live in a yellow submarine, yellow submarine, yellow submarine, yellow submarine</p>
    <p>Images can also be exported if you source them as base64 DATA URI.</p>
    <img src="cat.jpg">
  </textarea>
  <div class="page-orientation">
    <span>Page orientation:</span>
    <label><input type="radio" name="orientation" value="portrait" checked>Portrait</label>
    <label><input type="radio" name="orientation" value="landscape">Landscape</label>
  </div>
  <button id="convert">Convert</button>
  <div id="download-area"></div>

  <script>
    /* tinymce.init({
      selector: '#content',
      plugins: [
        "advlist autolink lists link image charmap print preview anchor",
        "searchreplace visualblocks code fullscreen fullpage",
        "insertdatetime media table contextmenu paste"
      ],
      toolbar: "insertfile undo redo | styleselect | bold italic | " +
        "alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | " +
        "link image"
    }); */
    tinyMCE.init({
        // General options
        selector: '#content',
        mode : "textareas",
        theme : "advanced",
        plugins : "paste,autolink,lists,pagebreak,style,layer,table,save,advhr,advimage," +
                    "advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace," +
                    "print,contextmenu,directionality,fullscreen,noneditable,visualchars,nonbreaking," +
                    "xhtmlxtras,template,wordcount,advlist,visualblocks",

        // Theme options
        theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak,restoredraft,visualblocks",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "left",
        theme_advanced_statusbar_location : "bottom",
        theme_advanced_resizing : true,
        add_unload_trigger: false,

        theme_advanced_default_font_size : '10pt',
        theme_advanced_default_font_family : 'Verdana',
        theme_advanced_fonts : "Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats",
        theme_advanced_font_sizes : '8pt,9pt,10pt,11pt,12pt,14pt,16pt,18pt,20pt,22pt,24pt,28pt,36pt',
        paste_retain_style_properties: 'font-size,font-family,color',
        paste_remove_styles_if_webkit: false,

        powerpaste_word_import: 'merge',
        powerpaste_html_import: 'clean',
        powerpaste_allow_local_images: false,

        // Example content CSS (should be your site CSS)
        // content_css : "css/content.css",

        // Drop lists for link/image/media/template dialogs
        template_external_list_url : "lists/template_list.js",
        external_link_list_url : "lists/link_list.js",
        external_image_list_url : "lists/image_list.js",
        media_external_list_url : "lists/media_list.js",

        // Style formats
        style_formats : [
            {title : 'Bold text', inline : 'b'},
            {title : 'Red text', inline : 'span', styles : {color : '#ff0000'}},
            {title : 'Red header', block : 'h1', styles : {color : '#ff0000'}},
            {title : 'Example 1', inline : 'span', classes : 'example1'},
            {title : 'Example 2', inline : 'span', classes : 'example2'},
            {title : 'Table styles'},
            {title : 'Table row 1', selector : 'tr', classes : 'tablerow1'}
        ],

        // Replace values for the template plugin
        template_replace_values : {
            username : "Some User",
            staffid : "991234"
        }
    });
    document.getElementById('convert').addEventListener('click', function(e) {
      e.preventDefault();
      convertImagesToBase64()
      // for demo purposes only we are using below workaround with getDoc() and manual
      // HTML string preparation instead of simple calling the .getContent(). Becasue
      // .getContent() returns HTML string of the original document and not a modified
      // one whereas getDoc() returns realtime document - exactly what we need.
      var contentDocument = tinymce.get('content').getDoc();
      var content = '<!DOCTYPE html>' + contentDocument.documentElement.outerHTML;
      var orientation = document.querySelector('.page-orientation input:checked').value;
      var converted = htmlDocx.asBlob(content, {orientation: orientation});

      saveAs(converted, 'test.docx');

      var link = document.createElement('a');
      link.href = URL.createObjectURL(converted);
      link.download = 'document.docx';
      link.appendChild(
        document.createTextNode('Click here if your download has not started automatically'));
      var downloadArea = document.getElementById('download-area');
      downloadArea.innerHTML = '';
      downloadArea.appendChild(link);
    });

    function convertImagesToBase64 () {
      contentDocument = tinymce.get('content').getDoc();
      var regularImages = contentDocument.querySelectorAll("img");
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      [].forEach.call(regularImages, function (imgElement) {
        // preparing canvas for drawing
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        canvas.width = imgElement.width;
        canvas.height = imgElement.height;

        ctx.drawImage(imgElement, 0, 0);
        // by default toDataURL() produces png image, but you can also export to jpeg
        // checkout function's documentation for more details
        var dataURL = canvas.toDataURL();
        imgElement.setAttribute('src', dataURL);
      })
      canvas.remove();
    }
  </script>
</body>
</html>

Test

<your-server-/html-docx-js-master/test/sample2.php

Compatibility

This library should work on any modern browser that supports Blobs (either natively or via
Blob.js). It was tested on Google Chrome 36, Safari 7 and
Internet Explorer 10.

It also works on Node.js (tested on v0.10.12) using Buffer instead of Blob.

Images Support

This library supports only inlined base64 images (sourced via DATA URI). But it is easy to convert a
regular image (sourced from static folder) on the fly. If you need an example of such conversion you can checkout a demo page source (see function convertImagesToBase64).

Usage and demo

Very minimal demo is available as test/sample.html in the repository and
online. Please note that saving
files on Safari is a little bit convoluted and the only reliable method seems to be falling back
to a Flash-based approach (such as Downloadify).
Our demo does not include this workaround to keep things simple, so it will not work on Safari at
this point of time.

You can also find a sample for using it in Node.js environment
here.

To generate DOCX, simply pass a HTML document (as string) to asBlob method to receive Blob (or Buffer)
containing the output file.

var converted = htmlDocx.asBlob(content);
saveAs(converted, 'test.docx');

asBlob can take additional options for controlling page setup for the document:

  • orientation: landscape or portrait (default)
  • margins: map of margin sizes (expressed in twentieths of point, see
    WordprocessingML documentation for details):

    • top: number (default: 1440, i.e. 2.54 cm)
    • right: number (default: 1440)
    • bottom: number (default: 1440)
    • left: number (default: 1440)
    • header: number (default: 720)
    • footer: number (default: 720)
    • gutter: number (default: 0)

For example:

var converted = htmlDocx.asBlob(content, {orientation: 'landscape', margins: {top: 720}});
saveAs(converted, 'test.docx');

IMPORTANT: please pass a complete, valid HTML (including DOCTYPE, html and body tags).
This may be less convenient, but gives you possibility of including CSS rules in style tags.

html-docx-js is distributed as 'standalone' Browserify module (UMD). You can require it as
html-docx. If no module loader is available, it will register itself as window.htmlDocx.
See test/sample.html for details.

License

Copyright (c) 2015 Evidence Prime, Inc.
See the LICENSE file for license rights and limitations (MIT).