UNPKG

html-doc-js

Version:
128 lines (123 loc) 3.99 kB
import saveAs from 'file-saver' import html2canvas from 'html2canvas' import wordexport from './wordexport' class App { constructor(wordDom, _config = {}) { const defaultConfig = { document: document, addStyle: true, fileName: '', maxWidth: 624, toImg: '', success() {} } this.config = {} this.dom = wordDom this.c_dom = wordDom.cloneNode(true) this.config = { ...defaultConfig, ..._config } } async init() { // 将所有样式转换为行内样式 this.config.addStyle && this.sheetToSelf(this.c_dom) // 将所有图片转化为base64 await this.sheetToImg() // 将带有对应class名字dom转化为图片 await this.domToCanvas() } async sheetToImg() { const img_doms = this.dom.querySelectorAll('img') const c_img_doms = this.c_dom.querySelectorAll('img') for (let i = 0; i < img_doms.length; i++) { c_img_doms[i].src = await this.toBase64(img_doms[i]) this.imgStyleReset(c_img_doms[i], img_doms[i]) } } async domToCanvas() { const str = this.config.toImg if (!str.length) { return } const canvas_doms = this.dom.querySelectorAll(str) const canvas_dom_clone = this.c_dom.querySelectorAll(str) for (let i = 0; i < canvas_doms.length; i++) { const src = await this.toBase64(canvas_doms[i]) const img = new Image() img.src = src this.imgStyleReset(img, canvas_doms[i]) canvas_dom_clone[i].innerHTML = '' canvas_dom_clone[i].appendChild(img) } } exportWord() { const wordBlob = wordexport(this.c_dom) if (this.config.fileName) { saveAs(wordBlob, this.config.fileName + '.doc') } this.config.success(wordBlob, this.c_dom) } sheetToSelf(dom) { const sheets = this.config.document.styleSheets const $dom = dom function cssTextToJSON(cssText) { const arr = cssText.split(';') arr.splice(arr.length - 1, 1) const obj = {} arr.forEach((item) => { const attrName = item.split(':')[0] obj[attrName.replace(/ /g, '')] = item.split(':').map((i, index) => (index ? i : '')).join('') }) return obj } for (let i = 0, l = sheets.length; i < l; i++) { try { sheets[i].rules || sheets[i].cssRules } catch (e) { console.warn("Can't read the css rules of: " + sheets[i].href, e) continue } const { rules, cssRules } = sheets[i] const rulesArry = Array.from(rules || cssRules || []) rulesArry.forEach((rule) => { const { selectorText, style } = rule if (selectorText !== '*') { try { const select = $dom.querySelectorAll(selectorText) select.forEach((dom) => { if (dom.style.cssText) { const oldCssText = cssTextToJSON(dom.style.cssText) const newCssText = cssTextToJSON(style.cssText) for (const i in newCssText) { oldCssText[i] = newCssText[i] } for (const i in oldCssText) { dom.style[i] = oldCssText[i] } } else { dom.style.cssText = style.cssText } }) } catch (e) { console.log('转换成行内样式失败', e) } } }) } } imgStyleReset(dom, coverDom) { const { maxWidth } = this.config const width = Math.min(coverDom.clientWidth, maxWidth) const height = coverDom.clientHeight * width / coverDom.clientWidth dom.width = width dom.height = height return dom } toBase64(element) { return new Promise((resolve) => { html2canvas(element).then((canvas) => { const data = canvas.toDataURL('image/jpeg', 1.0) resolve(data) }) }) } } export default App