一、安装vue3-print-nb

npm install vue3-print-nb --save
yarn add vue3-print-nb


二、引入Vue项目

// 1. 全局挂载
import { createApp } from 'vue'
import App from './App.vue'
import print from 'vue3-print-nb'
const app = createApp(App)
app.use(print)
app.mount('#app')
 
 
// 2. 自定义指令
import print from 'vue3-print-nb'
directives: {
    print   
}


三、简单使用案例

1、在components目录下新建penaltyRequestForm.vue

<script setup>
import { reactive, ref } from "vue";

let penaltyRequestForm = reactive({
  // id
  id: '',
  // 罚款单编号
  number: "20241025001",
  // 被扣款单位和个人
  deductionPerson : "代雄伟",
  // 扣款事项
  deductionMatters: "就是想扣你钱",
  // 扣款金额
  deductionAmount: "64800.00",
  // 扣款方式
  deductionMethod: "运费/工资中扣除",
  // 备注
  remark: "备注备注备注备注备注",
  // 分管领导审批
  departmentHeadApproval: "孙总",
  // 财务审核
  financialReview: "祝总",
  // 部门审核
  departmentReview: "李总",
  // 创建时间
  createTime: "2024年12月13日",
});
</script>

<template>
  <div>
    <div class="bottom-list">
      <div class="line-center">
        <span style="text-align: center;font-size: 28px;font-weight: bold;">重庆XXXXXXXX有限公司</span>
      </div>
      <div class="line-center">
        <span style="text-align: center; font-size: 24px;font-weight: bold;">扣(罚)款通知单</span>
      </div>
      <div class="line-right">
        <span style="text-align: right; font-weight: bold;">编号:<span style="padding: 0 2px">{{ penaltyRequestForm.number }}     </span></span>
      </div>
      <div class="g-grid-box">

        <div class="g-grid6">
          <div class="g-item center">被扣款单位/个人</div>
          <div class="g-item center">扣款事项</div>
          <div class="g-item center">扣款金额(单位:元)</div>
          <div class="g-item center">扣款方式</div>
          <div class="g-item center">备注</div>
        </div>

        <div class="g-grid6">
          <div class="g-item">{{ penaltyRequestForm.deductionPerson }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionMatters }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionAmount }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionMethod }}</div>
          <div class="g-item">{{ penaltyRequestForm.remark }}</div>
        </div>

      </div>
      <div class="g-grid5">
        <div><span style="text-align: center; font-size: 14px;">注:本通知单一式三联,当事单位(人)、制表部门、财务部门各执一份。</span></div>
      </div>

      <div class="g-grid4">
        <div>
          分管领导审批:
          <span>{{ penaltyRequestForm.departmentHeadApproval }}</span>
        </div>
        <div>
          财务审核:
          <span>{{ penaltyRequestForm.financialReview }}</span>
        </div>
        <div>
          部门审核:
          <span>{{ penaltyRequestForm.departmentReview }}</span>
        </div>
      </div>

      <div class="g-grid5">
        <div style="display:flex;justify-content: flex-end;"><span>制表日期:  {{ penaltyRequestForm.createTime }}        </span></div>
      </div>

    </div>


    <div sytle="height: 50px;"> </div>
    <div sytle="height: 50px;"> </div>
    <div class="xuxian"></div>
    <div sytle="height: 50px;"> </div>
    <div sytle="height: 50px;"> </div>

    <div class="bottom-list">
      <div class="line-center">
        <span style="text-align: center;font-size: 28px;font-weight: bold;">重庆XXXXXXXX有限公司</span>
      </div>
      <div class="line-center">
        <span style="text-align: center; font-size: 24px;font-weight: bold;">扣(罚)款通知单</span>
      </div>
      <div class="line-right">
        <span style="text-align: right; font-weight: bold;">编号:<span style="padding: 0 2px">{{ penaltyRequestForm.number }}     </span></span>
      </div>
      <div class="g-grid-box">

        <div class="g-grid6">
          <div class="g-item center">被扣款单位/个人</div>
          <div class="g-item center">扣款事项</div>
          <div class="g-item center">扣款金额(单位:元)</div>
          <div class="g-item center">扣款方式</div>
          <div class="g-item center">备注</div>
        </div>

        <div class="g-grid6">
          <div class="g-item">{{ penaltyRequestForm.deductionPerson }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionMatters }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionAmount }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionMethod }}</div>
          <div class="g-item">{{ penaltyRequestForm.remark }}</div>
        </div>

      </div>
      <div class="g-grid5">
        <div><span style="text-align: center; font-size: 14px;">注:本通知单一式三联,当事单位(人)、制表部门、财务部门各执一份。</span></div>
      </div>

      <div class="g-grid4">
        <div>
          分管领导审批:
          <span>{{ penaltyRequestForm.departmentHeadApproval }}</span>
        </div>
        <div>
          财务审核:
          <span>{{ penaltyRequestForm.financialReview }}</span>
        </div>
        <div>
          部门审核:
          <span>{{ penaltyRequestForm.departmentReview }}</span>
        </div>
      </div>

      <div class="g-grid5">
        <div style="display:flex;justify-content: flex-end;"><span>制表日期:  {{ penaltyRequestForm.createTime }}        </span></div>
      </div>

    </div>


    <div sytle="height: 50px;"> </div>
    <div sytle="height: 50px;"> </div>
    <div class="xuxian"></div>
    <div sytle="height: 50px;"> </div>
    <div sytle="height: 50px;"> </div>


    <div class="bottom-list">
      <div class="line-center">
        <span style="text-align: center;font-size: 28px;font-weight: bold;">重庆XXXXXXXX有限公司</span>
      </div>
      <div class="line-center">
        <span style="text-align: center; font-size: 24px;font-weight: bold;">扣(罚)款通知单</span>
      </div>
      <div class="line-right">
        <span style="text-align: right; font-weight: bold;">编号:<span style="padding: 0 2px">{{ penaltyRequestForm.number }}     </span></span>
      </div>
      <div class="g-grid-box">

        <div class="g-grid6">
          <div class="g-item center">被扣款单位/个人</div>
          <div class="g-item center">扣款事项</div>
          <div class="g-item center">扣款金额(单位:元)</div>
          <div class="g-item center">扣款方式</div>
          <div class="g-item center">备注</div>
        </div>

        <div class="g-grid6">
          <div class="g-item">{{ penaltyRequestForm.deductionPerson }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionMatters }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionAmount }}</div>
          <div class="g-item">{{ penaltyRequestForm.deductionMethod }}</div>
          <div class="g-item">{{ penaltyRequestForm.remark }}</div>
        </div>

      </div>
      <div class="g-grid5">
        <div><span style="text-align: center; font-size: 14px;">注:本通知单一式三联,当事单位(人)、制表部门、财务部门各执一份。</span></div>
      </div>

      <div class="g-grid4">
        <div>
          分管领导审批:
          <span>{{ penaltyRequestForm.departmentHeadApproval }}</span>
        </div>
        <div>
          财务审核:
          <span>{{ penaltyRequestForm.financialReview }}</span>
        </div>
        <div>
          部门审核:
          <span>{{ penaltyRequestForm.departmentReview }}</span>
        </div>
      </div>

      <div class="g-grid5">
        <div style="display:flex;justify-content: flex-end;"><span>制表日期:  {{ penaltyRequestForm.createTime }}        </span></div>
      </div>

    </div>

  </div>
