因为特定场景,想到使用 html2canvas
给Grid导出图片,感觉比导出Excel好使一些,这里忽略了Grid的横向滚动条,遇见的可以作为参考,导出的效果还是不错的
如果直接使用 html2canvas
导出 F.ui.Grid.el 会出现跨域问题,滚动条问题,样式错位问题 等;所以还是采用 Wrapper 或者copy 、shadow 的方式,即复制 F.ui.Grid.el 放到新的div中,再导出;
还有一个问题是滚动条,html2canvas
也会截取滚动条,如果溢出,那导出就看不见了,这里因为数据本身不会出现横向滚动条,而且没有分页,所以隐藏横向滚动条,纵向高度百分百以显示全部;
注意在复制后对 Wrapper 中的Grid进行修饰调整,比如有的列需要改为换行(不然挡上也显示不出来),取消选中的行,删除没用的按钮,等;
新增的容器 Wrapper 元素需要实实在在新增到document.body
中,不能遮挡原始的 Grid 否则会很奇怪,这里使用 translateY
进行偏移,直接偏移一个Grid的高度,就挡不上了,因为没有Y的滚动条,所以看不出来对于前台是无感的;
后来有个需求是增加水印,因为html2canvas
不支持 opacity
所以不能使用 opacity 控制水印,应该使用 canvas
这里找到了一个插件一并放出;
js/**导出图片 */
function outputimg() {
const divElement = document.getElementById('Grid1');
// 创建一个新的div元素,避免滚动条
const screenshotWrapper = document.createElement('div');
screenshotWrapper.style.overflow = 'hidden';
screenshotWrapper.style.height = '100%';
screenshotWrapper.style.width = '100%';
screenshotWrapper.style.transform = `translateY(${divElement.offsetHeight}px)`;//偏移 以不显示
// 创建一个新的div元素,用于容纳截图内容
const screenshotContent = document.createElement('div');
screenshotContent.style.width = '100%';
// 将原始Grid的内容复制到新的div元素中
screenshotContent.innerHTML = divElement.innerHTML;
// 将新的div元素添加到截图容器中
screenshotWrapper.appendChild(screenshotContent);
//复制之后就可以对Wrapper中的Grid进行操作
//解决滚动条的问题 Grid原始的高度直接不要
$(screenshotContent).find(`.f-panel-body`).height(`unset`);
$(screenshotContent).find(`.f-grid-bodyct`).height(`unset`);
//选中的和激活的行样式都删除
$(screenshotContent).find(`.f-grid-row-selected`).removeClass(`f-grid-row-selected`);
$(screenshotContent).find(`.f-state-active`).removeClass(`f-state-active`);
//删除按钮或其他
$(screenshotContent).find(`.btn`).remove();
//这里做了某一列的换行
$(screenshotContent).find(`[data-columnid="MB003"] .f-grid-cell-inner`).css({
"whiteSpace": "normal",
"wordBreak": "break-all"
});
//添加到body中
document.body.appendChild(screenshotWrapper);
//增加水印
new watermark({
text: `${thisusername} ${thisdate}`, //水印内容
render: screenshotContent,
});
// 使用html2canvas进行截图操作
html2canvas(screenshotWrapper, { useCORS: true }).then(canvas => {
// 创建一个新的图片元素
//const image = new Image();
//image.src = canvas.toDataURL('image/png');
// 将图片元素添加到页面中
//document.body.appendChild(image);
const dataURL = canvas.toDataURL('image/png');
// 创建一个虚拟的下载链接
const downloadLink = document.createElement('a');
downloadLink.href = dataURL;
downloadLink.download = '导出图片.png';
// 触发点击事件进行下载
downloadLink.click();
$(screenshotWrapper).remove();
});
}
(function (window) { /** * js水印插件 * 自动在body底部生成一个水印 * auth:zhangdaren * date:20190218 * version: v1.0 * * */ var canvas = null; var setting = { render: document.body, text: "水印测试", //水印内容,将来支持数组和图片 fontSize: "24", //字体大小 color: "#000", //水印字体颜色 opacity: 0.1, //水印透明度 rotate: 20, //水印旋转角度 spaceX: 10, //间隔 spaceY: 10, //间隔 }; var ww; //屏幕宽度 var wh; //屏幕高度 var ctx; function watermark(option) { return new watermark.prototype.init(option); } watermark.prototype = { constructor: watermark, init: function (option) { if (option && Object.keys(option).length > 0) { // setting.text = option.text; setting.fontSize = option.fontSize || setting.fontSize; setting.color = option.color || setting.color; setting.opacity = option.opacity || setting.opacity; setting.rotate = option.rotate || setting.rotate; setting.spaceX = option.spaceX || setting.spaceX; setting.spaceY = option.spaceY || setting.spaceY; setting.render = option.render || setting.render; } ww = setting.render.clientWidth; wh = setting.render.clientHeight; // canvas = document.createElement("canvas"); canvas.style = "position:absolute; z-index:0; width:100%;height:100%;left:0;top:0"; canvas.setAttribute("width", ww); canvas.setAttribute("height", wh); setting.render.append(canvas); ctx = canvas.getContext("2d"); //渲染 watermark.prototype.render(); }, render() { watermark.prototype.clear(); // ctx.font = setting.fontSize + "px Calibri"; ctx.textAlign = 'center'; ctx.textBaseline = 'bottom'; ctx.fillStyle = setting.color; ctx.globalAlpha = setting.opacity; //这里是设置全局的透明度 //获取文本宽高 var txtWidth = ctx.measureText(setting.text).width; //单个文字宽高 var singleTxtHeight = ctx.measureText("鹏").width; //横向数量,这里加2是为了补全一些情况 var columnNum = parseInt(ww / txtWidth + 2); //文字的高度,与旋转的角度有关 var txtHeight = Math.abs(singleTxtHeight * Math.sin(setting.rotate * Math.PI / 180) * setting.text.length); // * setting.text.length; //行数 var rowNum = parseInt(wh / txtHeight); for (var i = 0; i < rowNum; i++) { var y = (txtHeight + setting.spaceY) * i; for (var j = 0; j < columnNum; j++) { var x = (txtWidth + setting.spaceX) * j; //保存上次状态 ctx.save(); //旋转canvas rotateContext(ctx, x, y, -setting.rotate); ctx.fillText(setting.text, x, y); //回到上次状态 //用于重置canvas的旋转 ctx.restore(); } } }, clear() { ctx.clearRect(0, 0, ww, wh); } }; //确保是以(x,y)为中心进行旋转,而不是简单的以画布原点旋转 function rotateContext(ctx, x, y, degree) { ctx.translate(x, y); ctx.rotate(degree * Math.PI / 180); ctx.translate(-x, -y); } function onResize() { //重新获取window宽高 ww = setting.render.clientWidth; wh = setting.render.clientHeight; //重新设置canvas宽高 canvas.setAttribute("width", ww); canvas.setAttribute("height", wh); //重绘 watermark.prototype.clear(); watermark.prototype.render(); } window.onresize = function () { throttle(onResize, window); } //函数节流 function throttle(method, context) { clearTimeout(method.tId); method.tId = setTimeout(function () { method.call(context); }, 500); } window.watermark = watermark; })(window);
本文作者:没想好
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!