vue导出pdf文件

需求:
页面左右结构,左侧菜单,右侧表格,需求为导出表格信息
用typeScript来写的项目,大概思路在网上找的,然后就是改写之路…
在这里插入图片描述
实现:
1.安装依赖

npm install --save html2canvas
npm install jspdf --save

2.在项目中新建htmlToPdf.ts 定义全局函数

// 导出页面为PDF格式
import html2Canvas from 'html2canvas' // 引入html2canvas
import JsPDF from 'jspdf' // 引入jspdf
export default {
  install(Vue: { prototype: { getPdf: (title: any, idPdf: any, type: string) => void } }, options: any) {
    Vue.prototype.getPdf = (title: any, idPdf: any, type: string) => {
      const dataId: any = document.querySelector('#' + idPdf); // 或者用ref
      html2Canvas(dataId, {
        allowTaint: true
      }).then((canvas) => {
        let PDF: any = new JsPDF('p', 'pt', 'a4')
        const contentWidth: any = canvas.width
        const contentHeight: any = canvas.height
        const pageHeight: any = contentWidth / 592.28 * 841.89
        let leftHeight: any = contentHeight
        let position: any = 0
        const imgWidth: any = 595.28
        const imgHeight: any = 592.28 / contentWidth * contentHeight
        // 加水印
        let ctx: any = canvas.getContext("2d");
        ctx.font = "60px Georgia";
        ctx.fillStyle = "rgba(214,214,214,0.4)";
        ctx.textAlign = "start"
        ctx.textBaseline = "hanging";
        const num = contentHeight / 600
        // 每隔一段距离出现一次水印
        for (let i = 0; i <= num; i++) {
          if(type == 'table') {
            // 表格类型水印
            if(imgHeight < 600) { // 这里根据图片高度要进行下判断
              ctx.fillText("这是水印信息", (canvas.width - 400) / 2 + (canvas.width / 4), (i * 300) + 120);
            }else {
              ctx.fillText("这是水印信息", (canvas.width - 400) / 2 + (canvas.width / 4), (i * 600) + 500);
            }
          }else {
          	// 其他类型
            if(imgHeight < 600) { // 这里根据图片高度要进行下判断
              ctx.fillText("这是水印信息", canvas.width/2 + 120, (i * 300) + 120);
            }else {
              ctx.fillText("这是水印信息", canvas.width/2 + 120, (i * 600) + 500);
            }
          }          
        }
        // 加水印
        
        const pageData: any = canvas.toDataURL('image/jpeg', 1.0)

        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.save(title + '.pdf') // 生成pdf
      }
      )
    }
  }
}

3.在main.ts里引入

import htmlToPdf from './unit/htmlToPdf'   // 这里添加路径
Vue.use(htmlToPdf)

4.使用

<span id="downLoadPDF" @click="getPdf(
'导出测试 //生成pdf的名称', 
'contentPDF //pdf区域id', 
'table // 类型(因为我还有其他类型要导出,所以要判断一下)')
">导出PDF</span>
<!-- 页面主要内容,打印部分内容 start -->
<div id="contentPDF"> // 导出pdf区域的ID
    <table id="tableList">
      <tbody>
        <tr v-for="(item, index) in dataList" :key="index">
          <td v-if="index == 0">序号</td>
          <td v-else>{{ index + (pageNo - 1) * pageSize }}</td>
          <td v-for="(val, keyValue) in item" :key="keyValue">{{ val }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>
<!-- 页面主要内容,打印部分内容 end -->

5.基本内容已经实现,还存在问题
因为这种方式是将内容转换为一个canvas图片,并且保存的,这样就会存在中间断页的问题(如图)
在这里插入图片描述

网上给出的解决办法是:只生成一页pdf,但是这种解决办法的局限性就是 如果我生产pdf的表格数据量很大的话,表格就会很小,此方法不可行
然后,想到自己控制条数 生成pdf。这种放式,由于表格是动态生成了,数据需要看全,不能做成超出隐藏的形式,所以控制不了每行的高度,就目前的数据来看,第七条就已经断页了,解决不了根本问题
这个问题还没有解决…………

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值