listenlive.cn

是谁来自山川湖海 却囿于昼夜厨房与爱


  • 首页

  • 技术

  • 笔记

  • 杂记

  • 分享

  • 归档

  • 关于

  • 搜索
close

使用jspdf导出pdf 内容被截断的问题

时间: 2022-12-24   |   分类: 笔记     |   阅读: 1216 字 ~3分钟

问题

截图

分页时内容被截断

解决

环境

  • vue2
  • 依赖包:jspdf html2canvas jspdf-autotable

第一种解决方案—使用jspdf-autotable

适用于内容为表格的情况 jspdf-autotable会自动处理分页

<script>
import jsPDF from "jspdf";
import "jspdf-autotable";
// import html2canvas from "html2canvas";
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },

  methods: {
    jspdf() {
      let doc = new jsPDF();
      let columns = ["ID", "Name", "Country"];
      let rows = [
        [1, "Shaw", "Tanzania"],
        [2, "Nelson", "Kazakhstan"],
        [3, "Garcia", "Madagascar"],
        [4, "Shaw", "Tanzania"],
        [5, "Nelson", "Kazakhstan"],
        [6, "Garcia", "Madagascar"],
      ];
      doc.autoTable(columns, rows);
      doc.save("table.pdf");
    },
  },
};
</script>

第二种解决方案—使用html2canvas

a. 适用于内容为html的情况
b. html2canvas的原理:将html转换为canvas,再将canvas转换为图片,最后将图片添加到pdf中
c. 实现原理:限制html内容的大小,让元素内容占pdf的一页,然后合并pdf