</template>

<style scoped>
.g-grid-box {
  border: 1px solid #666666;
}
.g-item {
  line-height: 30px;
  border: 1px solid #666666;
  padding: 4px;
}
.center {
  text-align: center;
}
.g-grid {
  display: grid;
  grid-template-columns: 130px 1fr 130px 1fr;
}
.g-grid1 {
  display: grid;
  grid-template-columns: 130px 1fr;
}
.g-grid2 {
  display: grid;
  grid-template-columns: 130px 1fr 130px 1fr;
}
.grid3 {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.g-grid4 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
.g-grid4 div {
  padding: 2px;
}
.g-grid4 div span {
  padding: 0 2px;
}
.checkbox-custom {
  width: 18px; /* 调整多选框宽度 */
  height: 18px; /* 调整多选框高度 */
  background-color: #fff;
  border: 2px solid #666666;
  border-radius: 4px;
  position: relative;
  cursor: pointer;
  display: inline-block;
  margin-left: 10px;
}

.checkbox-custom::after {
  content: "";
  width: 6px; /* 调整勾选标记的宽度 */
  height: 12px; /* 调整勾选标记的高度 */
  border: solid #666666;
  border-width: 0 2px 2px 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  opacity: 0; /* 默认隐藏 */
}

.checkbox-custom.checked::after {
  opacity: 1; /* 显示勾选标记 */
}
.method-box {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 0 20px;
}
.method-box div {
  display: flex;
  align-items: center;
}
.g-grid5 {
  display: grid;
  grid-template-columns: 1fr;
}
.g-grid5 div {
  padding: 2px;
}
.g-grid5 div span {
  padding: 0 2px;
}
.g-grid6 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
}
.line-center {
  display: flex;
  flex-direction:row;
  justify-content: center;
  align-items: center;
}
.line-right {
  display: flex;
  flex-direction:row;
  justify-content: flex-end;
  align-items: center;
}
.xuxian {
  height: 0;
  width: 100%;
  border-bottom: 1px dashed #ccc;
}
</style>

