自学内容网 自学内容网

vue 2.0 使用 html2canvas + jspdf +ant-design-vue 1.x + echarts + 高德地图 导出数据报告

思路:
1. 因为html转为图片再加入到PDF中 会导致截断,因此前端自定义分页添加 类 (page)
2. 通过page生成图片 在加入PDF
<template>
  <div id="pdf-content">
    <div class="page first-page">
      <div>
        <div class="first-page-header">
          <p>监控报告</p>
          <p>物流有限公司</p>
        </div>
        <img style="width: 100%" src="@/assets/vehicleDriving/bg.jpg" />
        <div class="first-page-info">
          <div class="item">
            <div class="label">账户</div>
            <div class="value"></div>
          </div>
          <div class="item">
            <div class="label">运单名称</div>
            <div class="value"></div>
          </div>
          <div class="item">
            <div class="label">运单号</div>
            <div class="value"></div>
          </div>
          <div class="item">
            <div class="label">设备名称</div>
            <div class="value"></div>
          </div>
          <div class="item">
            <div class="label">设备id</div>
            <div class="value">1111</div>
          </div>
        </div>
      </div>
    </div>
    <div class="page">
      <p>运单开始时间:2024-09-10 03:43:38</p>
      <p>运单结束时间:2024-09-10 05:59:59</p>
      <p>设备起点:xxx</p>
      <p>设备终点:xxx</p>
      <p>时长:2小时1621</p>
      <p>:56条数</p>
      <sv-table :data="list" :height="300" border="inner">
        <sv-column v-for="item in columns" :key="item.field" :field="item.field" :title="item.title"></sv-column>
      </sv-table>
      <sv-table :data="list" :height="300" border="inner">
        <sv-column title="事件类型" field="eventType"></sv-column>
        <sv-column title="发生次数" field="count"></sv-column>
      </sv-table>
    </div>
    <div class="page">
      <e-line class="line-item"></e-line>
      <e-line class="line-item"></e-line>
    </div>
    <div class="page">
      <e-line class="line-item"></e-line>
      <e-line class="line-item"></e-line>
    </div>
    <div class="page">
      <e-line class="line-item"></e-line>
      <e-line class="line-item"></e-line>
    </div>
    <div class="map-route page">
      <e-map-route></e-map-route>
      <p style="margin-top: 20px">起点:xxxx</p>
      <p>终点:xxxx</p>
    </div>
    <div class="page">
      <p>报警数据列表</p>
      <sv-table :data="list" :height="300" border="inner">
        <sv-column title="时间" field="eventType"></sv-column>
        <sv-column title="参数类型" field="count"></sv-column>
        <sv-column title="具体数值" field="count"></sv-column>
      </sv-table>
    </div>
  </div>
</template>
<script>
import ELine from './components/ELine.vue'
import EMapRoute from './components/EMapRoute.vue'
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
export default {
  name: 'ExportPdf',
  components: {
    ELine,
    EMapRoute
  },
  data() {
    return {
      JsPDF: jsPDF,
      spinning: false,
      list: [
        {
          statusParam: 'speed',
          eventType: '超速',
          count: 10
        },
        {
          statusParam: 'speed',
          eventType: '疲劳驾驶',
          count: 20
        }
      ],
      columns: [
        {
          title: '状态参数',
          field: 'statusParam'
        },
        {
          title: '阈值',
          field: 'threshold'
        },
        {
          title: '最高',
          field: 'max'
        },
        {
          title: '最低',
          field: 'min'
        },
        {
          title: '平均',
          field: 'avg'
        },
        {
          title: '超阀值',
          field: 'overThreshold'
        },
        {
          title: '报警条数',
          field: 'alarmCount'
        },
        {
          title: '安全指数',
          field: 'safeIndex'
        }
      ]
    }
  },
  methods: {
    async getData() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({
            list: [
              {
                statusParam: 'speed',
                eventType: '超速',
                count: 10
              },
              {
                statusParam: 'speed',
                eventType: '疲劳驾驶',
                count: 20
              }
            ]
          })
        }, 2000)
      })
    },
    async print() {
      await this.getData()
      const contentDiv = document.getElementById('pdf-content')
      const pages = contentDiv.querySelectorAll('.page')
      const promises = []
      for (const page of pages) {
        const p = await html2canvas(page)
        promises.push(p)
      }
      const canvases = await Promise.all(promises)
      const pdf = new this.JsPDF('', 'pt', 'a4')
      for (let i = 0; i < canvases.length; i++) {
        const canvas = canvases[i]
        const imgData = canvas.toDataURL('image/jpeg', 1.0)
        const imgProps = pdf.getImageProperties(imgData)
        const pdfWidth = pdf.internal.pageSize.getWidth()
        const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width
        pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight)
        if (i < canvases.length - 1) {
          pdf.addPage()
        }
      }
      pdf.save('车载数据报告.pdf')
      this.$emit('success')
    }
  }
}
</script>

