自动计数页数并显示打印页数

问题描述 投票:0回答:1

我一直在开发一个 Vue.js 应用程序来生成发票,此过程的一部分涉及确保每个打印页面显示正确的页码。然而,我遇到了一个障碍:当我打印发票时,所有页面都被标记为“第 1 页,共 20 页”,无论它们在文档中的实际位置如何。这种不一致令人费解,我不知道如何解决它。任何有关故障排除和解决此问题的见解或建议将不胜感激。 这是代码:

<template>
  <div style="background-color: lightgray" >
    <div style="background-color: white;margin: auto;width: 29.7cm" id="printable-content">
      <div class="tfoot " id="pageFooter" style="display: none">
        <div class="footerHolder" style="">
          <div class="invoice-footer">
            <div class="" style="border: 1px solid lightgray;border-radius: 8px;padding: 10px 10px 0">
              <div style="display: flex;justify-content: space-between;gap: 30px">
                <div style="width: 50%;border-right: 1px solid lightgray;padding-right: 10px">
                  <h6 class="font-size-12">Köpare</h6>
                  <div style="display: flex;justify-content: space-between;gap: 20px">
                    <div style="width: 50%;">
                      <label for="">Datum</label>
                    </div>
                    <div style="width: 50%;">
                      <label for="">Ort</label>
                    </div>
                  </div>
                  <div class="pb-2">
                    <label for="">Signatur</label>
                  </div>
                </div>
                <div style="width: 50%">
                  <h6 class="font-size-12">Säljare</h6>
                  <div style="display: flex;justify-content: space-between;gap: 20px">
                    <div style="width: 50%;">
                      <label for="">Datum</label>
                    </div>
                    <div style="width: 50%;">
                      <label for="">Ort</label>
                    </div>
                  </div>
                  <div class="pb-2">
                    <label for="">Signatur</label>
                  </div>
                </div>
              </div>
            </div>
            <small style="font-size: 8px"> Köparen har tagit del av och godkänt Testbolaget Bil ABs
              integritetspolicy</small>
            <div class="mt-2"
                 style=" display: flex; justify-content: space-between; border-top: 1px solid lightgray;  padding: 10px;">
              <div>
                <h6 class="font-size-12">xxx</h6>
                <div class="font-size-10">
                  <div>Munkforsplan 37</div>
                  <div> xxxxxx</div>
                  <div> xxxx</div>
                  <div>xxxxxx</div>
                </div>
              </div>
              <div>
                <h6 class="font-size-12">Kontaktuppgifter</h6>
                <div class="d-flex gap-1 font-size-10">
                  <div>
                    <div>Telefon:</div>
                    <div>E-post</div>
                    <div>Hemsidan:</div>
                    <div>Adress:</div>
                  </div>
                  <div>
                    <div>xxx</div>
                    <div>xxx</div>
                    <div>xxx</div>
                    <div>xxxxxxx</div>
                  </div>
                </div>
              </div>
              <div>
                <h6 class="font-size-12">Betalningsuppgifter</h6>
                <div class="d-flex gap-1 font-size-10">
                  <div>
                    <div>Bank:</div>
                    <div>Bankkonto</div>
                    <div>Bankgiro:</div>
                    <div>Plusgiro:</div>
                    <div>Swish:</div>
                  </div>
                  <div>
                    <div>SEB</div>
                    <div>2311 321231233122</div>
                    <div>321-31111</div>
                    <div>321-31111</div>
                    <div>S070 414 3308</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- Display the page number -->
        <div class="page-number"></div>
      </div>
      <table >
        <thead>
        <tr>
          <td>
            <div class="invoice-header d-flex align-baseline justify-content-between">
              <div class="d-flex align-baseline justify-content-between flex-column">
                <div>
                  <h2 style="  font-weight: 500; color: #191919;font-size: 32px">Köpavtal</h2>
                  <div>No:12312312312312</div>
                  <div>Invoice date: 12312312312312</div>
                  <div>xxx</div>
                </div>

              </div>
              <div class="d-flex align-baseline  flex-column">
             
                <div class="mt-2">
                  <h5>Kunduppgifter</h5>
                  <div>xxxxx</div>
                  <div>xxxxx</div>
                  <div>xxxxxxx</div>
                  <div>xxxxxxx</div>
                </div>

              </div>

            </div>
            <div class="page-header-space"></div>
          </td>
        </tr>
        </thead>
        <tbody>
        <tr>
          <td>
            <div class="invoice-body mt-1">
              <div style="" class="mb-3">
                <h5>text</h5>
                <div style="border: 1px solid lightgray; border-radius: 8px; display: flex; flex-direction: column;">
                  <div
                      style="    display: flex; justify-content: space-between; border-bottom: 1px solid lightgray;  padding: 10px;">
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>text-text -text</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                  </div>
                  <div style="    display: flex; justify-content: space-between;  padding: 10px;">
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>654564</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">text</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">Garanti</label>
                      <div>text</div>
                    </div>
                    <div>
                      <label for="">Momsredovisning</label>
                      <div>text</div>
                    </div>
                  </div>
                </div>
              </div>
              <div class="invoiceTableHolder">
                <table class="invoice-table table">
                  <thead>
                  <tr>
                    <th>Item</th>
                    <th>Qty</th>
                    <th>Pris ex.</th>
                    <th>Moms</th>
                    <th>Pris ink.</th>
                    <th>Totalt</th>
                  </tr>
                  </thead>
                  <tbody>
                  <tr v-for="(item,index) in items" :key="item.id">
                    <td>{{ item.name }} {{ index }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.price }} sek</td>
                    <td>{{ item.vat }} sek</td>
                    <td>{{ item.price_in }} sek</td>
                    <td>{{ item.totalt }} sek</td>
                  </tr>
                  <tr v-for="(item,index) in items" :key="item.id">
                    <td>{{ item.name }} {{ index }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.price }} sek</td>
                    <td>{{ item.vat }} sek</td>
                    <td>{{ item.price_in }} sek</td>
                    <td>{{ item.totalt }} sek</td>
                  </tr>
                  <tr v-for="(item,index) in items" :key="item.id">
                    <td>{{ item.name }} {{ index }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.price }} sek</td>
                    <td>{{ item.vat }} sek</td>
                    <td>{{ item.price_in }} sek</td>
                    <td>{{ item.totalt }} sek</td>
                  </tr>
                  <tr v-for="(item,index) in items" :key="item.id">
                    <td>{{ item.name }} {{ index }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.price }} sek</td>
                    <td>{{ item.vat }} sek</td>
                    <td>{{ item.price_in }} sek</td>
                    <td>{{ item.totalt }} sek</td>
                  </tr>
                  <tr v-for="(item,index) in items" :key="item.id">
                    <td>{{ item.name }} {{ index }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.price }} sek</td>
                    <td>{{ item.vat }} sek</td>
                    <td>{{ item.price_in }} sek</td>
                    <td>{{ item.totalt }} sek</td>
                  </tr>
                  <tr v-for="(item,index) in items" :key="item.id">
                    <td>{{ item.name }} {{ index }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.price }} sek</td>
                    <td>{{ item.vat }} sek</td>
                    <td>{{ item.price_in }} sek</td>
                    <td>{{ item.totalt }} sek</td>
                  </tr>

                  </tbody>
                </table>
              </div>
              <div class="mt-2 rejectBreak" style="border: 1px solid lightgray;border-radius: 8px;padding: 10px">
                <div class="finansHolder d-flex">
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx %</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx %</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxxr</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                  <div>
                    <label for="">xxx</label>
                    <div>xxx</div>
                  </div>
                </div>
              </div>
              <div class="mt-2 mb-3 rejectBreak" style="border: 1px solid lightgray;border-radius: 8px;padding: 10px">
                <h6 class="font-size-12">Notering</h6>
                <div style="min-height: 10px">
                  Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean
                  massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
                </div>
              </div>
            </div>
          </td>
        </tr>
        </tbody>
        <tfoot>
        <tr>
          <td>
            <div class="tfootHolder">
              <div class="footerHolder" style="">
                <div class="invoice-footer">
                  <div class="" style="border: 1px solid lightgray;border-radius: 8px;padding: 10px 10px 0">
                    <div style="display: flex;justify-content: space-between;gap: 30px">
                      <div style="width: 50%;border-right: 1px solid lightgray;padding-right: 10px">
                        <h6 class="font-size-12">Köpare11</h6>
                        <div style="display: flex;justify-content: space-between;gap: 20px">
                          <div style="width: 50%;">
                            <label for="">Datum</label>
                          </div>
                          <div style="width: 50%;">
                            <label for="">Ort</label>
                          </div>
                        </div>
                        <div class="pb-2">
                          <label for="">Signatur</label>
                        </div>
                      </div>
                      <div style="width: 50%">
                        <h6 class="font-size-12">Säljare</h6>
                        <div style="display: flex;justify-content: space-between;gap: 20px">
                          <div style="width: 50%;">
                            <label for="">Datum</label>
                          </div>
                          <div style="width: 50%;">
                            <label for="">Ort</label>
                          </div>
                        </div>
                        <div class="pb-2">
                          <label for="">Signatur</label>
                        </div>
                      </div>
                    </div>
                  </div>
                  <small style="font-size: 8px"> Köparen har tagit del av och godkänt Testbolaget Bil ABs
                    integritetspolicy</small>
                  <div class="mt-2"
                       style=" display: flex; justify-content: space-between; border-top: 1px solid lightgray;  padding: 10px;">
                    <div>
                      <h6 class="font-size-12">xxx</h6>
                      <div class="font-size-10">
                        <div>xxx 37</div>
                        <div> xxxxxx</div>
                        <div> xxxx</div>
                        <div>xxxxxx</div>
                      </div>
                    </div>
                    <div>
                      <h6 class="font-size-12">Kontaktuppgifter</h6>
                      <div class="d-flex gap-1 font-size-10">
                        <div>
                          <div>Telefon:</div>
                          <div>E-post</div>
                          <div>Hemsidan:</div>
                          <div>Adress:</div>
                        </div>
                        <div>
                          <div>xxxxx</div>
                          <div>xxxx</div>
                          <div>xxxx</div>
                          <div>xxxxxxx</div>
                        </div>
                      </div>
                    </div>
                    <div>
                      <h6 class="font-size-12">Betalningsuppgifter</h6>
                      <div class="d-flex gap-1 font-size-10">
                        <div>
                          <div>Bank:</div>
                          <div>Bankkonto</div>
                          <div>Bankgiro:</div>
                          <div>Plusgiro:</div>
                          <div>Swish:</div>
                        </div>
                        <div>
                          <div>xx</div>
                          <div>xxx</div>
                          <div>xx-x</div>
                          <div>xxx-xxx</div>
                          <div>xxx</div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div class="page-footer-space"></div>
            </div>
            <div class="page-footer-space"></div>
          </td>
        </tr>
        </tfoot>
      </table>
    </div>
  </div>

  <div class="invoice">
    <!-- Your invoice content here -->

    <!-- Page number -->
    <span class="page-number"> <span class="page-counter"></span></span>
  </div>


