关于HTML导出word报告的问题(地图、图表)

关于HTML导出word报告的问题(地图、图表)

前提

产品上一个需求,就是做一个分析报告,报告里包括生成的(ol)地图,(echarts)图表,(table)表格和问题描述等。。

用到的组件:
"ol": "^6.8.1",
"ol-ext": "^3.2.6",
"html-docx-js": "^0.3.1",
"html2canvas": "^1.3.2",
"element-ui": "^2.15.6",

问题

  1. 其中问题最少的就是图表了,基本上只要能把canvas转图片就好了
  2. table的问题就是使用组件的话导出会有大小无法控制的问题,一直都是以表格内容的大小撑开,最后还是先用原生的table去写一个,用Css去控制大小和样式,理论上应该用组件也能控制width:100%,但是就是不生效。。
  3. 最后就是ol地图的问题了,ol的问题是导出的地图包括三种点图、热力图和聚合图,导出的地图也是几种的任意组合,总的来说由于它们是分别的图层叠加,就说会有底图层,绘制的面或线层,点图标记层,热力图分布层,聚合图分布层,如果直接用Canvas去获取转图片,就会出现很多张分裂的图层图片,可能还会有底层地图块,点标记图片等。

解决

/* 转换图片为 base64 (todo: 有可能因跨域报错) */
convertImagesToBase64(contentDocument) {
   // 找到所有的图片
   let imgs = contentDocument.querySelectorAll("img");
   // 图片转换用
   let canvas = document.createElement("canvas");
   let ctx = canvas.getContext("2d");
   imgs.forEach((img, i) => {
       if (img.src.startsWith("data:image")) return;
       //过滤多余的地图底层瓦片图片和标记图片,如你的报告里有小图片,慎用
       if(img.width<200){
           return
       }
       // img表现尺寸
       let realWidth = parseInt(img.width) - 100;
       let realHeight = parseInt(img.height);
       // 清空画布并调整为 img 的大小
       ctx.clearRect(0, 0, canvas.width, canvas.height);
       canvas.width = realWidth;
       canvas.height = realHeight;
       // 画图片到画布
       ctx.drawImage(
           img,
           0,
           0,
           img.width,
           img.height,
           0,
           0,
           realWidth,
           realHeight
       );
       // ctx.drawImage(img, 0, 0, 400, 200);
       // 画布转为 base64
       let dataURL = canvas.toDataURL();
       img.setAttribute("src", dataURL);
   });
   canvas.remove();
},
/* 转换canvas为img */
convertChartsToBase64(contentDocument) {
   // 找到所有的地图 (ol)进行图层合并转出
   //.ra_map是自行封装的地图组件标记样式,需要更换
   let canvases = contentDocument.querySelectorAll(".ra_map");  
   canvases.forEach((item,i)=>{
       let target = item.getAttribute('id')
       //获取所有地图组件下的图层,进行合并
       let list = document.getElementById(target).querySelectorAll("canvas")
       let imgDom = document.createElement('img')
       let canvas = document.createElement("canvas");
       let ctx = canvas.getContext("2d");
       //保持原有的显示大小,否则可能会变化
       canvas.width = 706;
       canvas.height = 500;
       if(list.length){
           let image = new Image();
           image.src = list[0].toDataURL("image/png");
           // image.crossOrigin = 'Anonymous';
           list.forEach((res,idx)=>{
               ctx.drawImage(image , 0 , 0 , 706 , 500);
               let img = new Image();
               img.src = res.toDataURL("image/png");
               // img.crossOrigin = 'Anonymous';
               img.onload = function(){
                   ctx.drawImage(img , 0 , 0 , 706 , 500);
                   let base64 = canvas.toDataURL("image/png");  //"image/png" 这里注意一下
                   imgDom.setAttribute('src' , base64);
               }
           })
           imgDom.style.width = '100%'
           //width的设置为导出成word后的图片大小设定,1px为0.04cm,不设定为原尺寸
           imgDom.width = parseInt(canvas.style.width.replace('px','')) - 86 || 620;
           item.parentNode.replaceChild(imgDom, item);
       }
       canvas.remove();
   })
   // 找到所有的图表 (echart)
   let charts = contentDocument.querySelectorAll("canvas");
   //遍历图表,转换为 base64 静态图片
   charts.forEach((chart, i) => {
       let img = new Image();
       img.src = chart.toDataURL("image/png");
       img.style.width = '100%'
       img.width = parseInt(chart.style.width.replace('px','')) - 86 || 620;
       chart.parentNode.replaceChild(img, chart);
   });
},

ol也有它自己的导出图片方法

参考:导出图片
获取地图层的方式是:querySelectorAll(’.ol-layer canvas, canvas.ol-layer’)

原项目还有一个地图导出问题

使用的html2canvas导出地图图片。问题:
1.它无法保存热力图
2.导出图片偏移,无法校准,查了一下是跟样式translate有关,但是ol里面都是这种样式,就算用offset和x,y去重置0都解决不了,还是官方导出较为实在

html2canvas(document.getElementById(this.mapOption.target), {useCORS: true}).then(
 (canvas) => {
   canvas.toBlob(function (blob) {
     saveAs(blob, 'map.png');
   });
 });

总结

希望本记录能帮助遇到同样问题的你!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值