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

news2024/12/24 13:23:01
思路:
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>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2217301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jmeter接口测试企业级项目实战day2

1.JMeter接口关联 含义&#xff1a;把上一个接口的响应内容&#xff0c;作为下一个接口的请求参数 思路&#xff1a;通过变量来传递数据 步骤&#xff1a; 1.创建&#xff1a;上一个接口&#xff0c;添加【后置处理器】&#xff1a;提取数据创建变量 2.使用&am…

项目分析:自然语言处理(语言情感分析)

在这个信息爆炸的时代&#xff0c;我们每天都在与海量的文本数据打交道。从社交媒体上的帖子、在线评论到新闻报道&#xff0c;文本信息无处不在。然而&#xff0c;这些文本不仅仅是文字的堆砌&#xff0c;它们背后蕴含着丰富的情感和观点。如何有效地理解和分析这些情感&#…

leetcode48:旋转矩阵

题目&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5…

昆仑虚 - NextJS 项目如何进行部署?

引言 NextJS 是一个构建于 NodeJS 之上的一个 Web 开发框架。它基于 React 特性进行了一些列的扩展!! 在社区中也很是火热, 前段时间 「昆仑虚」 也终于完成了项目的迁移(React > NexJS)!! 那么接下来就是项目部署, NextJS 相比常规的前端部署还是有所区别的: 常规的前端…

便捷实用的桌面时钟 让你随时掌握时间 美观且大气

便捷实用的桌面时钟 让你随时掌握时间 美观且大气。桌面时钟顾名思义就是可以放在桌面上的时钟&#xff0c;这是一款界面优美,功能实用,易于操作的桌面时钟工具芝麻时钟&#xff08;下载地址&#xff1a;https://clock.zhimasoft.cn/?bi&#xff09; 找个好看的桌面时钟&…

【R语言】随机森林+相关性热图组合图

数据概况文末有获取方式 随机森林部分 #调用R包 library(randomForest) library(rfPermute) library(ggplot2) library(psych) library(reshape2) library(patchwork) library(reshape2) library(RColorBrewer) ​ ​ #读取数据 df<-read.csv("F:\\EXCEL-元数据\\2020…

Spring Boot与JavaWeb协同:在线考试系统的实现“

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于JavaWeb技术的在线考试系统设计与实现…

【02】Windows特殊权限-Trustedinstaller

知识点&#xff1a; “TrustedInstaller” 是 Windows 操作系统中的一个特殊账户&#xff0c;用于管理和保护重要的系统文件。它是 Windows 模块安装程序 (Windows Modules Installer) 的一部分&#xff0c;负责安装、修改和删除 Windows 更新和可选组件。默认情况下&#xff…

Power BI:链接数据库与动态数据展示案例

一、案例背景 在数据驱动的时代&#xff0c;如何高效、直观地展示和分析数据成为了企业决策和个人洞察的关键。Power BI作为一款强大的商业智能工具&#xff0c;凭借其强大的数据连接能力、丰富的可视化选项以及交互性和动态性&#xff0c;成为了众多企业和个人的首选。本文将…

C++/初识C++

目录 一、前言 二、正文 1C语言第一个程序&#xff1a; 1.1C的第一个程序&#xff1a; 2.命名空间 2.1 namespace的价值 2.2namespace的定义 2.3namespace的正常使用 3.C输出和输入 三、结言 一、前言 点来不及悼念C语言&#xff0c;接下来出场的是新的语言C。不同于C…

WebGL编程指南 - WebGL入门

初识绘图流程、缓冲区、着色器、attribute和uniform变量 先画一个蓝色的正方形 html代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content&…

iOS 18升级:避免常见陷阱,顺利完成升级

随着iOS 18的发布&#xff0c;许多用户都希望尽快体验到新系统带来的新功能和改进。然而&#xff0c;升级过程可能会因为准备工作不足或对步骤的不熟悉而变得复杂。本文旨在为用户提供一个清晰的升级指南&#xff0c;确保升级过程既平滑又安全。 升级前的准备工作 在开始升级之…

PCL 点云配准-ICP算法(精配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 点云加载函数 2.1.2 ICP 配准函数 2.1.3 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xf…

股票Tick数据如何获取做量化交易

【高频tick数据源】银河金融数据库 【tick高频回测策略】在利用股票Tick数据做量化交易时&#xff0c;一个关键的细节点是“实现高频交易中的市场冲击成本最小化”。细节点&#xff1a;市场冲击成本最小化策略 1. 策略原理市场冲击成本是指大额交易对市场价格造成的影响&#…

Linux驱动开发——设备树

文章目录 1 什么是设备树&#xff1f;2 DTS、DTB和DTC3 DTS语法3.1 dtsi头文件3.2 设备节点3.3 标准属性3.4 根节点compatible属性3.5 向节点追加或修改内容 4 创建小型模板设备树5 设备树在系统中的体现6 绑定信息文档7 设备树常用OF操作函数7.1 查找节点的OF函数7.2 查找父/子…

软考高级系统规划与管理师,都是精华知识点!

知识点&#xff1a;信息的定义和属性 1、 信息的基本概念 l 信息是客观事物状态和运动特征的一种普遍形式&#xff0c;客观世界中大量地存在、产生和传递着以这些方式表示出来的各种各样的信息。 l 维纳&#xff08;控制论创始人&#xff09;&#xff1a;信息就是信息&#…

基于BS21芯片方案的SLE星闪模块功能特点

1、E105-BS21系列SLE星闪模块产品简介 E105-BS21系列SLE星闪模块模块是基于星闪协议 1.0 版本的串口转 SLE&#xff08;SparkLink Low Energy&#xff09;星闪模块&#xff0c;具有体积小、功耗低、 传输距离远、传输速度快、抗干扰能力强、低延时等特点&#xff0c;工作在 2…

R语言机器学习算法实战系列(四)随机森林算法+SHAP值 (Random Forest)

文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述特征选择数据切割调节参数构建模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve特征的重要性模型解释保存模型总结系统信息介绍 随机森林是常用的非线性用于构建分类器的算法,它是由数…

2024年法拍房爆了 1-9月挂牌金额超过5200亿

据互联网数据统计2024年1-9月全国法拍房挂拍量为494737套&#xff0c;同比增长66.84%&#xff0c;挂牌金额超过5200亿&#xff01; 法拍房暴增的背后是原业主的债务困境&#xff0c;或是房地产风险释放触底&#xff0c;或与规模高达10.61万亿的经营D相关。而对于不良资产行业机…

算法-利用深度优先搜索求解二叉树路径问题

这道题可以用深度优先搜索来写&#xff0c;比如说加入节点左右节点都为空且值等于targetsum则返回true,这里可以使用一个简单的方法来写&#xff0c;就比如说我们每次遍历到一个节点时&#xff0c;用targetsum减去当前节点的值 &#xff0c;这样的话只要遍历到叶子节点值等于ta…