<template>
  <div class="hello">
    <button @click="jspdf">jspdf</button>
    <div id="myPage">
      <!--每n行填充一次表格-->
      <div v-for="p in pageCount" :key="p" :id="'page' + p" class="table">
        <table
          style="font-size: 62px"
          border="1"
          cellspacing="0"
          cellpadding="1"
        >
          <thead>
            <tr>
              <th v-for="column in columns" :key="column.title">
                {{ column.title }}
              </th>
            </tr>
          </thead>
          <tbody>
            <!--rows pageSize行-->
            <tr
              v-for="row in rows.slice((p - 1) * pageSize, p * pageSize)"
              :key="row.id"
            >
              <td v-for="column in columns" :key="column.title">
                {{ row[column.dataKey] }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template> 
<script>
import jsPDF from "jspdf";
import "jspdf-autotable";
import html2canvas from "html2canvas";
export default {
  name: "HelloWorld",
  data() {
    return {
      columns: [
        { title: "ID", dataKey: "id" },
        { title: "Name", dataKey: "name" },
        { title: "Country", dataKey: "country" },
      ],
      rows: [
        { id: 1, name: "Shaw", country: "Tanzania" },
        { id: 2, name: "Nelson", country: "Kazakhstan" },
        { id: 3, name: "Garcia", country: "Madagascar" },
        { id: 4, name: "Shaw", country: "Tanzania" },
        { id: 5, name: "Nelson", country: "Kazakhstan" },
        { id: 6, name: "Garcia", country: "Madagascar" },
      ],
      tableCount: 0,
      pageSize: 20,
    };
  },
  props: {
    msg: String,
  },
  computed: {
    // 总记录数
    tableCounts() {
      return this.rows.length;
    },
    // 总页数
    pageCount() {
      return Math.ceil(this.tableCounts / this.pageSize);
    },
  },
  methods: {
    // 导出pdf
    async jspdf() {
      let arrData = [];
      for (let i = this.pageCount; i > 0; i--) {
        let idName = "page" + i;
        let imageData = await this.html2c(idName);
        arrData.unshift(imageData);
      }

      let PDF = new jsPDF("", "pt", "a4"); //A4纸,纵向
      for (let i = 0; i < arrData.length; i++) {
        PDF.addImage (arrData[i].pageData, "JPEG", 20, 20, arrData[i].imgWidth, arrData[i].imgHeight ); //添加图片
        if (arrData.length - i > 1) {
          PDF.addPage();
        }
      }
      PDF.save("hello" + ".pdf");
    },

    // html转canvas
    async html2c(idName) {
      return new html2canvas(document.getElementById(idName), {
        // allowTaint: true //跨域图片
        useCORS: true, //跨域图片,
      }).then(function (canvas) {
        let contentWidth = canvas.width; //内容宽度
        let contentHeight = canvas.height; //内容高度
        // let pageHeight = (contentWidth / 555.28) * 841.89; //一页pdf显示html页面生成的canvas高度;
        // let leftHeight = contentHeight; //剩余内容高度
        // let position = 20; //距离顶部位置
        let imgWidth = 555.28; //img宽度
        let imgHeight = (555.28 / contentWidth) * contentHeight; //img高度
        let pageData = canvas.toDataURL("image/jpeg", 1.0); //生成一张图片
        let pageObject = {
          pageData: pageData,
          imgWidth: imgWidth,
          imgHeight: imgHeight,
        };
        return pageObject;
      });
    },
  },
};
</script>
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.table {
  margin-top: 60px;
}
</style>

参考:

<script>
import jsPDF from "jspdf";
import "jspdf-autotable";
import html2canvas from "html2canvas";
export default {
  name: "HelloWorld",
  data() {
    return {
      columns: [
        { title: "ID", dataKey: "id" },
        { title: "Name", dataKey: "name" },
        { title: "Country", dataKey: "country" },
      ],
      rows: [
        { id: 1, name: "Shaw", country: "Tanzania" },
        { id: 2, name: "Nelson", country: "Kazakhstan" },
        { id: 3, name: "Garcia", country: "Madagascar" },
        { id: 4, name: "Shaw", country: "Tanzania" },
        { id: 5, name: "Nelson", country: "Kazakhstan" },
        { id: 6, name: "Garcia", country: "Madagascar" },
        { id: 7, name: "Shaw", country: "Tanzania" },
        { id: 8, name: "Nelson", country: "Kazakhstan" },
        { id: 9, name: "Garcia", country: "Madagascar" },
        { id: 10, name: "Shaw", country: "Tanzania" },
        { id: 11, name: "Nelson", country: "Kazakhstan" },
        { id: 12, name: "Garcia", country: "Madagascar" },
      ],
    };
  },
  props: {
    msg: String,
  },

  methods: {
    jspdf() {
      html2canvas(document.getElementById("myPage"), {
        // allowTaint: true //跨域图片
        useCORS: true, //跨域图片,
      }).then(function (canvas) {
        let contentWidth = canvas.width; //内容宽度
        let contentHeight = canvas.height; //内容高度
        let pageHeight = (contentWidth / 555.28) * 841.89; //一页pdf显示html页面生成的canvas高度;
        let leftHeight = contentHeight; //剩余内容高度
        let position = 20; //距离顶部位置
        let imgWidth = 555.28; //img宽度
        let imgHeight = (555.28 / contentWidth) * contentHeight; //img高度
        let pageData = canvas.toDataURL("image/jpeg", 1.0); //生成一张图片
        let PDF = new jsPDF("", "pt", "a4"); //A4纸,纵向
        if (leftHeight < pageHeight) { //内容未超过一页
          PDF.addImage(pageData, "JPEG", 20, 20, imgWidth, imgHeight); //添加图片
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight);
            leftHeight -= pageHeight;
            position -= 841.89;
            if (leftHeight > 0) {
              PDF.addPage();
            }
          }
        }
        PDF.save("hello" + ".pdf");
      });
    },
  },
};
</script>

喜欢这篇文章的话 打赏一下吧!

Wechat Alipay

#vue# #jspdf# #pdf#
Docker可视化管理工具--Portainer的配置与使用
deb包的打包流程
  • 文章目录
  • 站点概览
一刀未剪

一刀未剪

Programmer & Architect

GitHub Instagram Weibo Email
70 日志
4 分类
69 标签
工具站
Harbor 在线文档 Quick Reference Linux 命令查询 Mock 模拟数据
友情链接
  • milu杰克
  • 环境
  • 第一种解决方案—使用jspdf-autotable
  • 第二种解决方案—使用html2canvas
  • 参考:
京ICP备17004223号 © 2020 - 2023 listenlive.cn
Powered by - HUGO
Theme by - NexT
访客量 -
0%