<!-- @desc:打印组件  @auth:周兴  @time:2022/11/15 15:24 -->
<template>
  <div >
    <!--    <Button type="primary" @click="printFunc">打印</Button>-->
    <div :id="'print-div'+paperIndex" v-for="(paperItem,paperIndex) in paperPageQuantityList" :key="'paperIndex'+paperIndex" style="display:none;overflow: hidden;">
      <div id="pdf-dom" style="page-break-after: always;position: relative;overflow: hidden;" :class="[paperDirection==='portrait'?'portrait':'landscape']"
           :style="{
               backgroundImage: `url(${$config.imgUrl + backgroundConfig.relativePath})`,
               backgroundPosition:backgroundConfig.position,
               backgroundRepeat:backgroundConfig.repeat,
               backgroundSize:backgroundConfig.size === 'custom'?(backgroundConfig.customSize.width + '% ' +backgroundConfig.customSize.height+'%'):(backgroundConfig.size),
               height:calc10(paperDirection==='portrait'?paperInfo.height:paperInfo.width)+'px',
               width:paperDirection==='portrait'?paperInfo.width+'cm':paperInfo.height+'cm'
             }"
      >
        <loading id='loading' :loading=true :shade="true" :width="width" :height="height"></loading>
        <!--      <div  style="page-break-after: always;position: relative;width: 290mm;height: 210mm;" >-->
        <div v-if="pageFlag" style="position:absolute;right: 2px;bottom: 2px;">第{{ paperIndex +1 }}页/共{{paperPageQuantityList.length }}页</div>
        <!--   常规元素   -->
        <div style="position:absolute;word-break: break-all;" v-for="(item,index) in printBeforeTable.mainList" :key="'printBeforeTable'+index" :style="{  border:item.border?'1px solid #000':'',
                               fontSize: item.fontSize+'px',width:item.width+'px',height:item.height+'px',top:item.top+'px',left:item.left+'px'}">
          <div style="display: flex;width: 100%;height: 100%;" :style="{
                               justifyContent:item.align1,
                               alignItems:item.align2,
                               textDecoration: item.line?'underline':'',
                               fontStyle: item.fontStyle?'italic':'',
                               fontWeight: item.bold?'bold':''
                             }">
            <span v-if="!item.dataSourceKey">{{item.text}}</span>
            <div v-else style="display: flex;height: 100%;width: 100%;" :style="{
                               textDecoration: item.line?'underline':'',
                               fontStyle: item.fontStyle?'italic':'',
                               fontWeight: item.bold?'bold':''
                             }">
              <div style="display: flex;height: 100%;" :style="{borderRight:item.border?'1px solid #000':'',alignItems:item.align2,justifyContent:item.align1,width:item.keyValueScale+'%'}">{{item.text}}</div>
              <div style="display: flex;height: 100%" :style="{alignItems:item.align2,justifyContent:item.align1,width:(100- item.keyValueScale)+'%'}">
                {{ printData[item.dataSourceKey] }}</div>
            </div>
          </div>
        </div>

        <div style="position:absolute;" v-for="(item,index) in paperItem.mainList" :key="'paperItem.mainList'+index" :style="{  border:item.border?'1px solid #000':'',
                               fontSize: item.fontSize+'px',width:item.width+'px',height:item.height+'px',top:item.top+'px',left:item.left+'px'}">
          <div style="display: flex;width: 100%;height: 100%;" :style="{
                               justifyContent:item.align1,
                               alignItems:item.align2,
                               textDecoration: item.line?'underline':'',
                               fontStyle: item.fontStyle?'italic':'',
                               fontWeight: item.bold?'bold':''
                             }">
            <span v-if="!item.dataSourceKey">{{item.text}}</span>
            <div v-else style="display: flex;height: 100%;width: 100%;" :style="{
                               textDecoration: item.line?'underline':'',
                               fontStyle: item.fontStyle?'italic':'',
                               fontWeight: item.bold?'bold':''
                             }">
              <div style="display: flex;height: 100%;" :style="{borderRight:item.border?'1px solid #000':'',alignItems:item.align2,justifyContent:item.align1,width:item.keyValueScale+'%'}">{{item.text}}</div>
              <div style="display: flex;height: 100%" :style="{alignItems:item.align2,justifyContent:item.align1,width:(100- item.keyValueScale)+'%'}">
                {{ printData[item.dataSourceKey] }}</div>
            </div>
          </div>
        </div>
        <!--   图片元素   -->
        <div style="position:absolute;" v-for="(item,index) in printBeforeTable.imgList" :key="'printBeforeTable.imgList'+index" :style="{ width:item.width+'px',height:item.height+'px',top:item.top+'px',left:item.left+'px'}">
