Chrollo Desu
Chrollo Desu

Reputation: 11

How to add auto page break and footer per page in jsPDF?

How to add page break automatically when the page will be printed, I use jspdf plugin in vuejs 2, is it possible to add page break using those plugins?

Currently, the 2nd div appears broken in the exported file hence I would like to have the div and footer will appear from the next page.

enter image description here

Here's my code:

.final-proof-container {
  width: 1296px;
  height: 775px;
  /* background-color: #e8e8e8; */
  border-top: 6px solid #383434;
  border-left: 6px solid #383434;
  border-right: 6px solid #383434;
  /* padding: 10px 10px 10px 10px; */
  /* display: inline-flex;
  flex-direction: column;
  flex-wrap: wrap; */
}

.final-proof-content {
  /* width: 330px; */
  min-height: 350px;
  background-color: #474747;
  display: flex;
  flex-direction: row;
  color: white;
  border-radius: 5%;
  /* margin-left: 8px;
  margin-right: 4px; */
  font-weight: 400;
  font-family: "Open Sans", sans-serif;
  font-size: 12px;
  /* padding: 10px 10px 10px 10px; */
  /* margin: 10px 10px 10px 10px; */
  /* margin-bottom: 10px; */
}

.material-type {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.left-content {
  width: 60%;
  padding-top: 10px;
  padding-left: 10px;
}

.right-content {
  width: 40%;
  padding-top: 10px;
  padding-left: 5px;
  padding-right: 10px;
}
.right-content img {
  width: 100%;
  height: 50%;
}

.dimensions {
  list-style: none;
}
.option-logo {
  width: 20px;
  height: 12px;
}

.material-circle {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  margin-right: 5px;
}

.final-proof-footer {
  background-color: black;
  width: 1296px;
}

.top-section {
  background-color: #303030;
  display: flex;
  justify-content: space-between;
  padding-left: 10px;
  padding-right: 10px;
  color: white;
  font-weight: bolder;
  font-family: "Open Sans", sans-serif;
}
.bottom-section {
  display: flex;
  flex-direction: row;
  color: white;
  flex-wrap: wrap;
  justify-content: center;
  height: 175px;
}
.logo {
  width: 20%;
  display: flex;
  justify-content: center;
  border-right: 1.5px solid #686767;
  border-top: 3px solid #686767;
  border-left: 3px solid #686767;
  border-bottom: 3px solid #686767;
  min-width: 300px;
}
.order {
  width: 25%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  border-right: 1.5px solid #686767;
  border-top: 3px solid #686767;
  border-left: 3px solid #686767;
  border-bottom: 3px solid #686767;
  flex-wrap: wrap;
  min-width: 300px;
}
.location {
  width: 25%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  border-right: 1.5px solid #686767;
  border-top: 3px solid #686767;
  border-left: 3px solid #686767;
  border-bottom: 3px solid #686767;
  flex-wrap: wrap;
  min-width: 300px;
}
.shipping {
  width: 26.8%;
  display: flex;
  flex-direction: row;
  align-items: center;
  border-right: 4px solid #686767;
  border-top: 3px solid #686767;
  border-left: 3px solid #686767;
  border-bottom: 3px solid #686767;
  justify-content: center;
  flex-wrap: wrap;
}
.order img {
  width: 40px;
  height: 40px;
}
.location img {
  width: 40px;
  height: 40px;
}
.shipping img {
  width: 40px;
  height: 40px;
}
.text-content {
  display: flex;
  flex-direction: column;
  line-height: 0.1;
  font-size: 14px;
}
.order-type {
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  font-weight: bolder;
  font-size: 20px;
  text-align: center;
  margin-right: 30px;
}
.logo img {
  width: 200px;
  height: 150px;
}
<template>
  <div>
    <v-btn color="primary" @click="generateReport">Generate</v-btn>

    <div ref="order_details">
      <div class="final-proof-container">
        <v-layout row wrap style="padding: 10px !important">
          <v-flex
            xs4
            md4
            lg4
            v-for="(item, index) in order.carts"
            :key="index"
            class="pa-0"
            style="margin-bottom: 10px !important"
          >
            <div class="final-proof-content" style="margin: 10px !important">
              <div class="left-content">
                <p>Product(s): {{ getSectionNo(item) }}</p>
                <p class="mb-1">Material Type:</p>
                <div class="materia-type mb-2">
                  <span>
                    <div
                      class="material-circle"
                      :style="`background-color:${item.material.material_type.color}`"
                    ></div>
                    {{ item.material.material_type.name }}
                  </span>
                </div>
                <p class="mb-1">Dimensions:</p>
                <ul
                  v-if="Array.isArray(getDimensions(item))"
                  class="dimensions mb-2"
                >
                  <li
                    v-for="(dimension, key) in getDimensions(item)"
                    :key="key"
                  >
                    {{ dimension.section_no }} - W: {{ dimension.width }}"| H:
                    {{ dimension.height }}"
                  </li>
                </ul>
                <p class="mb-1">Options:</p>
                <!--Addition of option list in table layout-->
                <table class="option-list" id="option-list">
                  <tr>
                    <td>
                      <img
                        src="/assets/img/price_point.png"
                        class="option-logo"
                        alt="Logo"
                      />
                    </td>
                    <td><p class="mb-1 pl-1">Price Point: 2/$4.00</p></td>
                  </tr>
                </table>

                <table class="option-list">
                  <tr>
                    <td>
                      <img
                        src="/assets/img/comments.png"
                        width="20"
                        height="15"
                        alt="Comments"
                      />
                    </td>
                    <td>
                      <p class="mb-1 pl-1">
                        Comments/Text: "Thanks for Shopping"
                      </p>
                    </td>
                  </tr>
                </table>

                <table class="option-list">
                  <tr>
                    <td>
                      <img
                        src="/assets/img/image.png"
                        width="20"
                        height="15"
                        alt="Logo"
                      />
                    </td>
                    <td><p class="mb-1 pl-1">Logo: logo.png</p></td>
                  </tr>
                </table>

                <table class="quantity-table mt-2">
                  <tr>
                    <td>
                      <img
                        src="/assets/img/qty.png"
                        width="21"
                        height="8"
                        alt="Quantity"
                      />
                    </td>
                    <td><p class="mb-2 pl-1">Quantity: 2</p></td>
                  </tr>
                </table>
              </div>

              <div class="right-content">
                <!-- <img :src="item.product.img_path" alt="" /> -->
              </div>
            </div>
          </v-flex>
        </v-layout>
      </div>

      <!-- footer -->
      <div class="final-proof-footer">
        <div class="top-section">
          <div style="margin-top: 12px; margin-bottom: 8px">
            ORDER # MEC_EO-150454_AbingstonStopNGas
          </div>
          <div style="margin-top: 12px; margin-bottom: 10px">
            <!-- PAGE <span style="margin-left: 8px">1</span> OF 1 -->
          </div>
          <div style="margin-top: 12px; margin-bottom: 10px">
            Designer: Ryan Strawn
          </div>
        </div>
        <div class="bottom-section">
          <div class="logo">
            <img src="/assets/img/ww.png" alt="" />
          </div>
          <div class="order">
            <div class="order-type">
              <img src="/assets/img/man.png" alt="" />
              <div style="margin-top: 12px">Ordered By</div>
            </div>

            <div class="text-content">
              <p>Johnboy VanSampson</p>
              <p>[email protected]</p>
              <p>720-555-5698</p>
            </div>
          </div>
          <div class="location">
            <div class="order-type">
              <img src="/assets/img/shop.png" alt="" />
              <div style="margin-top: 12px">Project</div>
              <div>Location</div>
            </div>
            <div class="text-content">
              <p>Abington Stop N Gas</p>
              <p>Attn:Johnboy VanSampson</p>
              <p>1562 Hiltop Pallace Blvd.</p>
              <p>Swingtown, NJ 77895</p>
            </div>
          </div>
          <div class="shipping">
            <div class="order-type">
              <img src="/assets/img/car.png" alt="" />
              <div style="margin-top: 12px">Shipping</div>
            </div>
            <div class="text-content">
              <p>Abington Stop N Gas</p>
              <p>Attn:Johnboy VanSampson</p>
              <p>1562 Hiltop Pallace Blvd.</p>
              <p>Swingtown, NJ 77895</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { jsPDF } from "jspdf";

export default {
  props: {
    value: {
      type: Object,
    },
  },

  data() {
    return {
      order: {},
      htmlToPdfOptions: {
        html2canvas: {
          useCORS: true,
          scale: 2,
        },
        jsPDF: {
          //   unit: "px",
          format: "letter",
          orientation: "landscape",
        },
      },
    };
  },

  watch: {
    value(val) {
      this.order = val;
    },
  },

  mounted() {
    const vm = this;
    // vm.generateReport();
  },

  methods: {
    async generateReport() {
      const vm = this;
      const doc = new jsPDF({
        orientation: "l",
        unit: "px",
        format: "letter",
        hotfixes: ["px_scaling"],
        compress: true,
      });
      doc.html(vm.$refs.order_details, {
        margin: 10,
        autoPaging: "slice",
        html2canvas: {
          scale: 0.8,
        },
        pagesplit: true,
        callback: function (doc) {
          doc.save("test.pdf");
        },
      });
    },
  },
};
</script>

Upvotes: 0

Views: 10879

Answers (1)

aholake
aholake

Reputation: 86

atm, I don't see any property or function to support page break when printing HTML element, you just can do it manually via doc.addPage().

To add header and footer on each page, you can iterate each page of doc, then attach your header and footer to suitable position.

For example:

for (let i = 1; i <= doc.getNumberOfPages(); i++) {
  doc.setPage(i)
  doc.text('This is header', 10, 30)
}

Upvotes: 0

Related Questions