//---------------------------------------------------------- // Copyright (C) Microsoft Corporation. All rights reserved. // Released under the Microsoft Office Extensible File License // https://raw.github.com/stephen-hardy/docx.js/master/LICENSE.txt //---------------------------------------------------------- function convertContent(input) { 'use strict'; // Convert HTML to WordprocessingML, and vice versa var output, inputDoc, i, j, k, id, doc, inNode, inNodeChild, outNode, outNodeChild, styleAttrNode, pCount = 0, tempStr, tempNode, val; function newXMLnode(name, text) { var el = doc.createElement('w:' + name); if (text) { el.appendChild(doc.createTextNode(text)); } return el; } function newHTMLnode(name, html) { var el = document.createElement(name); el.innerHTML = html || ''; return el; } function color(str) { // Return hex or named color if (str.charAt(0) === '#') { return str.substr(1); } if (str.indexOf('rgb') < 0) { return str; } var values = /rgb\((\d+), (\d+), (\d+)\)/.exec(str), red = +values[1], green = +values[2], blue = +values[3]; return (blue | (green << 8) | (red << 16)).toString(16); } function toXML(str) { return new DOMParser().parseFromString(str.replace(/<[a-zA-Z]*?:/g, '<').replace(/<\/[a-zA-Z]*?:/g, '' + val + ''; } if (inNodeChild.getElementsByTagName('i').length) { val = '' + val + ''; } if (inNodeChild.getElementsByTagName('u').length) { val = '' + val + ''; } if (inNodeChild.getElementsByTagName('strike').length) { val = '' + val + ''; } if (styleAttrNode = inNodeChild.getElementsByTagName('vertAlign')[0]) { if (styleAttrNode.getAttribute('w:val') === 'subscript') { val = '' + val + ''; } if (styleAttrNode.getAttribute('w:val') === 'superscript') { val = '' + val + ''; } } if (styleAttrNode = inNodeChild.getElementsByTagName('sz')[0]) { val = '' + val + ''; } if (styleAttrNode = inNodeChild.getElementsByTagName('highlight')[0]) { val = '' + val + ''; } if (styleAttrNode = inNodeChild.getElementsByTagName('color')[0]) { val = '' + val + ''; } if (styleAttrNode = inNodeChild.getElementsByTagName('blip')[0]) { id = styleAttrNode.getAttribute('r:embed'); tempNode = toXML(input.files['word/_rels/document.xml.rels'].data); k = tempNode.childNodes.length; while (k--) { if (tempNode.childNodes[k].getAttribute('Id') === id) { val = ''; break; } } } tempStr += val; } outNode.innerHTML = tempStr; } } output = output.childNodes; } else if (input.nodeName) { // input is HTML DOM doc = new DOMParser().parseFromString('', 'text/xml') doc.getElementsByTagName('root')[0].appendChild(newXMLnode('body')); output = doc.getElementsByTagName('w:body')[0]; for (i = 0; inNode = input.childNodes[i]; i++) { outNode = output.appendChild(newXMLnode('p')); pCount++; if (inNode.style.textAlign) { outNode.appendChild(newXMLnode('pPr')).appendChild(newXMLnode('jc')).setAttribute('val', inNode.style.textAlign); } if (inNode.nodeName === '#text') { outNode.appendChild(newXMLnode('r')).appendChild(newXMLnode('t', inNode.nodeValue)); } else { for (j = 0; inNodeChild = inNode.childNodes[j]; j++) { outNodeChild = outNode.appendChild(newXMLnode('r')); if (inNodeChild.nodeName !== '#text') { styleAttrNode = outNodeChild.appendChild(newXMLnode('rPr')); tempStr = inNodeChild.outerHTML; if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('b')); } if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('i')); } if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('u')).setAttribute('val', 'single'); } if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('strike')); } if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('vertAlign')).setAttribute('val', 'subscript'); } if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('vertAlign')).setAttribute('val', 'superscript'); } if (tempNode = inNodeChild.nodeName === 'SPAN' ? inNodeChild : inNodeChild.getElementsByTagName('SPAN')[0]) { if (tempNode.style.fontSize) { styleAttrNode.appendChild(newXMLnode('sz')).setAttribute('val', parseInt(tempNode.style.fontSize, 10) * 2); } else if (tempNode.style.backgroundColor) { styleAttrNode.appendChild(newXMLnode('highlight')).setAttribute('val', color(tempNode.style.backgroundColor)); } else if (tempNode.style.color) { styleAttrNode.appendChild(newXMLnode('color')).setAttribute('val', color(tempNode.style.color)); } } } outNodeChild.appendChild(newXMLnode('t', inNodeChild.textContent)); } } } output = { string: new XMLSerializer().serializeToString(output).replace(//g, '').replace(/val=/g, 'w:val='), charSpaceCount: input.textContent.length, charCount: input.textContent.replace(/\s/g, '').length, pCount: pCount }; } return output; } function docx(file) { 'use strict'; // v1.0.1 var result, zip = new JSZip(), zipTime, processTime, docProps, word, content; if (typeof file === 'string') { // Load zipTime = Date.now(); zip = zip.load(file, { base64: true }); result = { zipTime: Date.now() - zipTime }; processTime = Date.now(); //{ Get file info from "docProps/core.xml" s = zip.files['docProps/core.xml'].data; s = s.substr(s.indexOf('') + 12); result.creator = s.substring(0, s.indexOf('')); s = s.substr(s.indexOf('') + 19); result.lastModifiedBy = s.substring(0, s.indexOf('')); s = s.substr(s.indexOf('') + 43); result.created = new Date(s.substring(0, s.indexOf(''))); s = s.substr(s.indexOf('') + 44); result.modified = new Date(s.substring(0, s.indexOf(''))); //} result.DOM = convertContent(zip); result.processTime = Date.now() - processTime; } else { // Save content = convertContent(file.DOM); processTime = Date.now(); sharedStrings = [[], 0]; //{ Fully static zip.file('[Content_Types].xml', ''); zip.folder('_rels').file('.rels', ''); docProps = zip.folder('docProps'); word = zip.folder('word'); word.folder('_rels').file('document.xml.rels', ''); word.folder('theme').file('theme1.xml', ''); word.file('fontTable.xml', ''); word.file('settings.xml', ''); word.file('styles.xml', ''); word.file('stylesWithEffects.xml', ''); word.file('webSettings.xml', ''); //} //{ Not content dependent docProps.file('core.xml', '' + (file.creator || 'DOCX.js') + '' + (file.lastModifiedBy || 'XLSX.js') + '1' + (file.created || new Date()).toISOString() + '' + (file.modified || new Date()).toISOString() + ''); //} //{ Content dependent //{ docProps/app.xml docProps.file('app.xml', '111' + content.charCount + 'DOCX.js01' + content.pCount + 'falseMicrosoft Corporationfalse' + content.charSpaceCount + 'falsefalse1.0'); //} word.file('document.xml', '' + content.string + ''); //} processTime = Date.now() - processTime; zipTime = Date.now(); result = { base64: zip.generate({ compression: 'DEFLATE' }), zipTime: Date.now() - zipTime, processTime: processTime, href: function() { return 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,' + this.base64; } } } return result; }