<style scoped lang="less">
#pdf-content {
  width: 900px;
  padding: 20px;
  font-size: 16px;
  color: #000;
  .line-item {
    width: 100%;
    height: 400px;
  }
  .map-route {
    width: 100%;
  }
  .page {
    height: 850px;
  }
  .first-page {
    box-sizing: border-box;
    padding-top: 80px;
    .first-page-header {
      text-align: center;
      font-size: 30px;
      font-weight: bold;
    }
    .first-page-info {
      font-weight: bold;
      width: 500px;
      margin: 0 auto;
    }
    .item {
      display: flex;
      .label {
        width: 150px;
        font-size: 24px;
        text-align: right;
      }
      .value {
        width: 300px;
        font-size: 22px;
        border-bottom: 1px solid #000;
      }
    }
  }
}
</style>

echarts 测试代码
<template>
  <div class="e-line" ref="eLineRef"></div>
</template>
<script>
import * as echarts from 'echarts'
export default {
  data() {
    return {}
  },
  mounted() {
    this.initChart()
  },
  methods: {
    initChart() {
      const eLineRef = this.$refs.eLineRef
      const myChart = echarts.init(eLineRef)
      const option = {
        title: {},
        tooltip: {},
        grid: {
          left: 0,
          right: 0,
          containLabel: true
        },
        legend: {
          data: ['Sales']
        },
        xAxis: {
          data: [
            'shirt',
            'cardign',
            'chiffon shirt',
            'pants',
            'heels',
            'socks',
            'book',
            'poster',
            'notebook',
            'glass',
            'toilet paper'
          ]
        },
        yAxis: {},
        series: [
          {
            name: 'Sales',
            type: 'line',
            data: [5, 20, 36, 10, 10, 20, 8, 20, 10, 10, 20]
          }
        ]
      }
      myChart.setOption(option)
    }
  }
}
</script>

<style scoped lang="less">
.e-line {
  width: 100%;
  height: 100%;
}
</style>

高德测试代码
<template>
  <div id="e-map-route"></div>
</template>
<script>
export default {
  data() {
    return {
      lnglats: [[121.473702, 31.230416]],
      map: null
    }
  },
  methods: {
    initMap() {
      const map = new AMap.Map('e-map-route', {
        viewMode: '2D',
        zoom: 11,
        WebGLParams: {
          preserveDrawingBuffer: true
        }
      })
      this.map = map
      this.setDriveRoute()
    },
    setDriveRoute() {
      const _this = this
      AMap.plugin('AMap.Driving', function () {
        const driving = new AMap.Driving({
          map: _this.map
        })
        const start = [121.473702, 31.230416]
        const end = [120.193636, 30.259244]
        const waypoints = []
        driving.search(start, end, waypoints, function (status, result) {
          if (status === 'complete') {
            _this.map.setFitView()
          }
        })
      })
    }
  },
  mounted() {
    this.initMap()
  }
}
</script>

<style lang="less">
#e-map-route {
  height: 500px;
  width: 100%;
}
</style>

在这里插入图片描述
在这里插入图片描述


原文地址:https://blog.csdn.net/weixin_44185995/article/details/142873429

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!