</template>
<script>

export default {
  data() {
    return {
      pageNumber: 1, // Initialize the page number
      items: [
        {name: "Item 1", quantity: 2, price: 10, vat: 20, price_in: 1200, totalt: 2000},
        {name: "Item 2 with a long name that needs to be truncated", quantity: 1, price: 20},
        {name: "Item 3", quantity: 3, price: 15},
        {name: "Item 1", quantity: 2, price: 10},
        {name: "Item 2 with a long name that needs to be truncated", quantity: 1, price: 20},
        {name: "Item 3", quantity: 3, price: 15},
        {name: "Item 3", quantity: 3, price: 15},

      ]
    };

    
  },
 
  methods: {
  limitNameLength(name) {
    const maxLength = 20;
    return name.length > maxLength ? name.substring(0, maxLength) + '...' : name;
  },
  updatePageCounter(totalPages) {
    const currentPage = this.pageNumber; // Use the component's data property
    this.$nextTick(() => {
      const pageCounterElement = document.querySelector('.page-counter');
      if (pageCounterElement) {
        document.querySelector('.page-counter').textContent = currentPage;
        pageCounterElement.textContent = `Page ${currentPage} of ${totalPages}`;
      }
    });
  },
},

mounted() {
    const totalPages = 20;
    this.updatePageCounter(totalPages);
  },


};

