|
|
@@ -84,6 +84,118 @@ function getBodyFilters(filters) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+function beforeItemExportImage(itemEl) {
|
|
|
+ let classListBackup = []; // 样式表备份
|
|
|
+ let tableStyle = {}; // table样式备份
|
|
|
+ /*
|
|
|
+ * a.因为部分样式(transition)在html2canvas的表达器中会出现渲染问题,所以需要在截图前将样式暂时移除
|
|
|
+ * b.发现svg元素样式不能继承,且编辑图标理应不显示,将其暂时隐藏
|
|
|
+ * c.隐藏工具栏按钮
|
|
|
+ * d. 处理表格中因为动画、svg造成导出图片样式错误问题
|
|
|
+ */
|
|
|
+ for(let i = 0; i < itemEl.classList.length; i++) {
|
|
|
+ classListBackup.push(itemEl.classList[i]);
|
|
|
+ }
|
|
|
+ // a
|
|
|
+ classListBackup.forEach(c => {
|
|
|
+ itemEl.classList.remove(c);
|
|
|
+ });
|
|
|
+ // b
|
|
|
+ itemEl.querySelector('.chart-title .tools').style.display = 'none';
|
|
|
+ // c
|
|
|
+ itemEl.querySelector('.chart-tools').style.display = 'none';
|
|
|
+
|
|
|
+ // d
|
|
|
+ let tableEl = itemEl.querySelector('.table-view');
|
|
|
+ if(tableEl) {
|
|
|
+ tableEl.querySelector('.ant-table-header').style.marginRight = '0';
|
|
|
+ let svgs = tableEl.querySelectorAll('svg');
|
|
|
+ let trs = tableEl.querySelectorAll('tr');
|
|
|
+ let tds = tableEl.querySelectorAll('td');
|
|
|
+ let paginationActiveItem = tableEl.querySelectorAll('.ant-pagination-item-active')[0];
|
|
|
+ let paginationActiveItemText = paginationActiveItem.children[0];
|
|
|
+
|
|
|
+ for(let x = 0; x < svgs.length; x++) {
|
|
|
+ if(x === 1) {
|
|
|
+ // 第二个svg是鼠标放上去才显示的,不需要处理
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ svgs[x].setAttribute('width', '12px');
|
|
|
+ svgs[x].setAttribute('height', '12px');
|
|
|
+ svgs[x].setAttribute('fill', '#ccc');
|
|
|
+ }
|
|
|
+ for(let l = 0; l < trs.length; l++) {
|
|
|
+ trs[l].style['transition'] = 'all 0s';
|
|
|
+ trs[l].style['-webkit-transition'] = 'all 0s';
|
|
|
+ }
|
|
|
+ for(let m = 0; m < tds.length; m++) {
|
|
|
+ tds[m].style['transition'] = 'all 0s';
|
|
|
+ tds[m].style['-webkit-transition'] = 'all 0s';
|
|
|
+ }
|
|
|
+ paginationActiveItem.style.width = paginationActiveItem.getBoundingClientRect().width + 'px';
|
|
|
+ paginationActiveItemText.style.position = 'absolute';
|
|
|
+
|
|
|
+ tableEl.querySelector('.ant-table-body').getAttribute('style').split(';').forEach(x => {
|
|
|
+ if(x) {
|
|
|
+ let arr = x.split(':');
|
|
|
+ tableStyle[arr[0]] = arr[1];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ let str = '';
|
|
|
+ for(let k in tableStyle) {
|
|
|
+ if(k === 'overflow') {
|
|
|
+ str += k + ':hidden !important;';
|
|
|
+ }else {
|
|
|
+ str += k + ':' + tableStyle[k] + ';';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tableEl.querySelector('.ant-table-body').setAttribute('style', str);
|
|
|
+ }
|
|
|
+ return { classListBackup, tableStyle }
|
|
|
+}
|
|
|
+
|
|
|
+function afterItemExportImage(itemEl, classListBackup, tableStyle) {
|
|
|
+ classListBackup.forEach(c => {
|
|
|
+ itemEl.classList.add(c);
|
|
|
+ });
|
|
|
+ itemEl.querySelector('.chart-title .tools').style.display = '';
|
|
|
+ itemEl.querySelector('.chart-tools').style.display = '';
|
|
|
+ let tableEl = itemEl.querySelector('.table-view');
|
|
|
+ if(tableEl) {
|
|
|
+ tableEl.querySelector('.ant-table-header').style.marginRight = '';
|
|
|
+ let svgs = tableEl.querySelectorAll('svg');
|
|
|
+ let trs = tableEl.querySelectorAll('tr');
|
|
|
+ let tds = tableEl.querySelectorAll('td');
|
|
|
+ let paginationActiveItem = tableEl.querySelectorAll('.ant-pagination-item-active')[0];
|
|
|
+ let paginationActiveItemText = paginationActiveItem.children[0];
|
|
|
+
|
|
|
+ for(let l = 0; l < trs.length; l++) {
|
|
|
+ trs[l].style['transition'] = '';
|
|
|
+ trs[l].style['-webkit-transition'] = '';
|
|
|
+ }
|
|
|
+ for(let m = 0; m < tds.length; m++) {
|
|
|
+ tds[m].style['transition'] = '';
|
|
|
+ tds[m].style['-webkit-transition'] = '';
|
|
|
+ }
|
|
|
+ for(let x = 0; x < svgs.length; x++) {
|
|
|
+ if(x === 1) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ svgs[x].setAttribute('width', '1em');
|
|
|
+ svgs[x].setAttribute('height', '1em');
|
|
|
+ svgs[x].setAttribute('fill', 'currentColor');
|
|
|
+ }
|
|
|
+ paginationActiveItem.style.width = '';
|
|
|
+ paginationActiveItemText.style.position = '';
|
|
|
+
|
|
|
+ let str = '';
|
|
|
+ for(let k in tableStyle) {
|
|
|
+ str += k + ':' + tableStyle[k] + ';';
|
|
|
+ }
|
|
|
+ tableEl.querySelector('.ant-table-body').setAttribute('style', str);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const _maxLayoutW = 12;
|
|
|
|
|
|
export default {
|
|
|
@@ -792,54 +904,13 @@ export default {
|
|
|
let viewcontent = document.querySelector('.dashboard-viewcontent');
|
|
|
let reactGridLayout = viewcontent.children[0];
|
|
|
let itemEls = reactGridLayout.children;
|
|
|
- let classList = reactGridLayout.children[0].classList; // 元素样式列表
|
|
|
- let classListBackup = []; // 样式名备份
|
|
|
+ let classListBackup = []; // 样式表备份
|
|
|
let tableStyles = []; // 表格样式备份
|
|
|
|
|
|
- /*
|
|
|
- * 1.因为部分样式(transition)在html2canvas的表达器中会出现渲染问题,所以需要在截图前将样式暂时移除
|
|
|
- * 2.发现svg元素样式不能继承,且编辑图标理应不显示,将其暂时隐藏
|
|
|
- */
|
|
|
- for(let i = 0; i < classList.length; i++) {
|
|
|
- classListBackup.push(classList[i]);
|
|
|
- }
|
|
|
-
|
|
|
- for(let i = 0; i< itemEls.length;i++) {
|
|
|
- classListBackup.forEach(c => {
|
|
|
- itemEls[i].classList.remove(c);
|
|
|
- itemEls[i].querySelector('.chart-title .tools').style.display = 'none';
|
|
|
- itemEls[i].querySelector('.chart-tools').style.display = 'none';
|
|
|
- });
|
|
|
- let tableEl = itemEls[i].querySelector('.table-view');
|
|
|
- if(tableEl) {
|
|
|
- tableEl.querySelector('.ant-table-header').style.marginRight = '0';
|
|
|
- let svgs = tableEl.querySelectorAll('svg');
|
|
|
- for(let x = 0; x < svgs.length; x++) {
|
|
|
- svgs[x].setAttribute('width', '12px');
|
|
|
- svgs[x].setAttribute('height', '12px');
|
|
|
- svgs[x].setAttribute('fill', '#ccc');
|
|
|
- }
|
|
|
-
|
|
|
- let tableStyle = {
|
|
|
- index: i
|
|
|
- };
|
|
|
- tableEl.querySelector('.ant-table-body').getAttribute('style').split(';').forEach(x => {
|
|
|
- if(x) {
|
|
|
- let arr = x.split(':');
|
|
|
- tableStyle[arr[0]] = arr[1];
|
|
|
- }
|
|
|
- });
|
|
|
- let str = '';
|
|
|
- for(let k in tableStyle) {
|
|
|
- if(k === 'overflow') {
|
|
|
- str += k + ':hidden !important;';
|
|
|
- }else {
|
|
|
- str += k + ':' + tableStyle[k] + ';';
|
|
|
- }
|
|
|
- }
|
|
|
- tableEl.querySelector('.ant-table-body').setAttribute('style', str);
|
|
|
- tableStyles.push(tableStyle);
|
|
|
- }
|
|
|
+ for(let i = 0; i < itemEls.length; i++) {
|
|
|
+ let backup = beforeItemExportImage(itemEls[i]);
|
|
|
+ classListBackup = backup.classListBackup; // 每个itemEl的样式名表是一样的所以可以重复赋值
|
|
|
+ tableStyles.push({ index: i, ...backup.tableStyle });
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
@@ -851,44 +922,16 @@ export default {
|
|
|
|
|
|
let evt = document.createEvent("HTMLEvents");
|
|
|
evt.initEvent("click", true, true);//initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为
|
|
|
- aLink.download = name;
|
|
|
+ aLink.download = (name || '未命名') + '.png';
|
|
|
aLink.href = URL.createObjectURL(blob);
|
|
|
-
|
|
|
- // aLink.dispatchEvent(evt);
|
|
|
- //aLink.click()
|
|
|
aLink.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));//兼容火狐
|
|
|
})
|
|
|
}catch(e) {
|
|
|
message.error('报表图片错误: ' + e);
|
|
|
}finally {
|
|
|
for(let i = 0; i< itemEls.length;i++) {
|
|
|
- classListBackup.forEach(c => {
|
|
|
- itemEls[i].classList.add(c);
|
|
|
- itemEls[i].querySelector('.chart-title .tools').style.display = '';
|
|
|
- itemEls[i].querySelector('.chart-tools').style.display = '';
|
|
|
- });
|
|
|
- let tableEl = itemEls[i].querySelector('.table-view');
|
|
|
- if(tableEl) {
|
|
|
- tableEl.querySelector('.ant-table-header').style.marginRight = '';
|
|
|
- let svgs = tableEl.querySelectorAll('svg');
|
|
|
- for(let x = 0; x < svgs.length; x++) {
|
|
|
- svgs[x].setAttribute('width', '1em');
|
|
|
- svgs[x].setAttribute('height', '1em');
|
|
|
- svgs[x].setAttribute('fill', 'currentColor');
|
|
|
- }
|
|
|
-
|
|
|
- for(let j=tableStyles.length-1;j>=0;j--) {
|
|
|
- let tableStyle = tableStyles[j];
|
|
|
- if(tableStyle.index === i) {
|
|
|
- delete tableStyle.index;
|
|
|
- let str = '';
|
|
|
- for(let k in tableStyle) {
|
|
|
- str += k + ':' + tableStyle[k] + ';';
|
|
|
- }
|
|
|
- tableEl.querySelector('.ant-table-body').setAttribute('style', str);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ let tableStyle = tableStyles.find(t => t.index === i);
|
|
|
+ afterItemExportImage(itemEls[i], classListBackup, tableStyle);
|
|
|
}
|
|
|
yield put({ type: 'setField', name: 'loading', value: false });
|
|
|
}
|
|
|
@@ -897,46 +940,8 @@ export default {
|
|
|
*exportItemToImage(action, { select, put }) {
|
|
|
const { itemEl, item } = action;
|
|
|
const { name } = item;
|
|
|
- let classListBackup = [];
|
|
|
- let tableStyle = {};
|
|
|
-
|
|
|
- let classList = itemEl.classList;
|
|
|
- for(let i = 0; i < classList.length; i++) {
|
|
|
- classListBackup.push(classList[i]);
|
|
|
- }
|
|
|
-
|
|
|
- classListBackup.forEach(c => {
|
|
|
- itemEl.classList.remove(c);
|
|
|
- });
|
|
|
- itemEl.querySelector('.chart-title .tools').style.display = 'none';
|
|
|
- itemEl.querySelector('.chart-tools').style.display = 'none';
|
|
|
-
|
|
|
- let tableEl = itemEl.querySelector('.table-view');
|
|
|
- if(tableEl) {
|
|
|
- tableEl.querySelector('.ant-table-header').style.marginRight = '0';
|
|
|
- let svgs = tableEl.querySelectorAll('svg');
|
|
|
- for(let x = 0; x < svgs.length; x++) {
|
|
|
- svgs[x].setAttribute('width', '12px');
|
|
|
- svgs[x].setAttribute('height', '12px');
|
|
|
- svgs[x].setAttribute('fill', '#ccc');
|
|
|
- }
|
|
|
- tableEl.querySelector('.ant-table-body').getAttribute('style').split(';').forEach(x => {
|
|
|
- if(x) {
|
|
|
- let arr = x.split(':');
|
|
|
- tableStyle[arr[0]] = arr[1];
|
|
|
- }
|
|
|
- });
|
|
|
- let str = '';
|
|
|
- for(let k in tableStyle) {
|
|
|
- if(k === 'overflow') {
|
|
|
- str += k + ':hidden !important;';
|
|
|
- }else {
|
|
|
- str += k + ':' + tableStyle[k] + ';';
|
|
|
- }
|
|
|
- }
|
|
|
- tableEl.querySelector('.ant-table-body').setAttribute('style', str);
|
|
|
- }
|
|
|
|
|
|
+ let { classListBackup, tableStyle } = beforeItemExportImage(itemEl);
|
|
|
try {
|
|
|
yield put({ type: 'setField', name: 'loading', value: false });
|
|
|
|
|
|
@@ -946,36 +951,14 @@ export default {
|
|
|
|
|
|
let evt = document.createEvent("HTMLEvents");
|
|
|
evt.initEvent("click", true, true);//initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为
|
|
|
- aLink.download = name;
|
|
|
+ aLink.download = (name || '未命名') + '.png';
|
|
|
aLink.href = URL.createObjectURL(blob);
|
|
|
-
|
|
|
- // aLink.dispatchEvent(evt);
|
|
|
- //aLink.click()
|
|
|
aLink.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));//兼容火狐
|
|
|
})
|
|
|
}catch(e) {
|
|
|
message.error('导出图片错误:' + e);
|
|
|
}finally {
|
|
|
- classListBackup.forEach(c => {
|
|
|
- itemEl.classList.add(c);
|
|
|
- });
|
|
|
- itemEl.querySelector('.chart-title .tools').style.display = '';
|
|
|
- itemEl.querySelector('.chart-tools').style.display = '';
|
|
|
- let tableEl = itemEl.querySelector('.table-view');
|
|
|
- if(tableEl) {
|
|
|
- tableEl.querySelector('.ant-table-header').style.marginRight = '';
|
|
|
- let svgs = tableEl.querySelectorAll('svg');
|
|
|
- for(let x = 0; x < svgs.length; x++) {
|
|
|
- svgs[x].setAttribute('width', '1em');
|
|
|
- svgs[x].setAttribute('height', '1em');
|
|
|
- svgs[x].setAttribute('fill', 'currentColor');
|
|
|
- }
|
|
|
- let str = '';
|
|
|
- for(let k in tableStyle) {
|
|
|
- str += k + ':' + tableStyle[k] + ';';
|
|
|
- }
|
|
|
- tableEl.querySelector('.ant-table-body').setAttribute('style', str);
|
|
|
- }
|
|
|
+ afterItemExportImage(itemEl, classListBackup, tableStyle);
|
|
|
yield put({ type: 'setField', name: 'loading', value: false });
|
|
|
}
|
|
|
}
|