<!--          crossorigin='anonymous'-->
          <img  :src="item.path" style="width: 100%;height: 100%;" @load="imgLoadComplate" />
        </div>

        <div style="position:absolute;" v-for="(item,index) in paperItem.imgList" :key="'paperItem.imgList'+index" :style="{ width:item.width+'px',height:item.height+'px',top:item.top+'px',left:item.left+'px'}">
          <img :src="item.path" style="width: 100%;height: 100%;"  @load="imgLoadComplate"/>
        </div>

        <img :src="backgroundConfig.path" v-if="backgroundConfig.path"  style="display: none;"  @load="backgroundImgLoadConplate"/>

        <!--   表格   -->
        <div v-if="printParams.tableInfo" style="position:absolute;" :style="{ width:printParams.tableInfo.width+'px',top:printParams.tableInfo.top+'px',left:printParams.tableInfo.left+'px'}">
          <table border="1" style="width: 100%;border-spacing:0;border-collapse:separate;">
            <tr>
              <td v-for="(item,index) in printParams.tableCol" :key="'printParams.tableCol'+index" style="background: #f2f2f2;" :width="item.width"
                  :style="{

                                fontSize:item.fontSize+'px',
                                height:printParams.tableInfo.height+'px',}">
                <div style="display:flex;width: 100%;height: 100%;" :style="{
                               justifyContent:'center',
                               alignItems:'center',
                               height:'100%',
                               fontStyle: item.fontStyle?'italic':'',
                               fontWeight: item.bold?'bold':'',}">
                  {{item.title}}
                </div>
              </td>
            </tr>
            <!--            {{getCurrentPageData(paperItem,paperIndex)}}-->
            <tr v-for="(item,index) in getCurrentPageData(paperItem,paperIndex)" :key="'getCurrentPageData'+index">
              <td v-for="(item2,index2) in printParams.tableCol" :key="'printParams.tableCol'+index2" :style="{
                               // width:item2.width+'%',
                               height:printParams.tableInfo.height+'px',
                               fontSize:item2.fontSize+'px',}">
                <!--                {{item2.key}}-->
                <!--        普通文本        -->
                <div  style="display:flex;width: 100%;height: 100%;" :style="{
                               justifyContent:item2.align1,
                               alignItems:item2.align2,
                               height:'100%',
                               fontStyle: item2.fontStyle?'italic':'',
                               fontWeight: item2.bold?'bold':'',}">
                  {{item[item2.key]}}
                </div>
              </td>
            </tr>
          </table>
        </div>

      </div>
    </div>
  </div>
</template>

<script>

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