</script>

<style lang="scss">
thead td, tfoot td {
  padding: 20px;
}

tbody tr td {
  padding: 5px 20px;
}


.rejectBreak {
  page-break-after: always;
}


@media print {
  .page-footer {
    position: fixed;
    bottom: 0;
    right: 0;
    left: 0;
    padding: 10px;
    background-color: white;
    border-top: 1px solid lightgray;
    text-align: right;
  thead {
    display: table-header-group;
  }
  }

  tfoot {
    display: table-footer-group;
  }

  button {
    display: none;
  }

  body {
    margin: 0;
  }

  tfoot .tfootHolder {
    display: none;
  }
  .tfoot {
    display: block !important;
    padding: 20px;
    position: fixed;
    bottom: 0;
    width: 29.7cm;

  }
  .page-footer-space {
    height: 300px;
  }

  @page {
    size: A4;
  }


  .page {
    page-break-after: always;
    position: relative;
    height: 95vh; /* Adjust based on your content and page size */
    padding: 20px;
  }
  .page:last-child {
    page-break-after: avoid;
  }
  .page-number {
    position:fixed;
    bottom: 10px;
    right: 50px;
    font-size: 12px;
  }

  .page-counter::before {
  content: counter(); 
} 
}

</style>

许多 vue 代码可以正确计数但不起作用。

javascript html css vue.js
1个回答
0
投票

在 Vue 中,不应使用

document.querySelector
,而应使用
ref
(如果使用 Vue 3):

<template>
<div ref="myDiv">lorem ipsum</div>
</template>

<script>
const myDiv = ref(null); // Initialize as null, make sure the variable has the same name as the ref attribute on the div.
</script>

在 Vue 2 中,你会这样做:

<template>
<div ref="myDiv">lorem ipsum</div>
</template>

<script>
export default {
  mounted() {
    this.$refs.myDiv.innerHTML = 'Page number…';
  }
}
</script>

另外,我不确定当您处于打印对话框中时 $nextTick 是否会起作用。

一个想法:

循环查看发票并设置每张发票的高度

<div>
以匹配您要打印的纸张:

<div class="page" v-for="(invoice, index) in invoices" :key="invoice">
  <span>Page {{ index + 1 }}</span>
</div>

<style>
@media print {
  .page {
    height: 793px; /* about 1 A4 page */
    break-after: always; /* force page break */
  }
}
</style>
© www.soinside.com 2019 - 2024. All rights reserved.