2、在components目录下新建paymentRequestForm.vue

<script setup>
import { reactive, ref } from "vue";
let paymentRequestForm = reactive({
  // id
  id: '',
  // 申请日期
  requestDate: "2024年12月12日",
  // 收款单位
  payee: "重庆收费有限公司",
  // 收款地址
  payeeAddress: "重庆市江北区观音桥街道建新北路1号",
  // 开户银行
  bankName: "中国建设银行重庆分行沙坪坝支行",
  // 账号
  account: "62220231234567890",
  // 付款金额¥
  paymentAmount: "678860.00",
  // 款项用途
  paymentPurpose: "你该付钱那!!!",
  // 付款金额(大写)
  paymentAmountInWords: "陆拾柒万捌千捌佰陆拾元",
  // 申请部门
  applyingDepartment: "重庆办事处",
  // 申请人
  applicant: "代某某",
  // 对账确认
  reconciliationConfirmation: "付某",
  // 开票确认
  invoicingConfirmation: "李某",
  // 付款方式
  paymentMethod: {
    // 银行转账
    bankTransfer: false,
    // 汇款
    remittance: false,
    // 现金
    cash: true,
  },
  // 备注
  remark: "备注备注备注备注备注备注",
  // 分管领导审批
  departmentHeadApproval: "孙总",
  // 财务审核
  financialReview: "祝总",
  // 部门审核
  departmentReview: "李总",
});
</script>