export default {
  name: 'print2022_print_c',
  data() {
    return {
      width:undefined,
      height:undefined,
      pageFlag:false,
      pageImgQuantity:0,
      printAfterTable:{},
      printBeforeTable:{},
      paperHeight:0,
      paperDirection:'landscape',
      paperTopYl:99999,
      paperPageQuantityList:[],
      timeStart:0,
      backgroundConfig:{},
      paperInfo:{}
    }
  },
  methods: {
    backgroundImgLoadConplate(){
      this.pageImgQuantity--;
      // console.log('图片加载完成，目前还有'+this.pageImgQuantity+'张未加载')
    },
    imgLoadComplate(){
      this.pageImgQuantity--;
      // console.log('图片加载完成，目前还有'+this.pageImgQuantity+'张未加载')
    },
    printFunc(data,template,pageFlag){

      // console.log('data',JSON.stringify(data))
      let showTemplate = template
      this.pageFlag = pageFlag
      // console.log('showTemplate',showTemplate)
      showTemplate.mainList = showTemplate.mainList.filter(it=>it.checked)
      showTemplate.tableCol = showTemplate.tableCol.filter(it=>it.checked)
      // imgList: Array(1)
      // mainList: Array(11)
      // paperDirection: "landscape"
      // paperInfo: Object
      // tableCol: Array(10)
      this.backgroundConfig = template.backgroundConfig
      this.paperInfo = template.paperInfo
      this.init(data,template)
      // console.log('printFunc',this.printData)
      this.$nextTick(()=>{
        if(template.backgroundConfig.path){
          this.pageImgQuantity+=this.paperPageQuantityList.length
        }
        //获取原样式
        let style=document.getElementById('loading').getAttribute("style");
        //先隐藏
        document.getElementById('loading').setAttribute("style",style+"display:none;")

        // console.log('打印渲染用时'+(new Date().getTime() - this.timeStart)+'(毫秒)')
        // console.log('本次打印共有图片'+this.pageImgQuantity+'张')
        let stv = setInterval(()=>{
          if(this.pageImgQuantity === 0){
            clearInterval(stv);
            // console.log('所有图片渲染完成，用时'+(new Date().getTime() - this.timeStart)+'(毫秒)')
            window.document.body.style.height = 'fit-content'
            let innerHtml = ''
            for(let i = 0; i<this.paperPageQuantityList.length;i++){
              innerHtml += document.getElementById('print-div'+i).innerHTML
            }
            window.document.body.innerHTML = innerHtml
            // console.log('window.document.body.innerHTML',window.document.body.innerHTML)
            window.print()
            window.location.reload()
          }
        },10)

      });
    },

    printFuncWX(data,template,pageFlag,uuid,width,height){
      this.width=parseInt(width)
      this.height=parseInt(height)
      let showTemplate = template
      this.pageFlag = pageFlag
      // console.log('showTemplate',showTemplate)
      showTemplate.mainList = showTemplate.mainList.filter(it=>it.checked)
      showTemplate.tableCol = showTemplate.tableCol.filter(it=>it.checked)
      this.backgroundConfig = template.backgroundConfig
      this.paperInfo = template.paperInfo
      this.init(data,template)
      // console.log('printFuncWX',this.printData)
      this.$nextTick(()=>{
        if(template.backgroundConfig.path){
          this.pageImgQuantity+=this.paperPageQuantityList.length
        }
        // console.log('打印渲染用时'+(new Date().getTime() - this.timeStart)+'(毫秒)')
        // console.log('本次打印共有图片'+this.pageImgQuantity+'张')
        // debugger
        let stv = setInterval(()=>{
          if(this.pageImgQuantity === 0){
            clearInterval(stv);
            // console.log('所有图片渲染完成，用时'+(new Date().getTime() - this.timeStart)+'(毫秒)')
            window.document.body.style.height = 'fit-content'
            let innerHtml = ''
            for(let i = 0; i<this.paperPageQuantityList.length;i++){
              innerHtml += document.getElementById('print-div'+i).innerHTML
            }
            window.document.body.innerHTML = innerHtml
          }

          //获取原样式
          let style=document.getElementById('loading').getAttribute("style");
          //先隐藏
          document.getElementById('loading').setAttribute("style",style+"display:none;")
          //获取要打印的dom对象
          let element=document.getElementById("pdf-dom")
          // html转画布
          html2Canvas(element, {
            allowTaint: true,//是否允许跨域
            taintTest: false,//在渲染前是否检查图片
            useCORS: true,//是否尝试加载跨源图像作为CORS服务，在返回到代理（用来解决图片跨域加载问题）
            // width:1200,
            // height:5000,
            dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
            scale: 4 //按比例增加分辨率
          }).then(function (canvas) {
            //生成画布对象后 展示加载效果
            document.getElementById('loading').setAttribute("style",style)
            //生成pdf
            let contentWidth = canvas.width
            let contentHeight = canvas.height
            let pageHeight = contentWidth / 592.28 * 841.89
            let leftHeight = contentHeight
            let position = 0
            let imgWidth = 595.28
            let imgHeight = 592.28 / contentWidth * contentHeight
            let pageData = canvas.toDataURL('image/jpeg', 1.0)
            let PDF = new JsPDF('', 'pt', 'a4')
            if (leftHeight < pageHeight) {
              PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
            } else {
              while (leftHeight > 0) {
                PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                leftHeight -= pageHeight
                position -= 841.89
                if (leftHeight > 0) {
                  PDF.addPage()
                }
              }
            }

          //PDF转换文件
            const dataURLtoFile = (dataurl, filename) => {
              let arr = dataurl.split(',');
              let mime = arr[0].match(/:(.*?);/)[1];
              let bstr = atob(arr[1]);
              let n = bstr.length;
              let u8arr = new Uint8Array(n);
              while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
              }
              //转换成file对象
              return new File([u8arr], filename, {type: mime});
            };
            let base64= PDF.output("datauristring");
            let myfile = dataURLtoFile(base64, "pdf");
            let formData = new FormData();
            formData.append('file', myfile);
            printTemplate.createPDF('pdf/order',uuid,formData).then(res => {
              // console.log('upload',res)
            })

          })
        },10)

      });
    },
    getCurrentPageData(obj,index){
      if(index === 0){
        return this.printData.detail.slice(0,obj.quantity)
      }else{
        let beforeQuantity = 0;
        this.paperPageQuantityList.filter((it,i)=>{return i<index}).forEach(it=>{
          beforeQuantity+=it.quantity
        })
        return this.printData.detail.slice(beforeQuantity,beforeQuantity+obj.quantity)
      }
    },
    calc10(cmHeight){
      let div = document.createElement("div");
      div.id = "cm";
      div.style.height = cmHeight+"cm";
      document.querySelector("body").appendChild(div);
      // 原生方法获取浏览器对元素的计算值
      let cm = document.getElementById("cm").getBoundingClientRect();
      let heightPx = cm.height
      div.remove()
      return heightPx - 2
    },
    getByteLength(str,fontSize) {
      let c = document.createElement("canvas");
      let ctx=c.getContext("2d");
      ctx.font=fontSize+"px Helvetica Neue";
      return ctx.measureText(str).width
    },
    init(data,template){
      //动态改变纸张方向
      let cssPagedMedia = (function () {
        let style = document.createElement('style')
        document.head.appendChild(style)
        return function (rule) {
          style.innerHTML = rule
        }
      }())
      cssPagedMedia.size = function (size) {
        cssPagedMedia('@page {size:  '+ size + '}')
      }
      this.paperDirection==='portrait'?cssPagedMedia.size('portrait'):cssPagedMedia.size('landscape')
      //计算高度
      this.timeStart = new Date().getTime()
      this.printData = data;
      this.printParams = template;
      // console.log('计算前',this.printParams)
      /* 如果table不存在 则不需要计算*/
      let imgList = this.printParams.imgList

      if(imgList.map(it=>it.name).includes('小程序码')){
        printTemplate.generateQRcode({"scene":data.no+"","pageFlag":"1"}).then(res => {
          if (res.code === 200) {
            if (imgList.length > 0){
              imgList.forEach(item=>{
                if(item.nameFlag === 1 || item.name === "小程序码"){
                  item.path = res.data
                }
              })
            }
          } else {
            this.$Message.warning(res.message)
          }
        })
      }

      if(!this.printParams.tableInfo || !this.printParams.tableInfo.top) {
        this.printBeforeTable = this.printParams
        this.paperPageQuantityList = [0]
        this.pageImgQuantity = this.paperPageQuantityList.length * this.printParams.imgList.length
        return
      }
      let tableTop = this.printParams.tableInfo.top
      this.printParams.mainList.forEach(it=>{
        if(it.top<this.paperTopYl){
          this.paperTopYl = it.top
        }
      })
      this.printParams.imgList.forEach(it=>{
        if(it.top<this.paperTopYl){
          this.paperTopYl = it.top
        }
      })
      if(this.printParams.tableInfo.top<this.paperTopYl){
        this.paperTopYl = this.printParams.tableInfo.top
      }
      this.printAfterTable = {
        mainList:  this.printParams.mainList.filter(it=>{return it.top>tableTop}),
        imgList:   this.printParams.imgList.filter(it=>{return it.top>tableTop})
      }
      this.printBeforeTable = {
        mainList:  this.printParams.mainList.filter(it=>{return it.top<=tableTop}),
        imgList:   this.printParams.imgList.filter(it=>{return it.top<=tableTop})
      }
      /* 计算一下给表格留下多少 */
      /* 先计算表格距下最大距离 = 最大高度 -  (底部预留 - table本身的top - 所有after占位 ) */


      /* 所有after 从最顶到最底 总共占的高度  先整个数组*/
      let arr = []
      this.printAfterTable.mainList.forEach(it=> {
        if(arr.length>0 && it.top < arr[0].top){
          arr.splice(0,0, {...it})
        }else{
          arr.push({top:it.top,height:it.height})
        }
      })
      this.printAfterTable.imgList.forEach(it=> {
        if(arr.length>0 && it.top < arr[0].top){
          arr.splice(0,0, {...it})
        }else{
          arr.push({top:it.top,height:it.height})
        }
      })
      /* 计算一下总共的高度（把最小的看做0） */

      /* 这块算法变一下 因为有可能table后面啥也没有的 得特殊处理一下 这样就不用让位置了 */
      let mostTop = 0
      /* 给table预留的最高高度 下面计算*/
      let tableMaxHeight = 0;
      // debugger
      if(arr.length>0){
        mostTop = arr[0].top
        arr.forEach(it=>{
          it.top = it.top - mostTop
        })
        let afterAllHeight = 0;
        arr.forEach(it=>{
          afterAllHeight = (it.top+it.height)>afterAllHeight?(it.top+it.height):afterAllHeight
        })
        tableMaxHeight = this.paperHeight - (this.paperTopYl + this.printParams.tableInfo.top + afterAllHeight + (mostTop - this.printParams.tableInfo.top - (3*30)))
      }else{
        tableMaxHeight = this.paperHeight - (this.paperTopYl + this.printParams.tableInfo.top)
      }
      // console.log('tableMaxHeight',tableMaxHeight)
      // console.log('paperHeight',this.paperHeight)
      // tableMaxHeight=495.515625
      // this.paperHeight=1122.515625

      // console.log('tableMaxHeight',tableMaxHeight)
      // 27 20 204 169
      /* 计算一下每页最多多少行 */
      let tableMaxRow = parseInt((tableMaxHeight/30).toString())-1
      // console.log(tableMaxRow)
      /* 给数据排版 */
      // console.log('this.printData',this.printData)
      this.printData.detail.forEach(it=>{
        this.$set(it,'tdRow',0)
        this.printParams.tableCol.forEach(it2=>{
          let textWidth = 1
          // debugger
          if(it2.key&&it2.key!=='picture'){
            textWidth  = this.getByteLength(it[it2.key],it2.fontSize)

            // let tdWidth = this.printParams.tableInfo.width * (it2.width/100)-5 /* 有误差，手动-5 */
            /* 向上取整 */
            let tdWidth = it2.width - 5 /* 有误差，手动-5 */ /* 因为改成px了不用计算了直接用 */

            let tdRow = Math.ceil( textWidth / tdWidth)
            // console.log(it[it2.key],tdRow,tdWidth,textWidth)
            // console.log(it2.title,tdRow,it2.key,textWidth,tdWidth)
            // console.log('textWidth',textWidth)
            // console.log('tdWidth',tdWidth)
            // console.log('tdRow',tdRow)
            if(it.tdRow < tdRow){
              if(tdRow > 1){
                this.$set(it,'tdHeight',(tdRow * it2.fontSize * 1.5) + 2)
                this.$set(it,'tdRow',tdRow)
              }else{
                this.$set(it,'tdHeight',30)
                this.$set(it,'tdRow',tdRow)
              }
            }
          }else{
            this.$set(it,'tdHeight',80)
            this.$set(it,'tdRow',1)
          }
        })
      })
      /* 去掉头部最高table */
      let widthHeadTableMaxHeight =  tableMaxHeight - 30;
      let index = 0;
      this.paperPageQuantityList.push({quantity:0,height:0});
      this.printData.detail.forEach(it=>{
        if((widthHeadTableMaxHeight - it.tdHeight)>=0){
          widthHeadTableMaxHeight -= it.tdHeight
          this.paperPageQuantityList[index].quantity+=1
          this.paperPageQuantityList[index].height+=it.tdHeight
        }else{
          widthHeadTableMaxHeight =  tableMaxHeight - 30;
          this.paperPageQuantityList.push({quantity:0,height:0});
          index++;
          widthHeadTableMaxHeight -= it.tdHeight
          this.paperPageQuantityList[index].quantity+=1
          this.paperPageQuantityList[index].height+=it.tdHeight
        }
      })
      /* after 跟着页走 重新计算一下 */
      this.paperPageQuantityList.forEach(it=>{
        this.$set(it,'mainList',[])
        this.$set(it,'imgList',[])
        this.printAfterTable.mainList.forEach(it1=>{
          let it1Temp = {...it1}
          it1Temp.top = it1Temp.top + (it.height - 60)
          it.mainList.push({...it1Temp})
        })
        this.printAfterTable.imgList.forEach(it2=>{
          let it2Temp = {...it2}
          it2Temp.top = it2Temp.top + (it.height - 60)
          it.imgList.push({...it2Temp})
        })
      })
      // console.log(this.paperPageQuantityList)
      this.pageImgQuantity = this.paperPageQuantityList.length * this.printParams.imgList.length
      // console.log('计算后',this.printParams)
    }
  },
  created() {

  },

}
</script>

<style scoped>
/*.portrait{*/
/*  !*border: 1px solid red;*!*/
/*  width: 20.9cm;*/
/*  height: 29.6cm;*/
/*}*/
/*.landscape{*/
/*  !*border: 1px solid blue;*!*/
/*  width: 29.6cm;*/
/*  height: 20.9cm;*/
/*}*/
@page {
  /*默认为无边距*/
  margin: 0cm !important;
  /*纸张大小默认A4*/
  size: A4 landscape;

}

</style>
