/*
* HTML内容生成docx文档(基于:https://github.com/evidenceprime/html-docx-js)
* 江鸿宾(QQ33080907)
* 最近修改:2020.12.28
* 本插件只用于作者参与的项目,未经许可请勿转载
*/
/* global htmlDocx, saveAs, canvg */
(function ($) {
$.fn.html2docx = function (filename) {
if ($(this).length) {
filename = filename || $('title').text() || '未命名'
var ImageMaxWidth = 620
var imgscount = 0
var markup = null
var $this = $(this).first()
var svgs = $this.find('svg')
if (typeof layer !== 'undefined') { layer.msg('正在生成,请稍候...', { icon: 16, time: 0, shade: [0.1, '#000'] }) }
else if (typeof AMUI === 'object') { $('#btn-word').prop('disabled', true).find('i').attr('class', 'am-icon-circle-o-notch am-icon-spin') }
else { $('#btn-word').prop('disabled', true).data('value', $('#btn-word').val()).val('请稍候...') }
// 装载基础脚本
var deferreds = []
if (typeof saveAs === 'undefined') { deferreds.push($.ajax('/Scripts/FileSaver.min.js', { dataType: 'script', cache: true })) }
if (typeof htmlDocx === 'undefined') { deferreds.push($.ajax('/Scripts/html-docx.js', { dataType: 'script', cache: true })) }
if (svgs.length && typeof canvg === 'undefined') { deferreds.push($.ajax('/Scripts/canvg/umd.js', { dataType: 'script', cache: true })) }
$.when.apply(null, deferreds).done(makedocx0)
}
return this
// 处理svg元素,由于异步所以分离
function makedocx0() {
if (svgs.length) {
var deferreds = []
svgs.each(function () {
var svg = $(this)
var w = Math.min(svg.width(), ImageMaxWidth)
var h = svg.height() * (w / svg.width())
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
deferreds.push(
canvg.Canvg.from(ctx, svg.prop('outerHTML')).then(function (v) {
v.resize(w, h)
v.render().then(function () {
var url = canvas.toDataURL('image/png')
svg.closest('div.chart').replaceWith('')
canvas.remove()
})
})
)
})
$.when.apply(null, deferreds).done(makedocx1)
} else {
makedocx1()
}
}
// 生成docx:处理
function makedocx1() {
// 克隆
markup = $this.clone()
// 移除某些节点
markup.find('iframe,embed,style,input[type="hidden"],.no-word').remove()
// 清除:注释、回车、标签之间的空格
var tag = markup.prop('tagName').toLowerCase()
var html = markup.html().replace(//g, '').replace(/
/g, '').replace(/\n/g, '').replace(/>\s+<')
markup = $('<' + tag + '>' + html + '' + tag + '>')
// 处理图片
var imgs = markup.find('img')
imgscount = imgs.length
if (imgscount === 0) { makedocx2() }
else {
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
imgs.each(function () {
var $img = $(this)
var src = $img.attr('src')
// 原来的对应图片
var img = $this.find('img[src="' + src + '"]').get(0)
// 已经是base64编码的图片不再处理
if (src.indexOf('data:') === 0) { makedocx2() }
else if (img) {
var w = Math.min(img.width, ImageMaxWidth)
if (w <= 16) {
// 小于等于16的图片不处理
$img.remove()
makedocx2()
} else {
var h = img.height * (w / img.width)
var a = document.createElement('a')
var dataURL = ''
a.href = src
// 同源
if (a.host === window.location.host) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
canvas.width = w
canvas.height = h
ctx.drawImage(img, 0, 0, w, h)
dataURL = canvas.toDataURL()
$img.attr('src', dataURL).removeAttr('width')
makedocx2()
} else {
// 外站
// 获取base64
var url = 'https://api.psy.com.cn/request/?url=' + src + '&dataurl=1'
$.ajax({
url: url,
success: function (dataURL) {
$img.attr('src', dataURL).attr('width', w).attr('height', h)
makedocx2()
},
error: function () {
$img.remove()
makedocx2()
}
})
}
a.remove()
}
} else {
// 图片没有加载到的不处理
$img.remove()
makedocx2()
}
})
canvas.remove()
}
}
// 生成docx:生成
function makedocx2() {
if (imgscount > 1) { imgscount-- }
else {
// 处理Echarts
markup.find('div.chart[_echarts_instance_]').has('canvas,svg').each(function () {
var id = $(this).attr('id')
var $old = $this.find('#' + id)
var option = $old.data('option')
var theme = $old.data('theme')
var width = $old.width()
var height = $old.height()
// 克隆的Echarts与已有的冲突,所以新建DOM,重新绘制
if (option) {
if (typeof (option) === 'string') { option = JSON.parse(option) }
// epqa量表象限图宽度固定
var $new = $('