<template>
  <div>
    <div class="bottom-list">
      <h1 style="text-align: center">重庆XXXXXXXX有限公司</h1>
      <h2 style="text-align: center">付款申请单</h2>
      <h3 style="text-align: right">
        申请日期:
        <span style="padding: 0 10px">{{ paymentRequestForm.requestDate }}</span>
      </h3>

      <div class="g-grid-box">
        <div class="g-grid">
          <div class="g-item center">收款单位</div>
          <div class="g-item">{{ paymentRequestForm.payee }}</div>
          <div class="g-item center">收款地址</div>
          <div class="g-item">{{ paymentRequestForm.payeeAddress }}</div>
        </div>
        <div class="g-grid">
          <div class="g-item center">开户银行</div>
          <div class="g-item">
            {{ paymentRequestForm.bankName }}
          </div>
          <div class="g-item center">账号</div>
          <div class="g-item">{{ paymentRequestForm.account }}</div>
        </div>

        <div class="g-grid">
          <div class="g-item center">付款金额¥</div>
          <div class="g-item">{{ paymentRequestForm.paymentAmount }}</div>
          <div class="g-item center">款项用途</div>
          <div class="g-item">{{ paymentRequestForm.paymentPurpose }}</div>
        </div>

        <div class="g-grid1">
          <div class="g-item center">付款金额(大写)</div>
          <div class="g-item" colspan="6">
            {{ paymentRequestForm.paymentAmountInWords }}
          </div>
        </div>

        <div class="g-grid">
          <div class="g-item center">申请部门</div>
          <div class="g-item">{{ paymentRequestForm.applyingDepartment }}</div>
          <div class="g-item center">申请人</div>
          <div class="g-item">{{ paymentRequestForm.applicant }}</div>
        </div>

        <div class="grid3">
          <div class="g-grid">
            <div class="g-item center">对账确认</div>
            <div class="g-item">
              {{ paymentRequestForm.reconciliationConfirmation }}
            </div>
            <div class="g-item center">开票确认</div>
            <div class="g-item">
              {{ paymentRequestForm.invoicingConfirmation }}
            </div>
          </div>
          <div class="g-grid1">
            <div class="g-item center">付款方式</div>
            <div class="g-item method-box">
              <div>
                转账
                <span
                  :class="{ 'checkbox-custom': true, checked: paymentRequestForm.paymentMethod.bankTransfer }"
                ></span>
              </div>
              <div>
                汇款
                <span
                  :class="{ 'checkbox-custom': true, checked: paymentRequestForm.paymentMethod.remittance }"
                ></span>
              </div>
              <div>
                现金
                <span
                  :class="{ 'checkbox-custom': true, checked: paymentRequestForm.paymentMethod.cash }"
                ></span>
              </div>
            </div>
          </div>
        </div>

        <div class="g-grid1">
          <div class="g-item center" style="line-height: 80px">备注</div>
          <div class="g-item" colspan="6">{{ paymentRequestForm.remark }}</div>
        </div>
      </div>
      <div class="g-grid4">
        <div>
          分管领导审批:
          <span>{{ paymentRequestForm.departmentHeadApproval }}</span>
        </div>
        <div>
          财务审核:
          <span>{{ paymentRequestForm.financialReview }}</span>
        </div>
        <div>
          部门审核:
          <span>
            {{ paymentRequestForm.departmentReview }}
          </span>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.g-grid-box {
  border: 1px solid #666666;
}
.g-item {
  line-height: 40px;
  border: 1px solid #666666;
  padding: 8px;
}
.center {
  text-align: center;
}
.g-grid {
  display: grid;
  grid-template-columns: 130px 1fr 130px 1fr;
}
.g-grid1 {
  display: grid;
  grid-template-columns: 130px 1fr;
}
.g-grid2 {
  display: grid;
  grid-template-columns: 130px 1fr 130px 1fr;
}
.grid3 {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.g-grid4 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
.g-grid4 div {
  padding: 10px;
}
.g-grid4 div span {
  padding: 0 10px;
}
.checkbox-custom {
  width: 18px; /* 调整多选框宽度 */
  height: 18px; /* 调整多选框高度 */
  background-color: #fff;
  border: 2px solid #666666;
  border-radius: 4px;
  position: relative;
  cursor: pointer;
  display: inline-block;
  margin-left: 10px;
}

.checkbox-custom::after {
  content: "";
  width: 6px; /* 调整勾选标记的宽度 */
  height: 12px; /* 调整勾选标记的高度 */
  border: solid #666666;
  border-width: 0 2px 2px 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  opacity: 0; /* 默认隐藏 */
}

.checkbox-custom.checked::after {
  opacity: 1; /* 显示勾选标记 */
}
.method-box {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 0 20px;
}
.method-box div {
  display: flex;
  align-items: center;
}
</style>

3、App.vue修改内容如下

<script setup>
import PenaltyRequisition from "./components/PenaltyRequisition.vue";
import PaymentRequisition from "./components/PaymentRequisition.vue";
</script>

<template>
  <div id="PenaltyRequisition">
    <PenaltyRequisition />
  </div>
  <button v-print="'PenaltyRequisition'">Print1</button>
  <div id="PaymentRequisition">
    <PaymentRequisition />
  </div>
  <button v-print="'PaymentRequisition'">Print2</button>
</template>

<style>
@media print {
}
</style>



4、打开页面出现的效果

vue3使用vue3-print-nb多打印一个空白页情况排查_多选框

5、点击打印1出现的效果

vue3使用vue3-print-nb多打印一个空白页情况排查_多选框_02

6、点击打印2出现的效果

vue3使用vue3-print-nb多打印一个空白页情况排查_App_03



四、通过添加border来测试解决问题

在一次使用vue的print.js打印简历的时候,会多出一个空白页,百度了一些博客,大致方法就是设置margin:0;但是我的项目依然是没有用。

突然想到了把边框打印出来,使用border:1px solid red;点击打印,发现空白页消失了,由于打印的是白色的纸,所以设置border:1px solid white;就可以解决此问题!

https://blog.csdn.net/jjsmida1/article/details/116919011

使用vue3-print-nb出现一个空白页,百度是找到改文章,我也引入使用。也是加上了border测试就OK了。

vue3使用vue3-print-nb多打印一个空白页情况排查_App_04

vue3使用vue3-print-nb多打印一个空白页情况排查_多选框_05

加上:style="border:1px solid white;" 或者 style="border:1px solid red;"

vue3使用vue3-print-nb多打印一个空白页情况排查_多选框_06

vue3使用vue3-print-nb多打印一个空白页情况排查_ci_07

打印时只有1页了,后面只需要把red修改成white;把颜色由红边框修改成白边框,这样就看不见了。



五、通过查看打印内部元素是否有margin导致出险空白页

其它几乎所有的多打印一个空白页都是让查看打印内容是否有margin相关元素导致的,如果有考虑把由margin该为有padding实现。

1、height的100%可以考虑height为auto;

vue3使用vue3-print-nb多打印一个空白页情况排查_多选框_08

2、如果打印的是整页,则需要关注html的height和margin

html {
    height: auto;
    margin: 0px;
}