Vue3+TS:A4纸横向打印单据,固定表头页面,动态分页方法

需求:

A4纸横向打印,标题、基本信息、表头、页码等内容固定显示,表格内容根据实际高度进行分页

基本思路:

1.将打印内容放在div中,固定div宽高为A4纸横向宽高
2.将内容先不分页全部在div中显示,根据原生方法获取标题、基本信息、表头、页码、所有行的######表体高度,根据纸张高度-标题-基本信息-表头-页码的高度和实际表体高度来判断是否需要分页
3.需要分页则循环表体行,获取每一行的高度并求和,当高度之和>表体高度则在上一行标记需要换行
4.循环所有数据,在标记换行的数据上进行分割换行

预览效果

在这里插入图片描述
注:

  1. 使用原生的方法获取高度,通过设置id,不同的单据以单据号来标记唯一id,不同行以行id来标记唯一id
  2. 控制虚拟bom不显示通过 use-get-height 类
  3. 通过定位让页码固定在页面下边
  4. 后台返回的数据格式是,可以同时勾选多条单据打印
    在这里插入图片描述

代码:

a. 做两个div存放,一个是不分页的情况,用于计算实际高度(因为想要获取高度,必须渲染完成,所以写一个div,画上基本样式);一个是经过分割后分页的样式及分页循环逻辑
<!-- 虚拟bom,用于计算高度,实际不显示,通过 use-get-height 类来控制不显示 -->
<div class="page_div use-get-height">
    <div id="totalDiv" class="print_div">
        <div v-for="(ele, index) in states.tableData" :key="index" class="page">
            <div id="pageHeight" class="page_height">
                <div id="printTitle" class="print_title">
                    {{ ele.companyName }}交货单
                </div>
                <div id="msgTitle" class="msg_title">基本信息:</div>
                <div id="topDiv">
                    <el-row>
                        <el-col :span="21">
                            <table ref="topTableRef" class="msg_table">
                                <tr>
                                    <td class="table_td_title_left">交货单号</td>
                                    <td class="table_td_left">{{ ele.deliveryNo }}</td>
                                    <td class="table_td_title">工作令</td>
                                    <td class="table_td_center">{{ ele.workOrder }}</td>
                                    <td class="table_td_title">需求交货日期</td>
                                    <td class="table_td">{{ ele.deliveryTime }}</td>
                                </tr>
                                <tr>
                                    <td class="table_td_title_left">发料仓库</td>
                                    <td class="table_td_left">
                                        {{ ele.deliveryWarehouseName }}
                                    </td>
                                    <td class="table_td_title">收货单位编码</td>
                                    <td class="table_td_center">{{ ele.receiveNo }}</td>
                                    <td class="table_td_title">收货单位名称</td>
                                    <td class="table_td">{{ ele.receiveName }}</td>
                                </tr>
                                <tr>
                                    <td class="table_td_title_left">收货人</td>
                                    <td class="table_td_left">
                                        {{ ele.receivePerson }}
                                    </td>
                                    <td class="table_td_title">联系电话</td>
                                    <td class="table_td_center">{{ ele.phone }}</td>
                                    <td class="table_td_title">收货地址</td>
                                    <td colspan="3" class="table_td">
                                        {{ ele.receiveAddress }}
                                    </td>
                                </tr>
                            </table>
                        </el-col>
                        <el-col :span="3">
                            <div class="vue_qr">
                                <vue-qr
                                    :text="ele.deliveryNo"
                                    :margin="1"
                                    :size="100"
                                ></vue-qr>
                            </div>
                        </el-col>
                    </el-row>
                </div>
                <div class="msg_title">物料信息:</div>
                <div :id="`bottomDiv_${ele.deliveryNo}`">
                    <table class=" ">
                        <tr id="bottomTh">
                            <th class="material_table_td">序号</th>
                            <th class="material_table_td">物料编码</th>
                            <th class="material_table_td">物料名称</th>
                            <th class="material_table_td">规格</th>
                            <th class="material_table_td">型号</th>
                            <th class="material_table_td">交货数量(主)</th>
                            <th class="material_table_td">主单位</th>
                        </tr>
                        <tr
                            v-for="(item, indexs) in ele.wmsOutwardDeliveryDetailList"
                            :key="indexs"
                            :id="`bottomTd_${item.id}`"
                        >
                            <td class="material_table_td" style="width: 3%">
                                {{ Number(index) + Number(indexs) + 1 }}
                            </td>
                            <td class="material_table_td" style="width: 6%">
                                {{ item.materialCode }}
                            </td>
                            <td class="material_table_td" style="width: 10%">
                                {{ item.materialName }}
                            </td>
                            <td class="material_table_td" style="width: 10%">
                                {{ item.specification }}
                            </td>
                            <td class="material_table_td" style="width: 10%">
                                {{ item.model }}
                            </td>
                            <td class="material_table_td" style="width: 6%">
                                {{ item.outStockMainNum }}
                            </td>
                            <td class="material_table_td" style="width: 5%">
                                {{ item.basicUnitName }}
                            </td>
                        </tr>
                    </table>
                </div>
                <div id="pageMessage" class="page-message">
                    {{ index / states.printNumber + 1 }} /
                    {{
                        Math.ceil(
                            ele.wmsOutwardDeliveryDetailList.length /
                                states.printNumber,
                        )
                    }}
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 实际显示的bom,是已经分好页的打印预览,因为要想打印必须先预览所有内容 -->
<div class="page_div">
    <div id="totalDiv" ref="print" class="print_div">
    	<!-- 可以批量勾选多条单据,此处是循环不同的单据 -->
        <div v-for="(eleAll, indexAll) in states.allDataPrintPage" :key="indexAll">
        	<!-- 相同的单据需要分页,这里是循环不同的页码内容 -->
            <div v-for="(ele, index) in eleAll" :key="index" class="page">
                <div id="pageHeight" class="page_height">
                    <div id="printTitle" class="print_title">
                        {{ ele[0]?.mainList.companyName }}交货单
                    </div>
                    <div id="msgTitle" class="msg_title">基本信息:</div>
                    <div id="topDiv">
                        <el-row>
                            <el-col :span="21">
                                <table ref="topTableRef" class="msg_table">
                                    <tr>
                                        <td class="table_td_title_left">交货单号</td>
                                        <td class="table_td_left">
                                            {{ ele[0]?.mainList.deliveryNo }}
                                        </td>
                                        <td class="table_td_title">工作令</td>
                                        <td class="table_td_center">
                                            {{ ele[0]?.mainList.workOrder }}
                                        </td>
                                        <td class="table_td_title">需求交货日期</td>
                                        <td class="table_td">
                                            {{ ele[0]?.mainList.deliveryTime }}
                                        </td>
                                    </tr>
                                    <tr>
                                        <td class="table_td_title_left">发料仓库</td>
                                        <td class="table_td_left">
                                            {{ ele[0]?.mainList.deliveryWarehouseName }}
                                        </td>
                                        <td class="table_td_title">收货单位编码</td>
                                        <td class="table_td_center">
                                            {{ ele[0]?.mainList.receiveNo }}
                                        </td>
                                        <td class="table_td_title">收货单位名称</td>
                                        <td class="table_td">
                                            {{ ele[0]?.mainList.receiveName }}
                                        </td>
                                    </tr>
                                    <tr>
                                        <td class="table_td_title_left">收货人</td>
                                        <td class="table_td_left">
                                            {{ ele[0]?.mainList.receivePerson }}
                                        </td>
                                        <td class="table_td_title">联系电话</td>
                                        <td class="table_td_center">
                                            {{ ele[0]?.mainList.phone }}
                                        </td>
                                        <td class="table_td_title">收货地址</td>
                                        <td colspan="3" class="table_td">
                                            {{ ele[0]?.mainList.receiveAddress }}
                                        </td>
                                    </tr>
                                </table>
                            </el-col>
                            <el-col :span="3">
                                <div class="vue_qr">
                                    <vue-qr
                                        :text="ele[0]?.mainList.deliveryNo"
                                        :margin="1"
                                        :size="100"
                                    ></vue-qr>
                                </div>
                            </el-col>
                        </el-row>
                    </div>
                    <div class="msg_title">物料信息:</div>
                    <div :id="`bottomDiv_${ele[0]?.mainList.deliveryNo}`">
                        <table class=" ">
                            <tr id="bottomTh">
                                <th class="material_table_td">序号</th>
                                <th class="material_table_td">物料编码</th>
                                <th class="material_table_td">物料名称</th>
                                <th class="material_table_td">规格</th>
                                <th class="material_table_td">型号</th>
                                <th class="material_table_td">交货数量(主)</th>
                                <th class="material_table_td">主单位</th>
                            </tr>
                            <!-- 这里是循环具体的表格内容 -->
                            <tr
                                v-for="(item, indexs) in ele"
                                :key="indexs"
                                :id="`bottomTd_${item.id}`"
                            >
                                <td class="material_table_td" style="width: 3%">
                                    {{ Number(indexs) + 1 }}
                                </td>
                                <td class="material_table_td" style="width: 6%">
                                    {{ item.materialCode }}
                                </td>
                                <td class="material_table_td" style="width: 10%">
                                    {{ item.materialName }}
                                </td>
                                <td class="material_table_td" style="width: 10%">
                                    {{ item.specification }}
                                </td>
                                <td class="material_table_td" style="width: 10%">
                                    {{ item.model }}
                                </td>
                                <td class="material_table_td" style="width: 6%">
                                    {{ item.outStockMainNum }}
                                </td>
                                <td class="material_table_td" style="width: 5%">
                                    {{ item.basicUnitName }}
                                </td>
                            </tr>
                        </table>
                    </div>
                    <div id="pageMessage" class="page-message">
                        {{ Number(index) }} /
                        {{ Object.keys(eleAll).length }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
b. 打开弹窗时先调接口获取数据
// 获取数据
const getlistData = () => {
	// 此处调用接口
    states.tableData = res.data
	// 整理打印数据
	nextTick(() => {
		// 打开预览弹窗
	    states.dialogVisible = true
	    nextTick(() => {
    		// 获取页面整体高度,即A4纸横向高度 
	        let pageHeight = document.getElementById('pageHeight')
	        states.paperHeight = pageHeight.clientHeight
	        countPage() //计算分割点
	    })
	})
}
c. 将所有数据显示到页面上,获取实际行高,计算分割点
const countPage = () => {
    states.tableData.forEach(item => {
        let printTitle = document.getElementById('printTitle')
        let printTitleH = printTitle.clientHeight

        let msgTitle = document.getElementById('msgTitle')
        let msgTitleH = msgTitle.clientHeight

        let topDiv = document.getElementById('topDiv')
        let topDivH = topDiv.clientHeight < 100 ? 100 : topDiv.clientHeight

        let bottomTh = document.getElementById('bottomTh')
        let bottomThH = bottomTh.clientHeight

        let bottomDiv = document.getElementById(`bottomDiv_${item.deliveryNo}`)
        let bottomDivH = bottomDiv.clientHeight

        let pageMessage = document.getElementById('pageMessage')
        let pageMessageH = pageMessage.clientHeight
        // 动态表格内容的高度 = A4纸横向高度 - 打印标题高度 - 小标题高度*2 - 上面表格高度 - 下面表格的表头高度 - 页码高度
        let surplusHeight =
            states.paperHeight -
            printTitleH -
            msgTitleH -
            msgTitleH -
            topDivH -
            bottomThH -
            pageMessageH

        // 动态表格内容的高度 >= 实际下面表格的高度,表示实际下面表格的高度没有超过一页,不分页
        // 动态表格内容的高度 < 实际下面表格的高度,表示实际下面表格的高度超过一页了,根据计算的动态表格高度进行分页
        if (surplusHeight < bottomDivH) {
            // 循环列表数组,获取每行的高度相加,当高度和大于计算的动态表格高度,则此处分页
            let sum = 0
            item.wmsOutwardDeliveryDetailList.forEach((item_, index_) => {
                let bottomTd = document.getElementById(`bottomTd_${item_.id}`)
                let bottomTdH = bottomTd.clientHeight
                sum += bottomTdH
                // 行高之和 > 计算的高度,表示已经超出了,在上一行就应该分页
                if (sum > surplusHeight) {
                    item.wmsOutwardDeliveryDetailList[index_ - 1].splitIndex = true //标记到这一行应该分页了
                    sum = bottomTdH
                }
            })
        }
    })
    nextTick(() => {
        splitPage()// 分割数据
    })
}
d. 分割数据
const splitPage = () => {
    states.allDataPrintPage = []
    states.tableData.forEach(item => {
        item.wmsOutwardDeliveryDetailList.forEach(e => {
            e.mainList = item
        })
        if (item.wmsOutwardDeliveryDetailList.length > 0) {
            // 设置一个分页的对象
            states.printData = {}
            // 保存要打印的数据
            let filterList = item.wmsOutwardDeliveryDetailList
            // 判断当前列表中分割标记 splitIndex 是否为true
            let splitIndexFlag = item.wmsOutwardDeliveryDetailList.some(subItem => {
                return subItem.splitIndex
            })
            // 如果有分页的则根据splitIndex进行分页
            if (splitIndexFlag) {
                let length = item.wmsOutwardDeliveryDetailList.length - 1
                item.wmsOutwardDeliveryDetailList[length].splitIndex = true //标记到这一行应该分页了
                let pageCount = 0
                let start = 0
                let listArr = _.cloneDeep(item.wmsOutwardDeliveryDetailList)
                filterList.forEach((e, i) => {
                    if (e.splitIndex) {
                        pageCount++
                        states.printData[pageCount] = listArr.slice(start, i + 1)
                        start = i + 1
                    }
                })
            } else {
                // 如果没有分页的,表示该表格不分页,
                states.printData[1] = filterList
            }
            states.allDataPrintPage.push(states.printData)
        }
    })
}

以下附上页面完整代码:

<template>
    <div>
        <el-card
            class="bt-view"
            :body-style="{ flex: '1', height: '100%' }"
            v-show="states.dialogVisible"
        >
            <template #header>
                <span>{{ states.title }}</span>
                <el-icon class="header-close" @click="handleClose">
                    <Close></Close>
                </el-icon>
            </template>
            <!-- 以下开始是打印 -->
            <div class="page_div use-get-height">
                <div id="totalDiv" class="print_div">
                    <div v-for="(ele, index) in states.tableData" :key="index" class="page">
                        <div id="pageHeight" class="page_height">
                            <div id="printTitle" class="print_title">
                                {{ ele.companyName }}交货单
                            </div>
                            <div id="msgTitle" class="msg_title">基本信息:</div>
                            <div id="topDiv">
                                <el-row>
                                    <el-col :span="21">
                                        <table ref="topTableRef" class="msg_table">
                                            <tr>
                                                <td class="table_td_title_left">交货单号</td>
                                                <td class="table_td_left">{{ ele.deliveryNo }}</td>
                                                <td class="table_td_title">工作令</td>
                                                <td class="table_td_center">{{ ele.workOrder }}</td>
                                                <td class="table_td_title">需求交货日期</td>
                                                <td class="table_td">{{ ele.deliveryTime }}</td>
                                            </tr>
                                            <tr>
                                                <td class="table_td_title_left">发料仓库</td>
                                                <td class="table_td_left">
                                                    {{ ele.deliveryWarehouseName }}
                                                </td>
                                                <td class="table_td_title">收货单位编码</td>
                                                <td class="table_td_center">{{ ele.receiveNo }}</td>
                                                <td class="table_td_title">收货单位名称</td>
                                                <td class="table_td">{{ ele.receiveName }}</td>
                                            </tr>
                                            <tr>
                                                <td class="table_td_title_left">收货人</td>
                                                <td class="table_td_left">
                                                    {{ ele.receivePerson }}
                                                </td>
                                                <td class="table_td_title">联系电话</td>
                                                <td class="table_td_center">{{ ele.phone }}</td>
                                                <td class="table_td_title">收货地址</td>
                                                <td colspan="3" class="table_td">
                                                    {{ ele.receiveAddress }}
                                                </td>
                                            </tr>
                                        </table>
                                    </el-col>
                                    <el-col :span="3">
                                        <div class="vue_qr">
                                            <vue-qr
                                                :text="ele.deliveryNo"
                                                :margin="1"
                                                :size="100"
                                            ></vue-qr>
                                        </div>
                                    </el-col>
                                </el-row>
                            </div>
                            <div class="msg_title">物料信息:</div>
                            <div :id="`bottomDiv_${ele.deliveryNo}`">
                                <table class=" ">
                                    <tr id="bottomTh">
                                        <th class="material_table_td">序号</th>
                                        <th class="material_table_td">物料编码</th>
                                        <th class="material_table_td">物料名称</th>
                                        <th class="material_table_td">规格</th>
                                        <th class="material_table_td">型号</th>
                                        <th class="material_table_td">交货数量(主)</th>
                                        <th class="material_table_td">主单位</th>
                                    </tr>
                                    <tr
                                        v-for="(item, indexs) in ele.wmsOutwardDeliveryDetailList"
                                        :key="indexs"
                                        :id="`bottomTd_${item.id}`"
                                    >
                                        <td class="material_table_td" style="width: 3%">
                                            {{ Number(index) + Number(indexs) + 1 }}
                                        </td>
                                        <td class="material_table_td" style="width: 6%">
                                            {{ item.materialCode }}
                                        </td>
                                        <td class="material_table_td" style="width: 10%">
                                            {{ item.materialName }}
                                        </td>
                                        <td class="material_table_td" style="width: 10%">
                                            {{ item.specification }}
                                        </td>
                                        <td class="material_table_td" style="width: 10%">
                                            {{ item.model }}
                                        </td>
                                        <td class="material_table_td" style="width: 6%">
                                            {{ item.outStockMainNum }}
                                        </td>
                                        <td class="material_table_td" style="width: 5%">
                                            {{ item.basicUnitName }}
                                        </td>
                                    </tr>
                                </table>
                            </div>
                            <div id="pageMessage" class="page-message">
                                {{ index / states.printNumber + 1 }} /
                                {{
                                    Math.ceil(
                                        ele.wmsOutwardDeliveryDetailList.length /
                                            states.printNumber,
                                    )
                                }}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="page_div">
                <div id="totalDiv" ref="print" class="print_div">
                    <div v-for="(eleAll, indexAll) in states.allDataPrintPage" :key="indexAll">
                        <div v-for="(ele, index) in eleAll" :key="index" class="page">
                            <div id="pageHeight" class="page_height">
                                <div id="printTitle" class="print_title">
                                    {{ ele[0]?.mainList.companyName }}交货单
                                </div>
                                <div id="msgTitle" class="msg_title">基本信息:</div>
                                <div id="topDiv">
                                    <el-row>
                                        <el-col :span="21">
                                            <table ref="topTableRef" class="msg_table">
                                                <tr>
                                                    <td class="table_td_title_left">交货单号</td>
                                                    <td class="table_td_left">
                                                        {{ ele[0]?.mainList.deliveryNo }}
                                                    </td>
                                                    <td class="table_td_title">工作令</td>
                                                    <td class="table_td_center">
                                                        {{ ele[0]?.mainList.workOrder }}
                                                    </td>
                                                    <td class="table_td_title">需求交货日期</td>
                                                    <td class="table_td">
                                                        {{ ele[0]?.mainList.deliveryTime }}
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td class="table_td_title_left">发料仓库</td>
                                                    <td class="table_td_left">
                                                        {{ ele[0]?.mainList.deliveryWarehouseName }}
                                                    </td>
                                                    <td class="table_td_title">收货单位编码</td>
                                                    <td class="table_td_center">
                                                        {{ ele[0]?.mainList.receiveNo }}
                                                    </td>
                                                    <td class="table_td_title">收货单位名称</td>
                                                    <td class="table_td">
                                                        {{ ele[0]?.mainList.receiveName }}
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td class="table_td_title_left">收货人</td>
                                                    <td class="table_td_left">
                                                        {{ ele[0]?.mainList.receivePerson }}
                                                    </td>
                                                    <td class="table_td_title">联系电话</td>
                                                    <td class="table_td_center">
                                                        {{ ele[0]?.mainList.phone }}
                                                    </td>
                                                    <td class="table_td_title">收货地址</td>
                                                    <td colspan="3" class="table_td">
                                                        {{ ele[0]?.mainList.receiveAddress }}
                                                    </td>
                                                </tr>
                                            </table>
                                        </el-col>
                                        <el-col :span="3">
                                            <div class="vue_qr">
                                                <vue-qr
                                                    :text="ele[0]?.mainList.deliveryNo"
                                                    :margin="1"
                                                    :size="100"
                                                ></vue-qr>
                                            </div>
                                        </el-col>
                                    </el-row>
                                </div>
                                <div class="msg_title">物料信息:</div>
                                <div :id="`bottomDiv_${ele[0]?.mainList.deliveryNo}`">
                                    <table class=" ">
                                        <tr id="bottomTh">
                                            <th class="material_table_td">序号</th>
                                            <th class="material_table_td">物料编码</th>
                                            <th class="material_table_td">物料名称</th>
                                            <th class="material_table_td">规格</th>
                                            <th class="material_table_td">型号</th>
                                            <th class="material_table_td">交货数量(主)</th>
                                            <th class="material_table_td">主单位</th>
                                        </tr>
                                        <tr
                                            v-for="(item, indexs) in ele"
                                            :key="indexs"
                                            :id="`bottomTd_${item.id}`"
                                        >
                                            <td class="material_table_td" style="width: 3%">
                                                {{ Number(indexs) + 1 }}
                                            </td>
                                            <td class="material_table_td" style="width: 6%">
                                                {{ item.materialCode }}
                                            </td>
                                            <td class="material_table_td" style="width: 10%">
                                                {{ item.materialName }}
                                            </td>
                                            <td class="material_table_td" style="width: 10%">
                                                {{ item.specification }}
                                            </td>
                                            <td class="material_table_td" style="width: 10%">
                                                {{ item.model }}
                                            </td>
                                            <td class="material_table_td" style="width: 6%">
                                                {{ item.outStockMainNum }}
                                            </td>
                                            <td class="material_table_td" style="width: 5%">
                                                {{ item.basicUnitName }}
                                            </td>
                                        </tr>
                                    </table>
                                </div>
                                <div id="pageMessage" class="page-message">
                                    {{ Number(index) }} /
                                    {{ Object.keys(eleAll).length }}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="public-bigPage-footer flex-a-center-j-end">
                <bt-button type="secondary" @click="handleClose">&nbsp;</bt-button>
                <bt-button :loading="states.saveLoading" @click="handlePrint">&nbsp;</bt-button>
            </div>
        </el-card>
    </div>
</template>
<script lang="ts" setup>
import vueQr from 'vue-qr/src/packages/vue-qr.vue'
import { E_Msg } from '@/usage/utils'
import { Close } from '@element-plus/icons-vue'
import { reactive, nextTick, ref } from 'vue'
import { ElLoading } from 'element-plus'
import { Print } from '@/usage/utils/index'
import _ from 'lodash'
import { WmsOutwardDeliveryDetailApi } from '@/base/consts/api/wms/index'

// 成功后父组件刷新页面
const emits = defineEmits(['succeed'])

const states = reactive({
    paperHeight: undefined,
    dialogVisible: false, //弹窗显示
    title: '', //标题
    printData: {},
    parentRows: [],
    tableData: [], //物料信息
    allDataPrintPage: [],
    saveLoading: false, //保存loading
})

// 接收父组件参数
const startAddData = arr => {
    console.log('arr', arr)
    states.parentRows = _.cloneDeep(arr)
    states.title = '交货单打印'
    nextTick(() => {
        getlistData() //获取数据
    })
}

// 计算分割点
const countPage = () => {
    states.tableData.forEach(item => {
        let printTitle = document.getElementById('printTitle')
        let printTitleH = printTitle.clientHeight

        let msgTitle = document.getElementById('msgTitle')
        let msgTitleH = msgTitle.clientHeight

        let topDiv = document.getElementById('topDiv')
        let topDivH = topDiv.clientHeight < 100 ? 100 : topDiv.clientHeight

        let bottomTh = document.getElementById('bottomTh')
        let bottomThH = bottomTh.clientHeight

        let bottomDiv = document.getElementById(`bottomDiv_${item.deliveryNo}`)
        let bottomDivH = bottomDiv.clientHeight

        let pageMessage = document.getElementById('pageMessage')
        let pageMessageH = pageMessage.clientHeight
        // 动态表格内容的高度 = A4纸横向高度 - 打印标题高度 - 小标题高度*2 - 上面表格高度 - 下面表格的表头高度 - 页码高度
        let surplusHeight =
            states.paperHeight -
            printTitleH -
            msgTitleH -
            msgTitleH -
            topDivH -
            bottomThH -
            pageMessageH

        // 动态表格内容的高度 >= 实际下面表格的高度,表示实际下面表格的高度没有超过一页,不分页
        // 动态表格内容的高度 < 实际下面表格的高度,表示实际下面表格的高度超过一页了,根据计算的动态表格高度进行分页
        if (surplusHeight < bottomDivH) {
            // 循环列表数组,获取每行的高度相加,当高度和大于计算的动态表格高度,则此处分页
            let sum = 0
            item.wmsOutwardDeliveryDetailList.forEach((item_, index_) => {
                let bottomTd = document.getElementById(`bottomTd_${item_.id}`)
                let bottomTdH = bottomTd.clientHeight
                sum += bottomTdH
                // 行高之和 > 计算的高度,表示已经超出了,在上一行就应该分页
                if (sum > surplusHeight) {
                    item.wmsOutwardDeliveryDetailList[index_ - 1].splitIndex = true //标记到这一行应该分页了
                    sum = bottomTdH
                }
            })
        }
    })
    nextTick(() => {
        splitPage()
    })
}

// 分割数据
const splitPage = () => {
    states.allDataPrintPage = []
    states.tableData.forEach(item => {
        item.wmsOutwardDeliveryDetailList.forEach(e => {
            e.mainList = item
        })
        if (item.wmsOutwardDeliveryDetailList.length > 0) {
            // 设置一个分页的对象
            states.printData = {}
            // 保存要打印的数据
            let filterList = item.wmsOutwardDeliveryDetailList
            // 判断当前列表中分割标记 splitIndex 是否为true
            let splitIndexFlag = item.wmsOutwardDeliveryDetailList.some(subItem => {
                return subItem.splitIndex
            })
            // 如果有分页的则根据splitIndex进行分页
            if (splitIndexFlag) {
                let length = item.wmsOutwardDeliveryDetailList.length - 1
                item.wmsOutwardDeliveryDetailList[length].splitIndex = true //标记到这一行应该分页了
                let pageCount = 0
                let start = 0
                let listArr = _.cloneDeep(item.wmsOutwardDeliveryDetailList)
                filterList.forEach((e, i) => {
                    if (e.splitIndex) {
                        pageCount++
                        states.printData[pageCount] = listArr.slice(start, i + 1)
                        start = i + 1
                    }
                })
            } else {
                // 如果没有分页的,表示该表格不分页,
                states.printData[1] = filterList
            }
            states.allDataPrintPage.push(states.printData)
        }
    })
}

// 获取数据
const getlistData = () => {
    const loadingInstance = ElLoading.service({
        target: '.rankingListBtTable',
        text: '',
    })
    let query = {
        ids: [],
    }
    states.parentRows.forEach(item => {
        query.ids.push(item.wmsOutwardDeliveryId)
    })
    WmsOutwardDeliveryDetailApi.selectPrint(query)
        .then(res => {
            states.tableData = res.data
            // 整理打印数据
            // printPage()
            nextTick(() => {
                states.dialogVisible = true
                nextTick(() => {
                    let pageHeight = document.getElementById('pageHeight')
                    states.paperHeight = pageHeight.clientHeight
                    countPage() //计算分割点
                })
            })
        })
        .catch(err => {
            E_Msg.error(err.msg || err)
        })
        .finally(() => {
            loadingInstance.close()
        })
}

const print = ref()
// 打印
const handlePrint = () => {
    Print(print.value, {
        'no-print': '.do-not-print-me-xxx',
    })
}

// 弹窗关闭
const handleClose = () => {
    states.allDataPrintPage = []
    states.tableData = [] //清空表格
    states.printData = [] //清空表格
    emits('succeed')
    states.dialogVisible = false //关闭弹窗
}

defineExpose({ startAddData })
</script>
<style scoped lang="scss">
.footer {
    left: 3%;
    top: -2%;
    width: 250px;
    height: 50px;
    z-index: 10;
}
.bt-view {
    position: absolute;
    top: 0px;
    left: 0;
    z-index: 10;
    width: 100%;
    height: 100%;
}
.header-close {
    float: right;
    cursor: pointer;
    position: relative;
    top: 4px;
}
.page_div {
    height: 85%;
    overflow: auto;
    display: flex;
}
.page_height {
    height: 200mm;
    width: 297mm;
    box-sizing: border-box;
    margin-bottom: 85px;
    position: relative;
}
// 以下为打印样式
.print_div {
    page-break-before: always;
    page-break-after: avoid;
    page-break-inside: avoid;
    margin: 0 auto;
}
.print_title {
    font-size: 22px;
    font-weight: bolder;
    text-align: center;
}
.msg_title {
    font-size: 20px;
    font-weight: bolder;
}
.msg_table {
    text-align: center;
    width: 100%;
}
.table_td_title_left {
    width: 6%;
    border: 1px solid #000;
}
.table_td_title {
    width: 9%;
    border: 1px solid #000;
}
.table_td_left {
    width: 9%;
    border: 1px solid #000;
}
.table_td_center {
    width: 9%;
    border: 1px solid #000;
}
.table_td {
    width: 16.5%;
    border: 1px solid #000;
}
.vue_qr {
    text-align: center;
}
.material_table_td {
    word-break: break-all;
    text-align: center;
    border: 1px solid #000;
}
.page-message {
    text-align: center;
    page-break-before: avoid;
    page-break-after: always;
    page-break-inside: avoid;
    position: absolute;
    bottom: 0;
    left: 50%;
}
.use-get-height {
    position: absolute;
    top: 0;
    z-index: -1;
    opacity: 0;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值