利用【vue-print-nb】实现表格单个打印和批量打印

参考文档:vue-print-nb - npm

参考代码(重要实现页面):

<template>
    <div class="app-container">
        <button @click="handleprinter(1)">打印</button>
        <button @click="handlePrint([1,2,3])">批量打印</button>

        <!-- 打印内容 篇幅太长写在另一个页面 以组件的形式引入 page-break-after:always 分页,可使批量打印时每一个id的数据各单独占一页打印 -->
        <div id="printMe">
            <PrintAll style="page-break-after:always" v-for="dataItem in dataList" :key="dataItem.id" :dataItem="dataItem"></PrintAll>
        </div>

        <!-- 确认打印 -->
        <el-dialog title="批量打印" :visible.sync="printShow" width="500px">
            <div>是否确认打印ID为{{ ids.join(",") }}的数据</div>

            <div slot="footer" class="dialog-footer">
                <el-button type="primary" v-print="printObj">打 印</el-button>
                <el-button @click="cancelPrint">取 消</el-button>
            </div>

            <!-- 加载框 -->
            <div class="loading-box" v-show="loadingBox">
                <i class="el-icon-loading" style="font-size: 140px;"></i>
                <div>正在导出中...</div>
            </div>
        </el-dialog>

    </div>
</template>

<script>
import print from 'vue-print-nb'
import { getData } from "@/api/print"
import PrintAll from './printAll'

export default {
    name: "PrintTable",
    components: {
        PrintAll
    },
    directives: {
        print
    },
    data() {
        return {
            // 打印
            ids: [],
            dataList: [],
            printShow: false,
            printLoading: true,
            loadingBox: false,
            printObj: {
                id: "printMe",
                popTitle: '打印详情',
                extraCss: "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
                extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
                previewBeforeOpenCallback(vue) {
                    console.log('预览窗口打开之前')
                },
                beforeOpenCallback(vue) {
                    vue.printLoading = true
                    vue.loadingBox = true
                    console.log('调用打印工具前的回调函数')
                },
                openCallback(vue) {
                    vue.loadingBox = false
                    vue.printLoading = false
                    console.log('执行了打印')
                },
                closeCallback(vue) {
                    vue.dataList = []
                    console.log('关闭了打印工具')
                }
            }
        };
    },
    methods: {
        // 打印
        handleprinter(id) {
            this.ids = [id]
            // 清空表格内的内容
            this.dataList = []
            // 打印逻辑
            getData({ id: id }).then(res => {
                // 将查询到的数据写入表格
                this.dataList.push(res.data)
            })
            this.printShow = true
        },

        // 批量打印
        handlePrint(ids) {
            this.ids = ids
            // 清空表格内的内容
            this.dataList = []
            if (ids.length !== 0) {
                // 批量查询出要打印的内容
                for (let i = 0; i < ids.length; i++) {
                    // 调用
                    getData({ id: ids[i] }).then(res => {
                        // 将查询到的数据写入表格
                        this.dataList.push(res.data)
                    })
                }
                this.printShow = true
            }
        },

        cancelPrint() {
            this.printShow = false
            this.dataList = []
        }
    }
};
</script>

<style lang="scss" scoped>
.loading-box {
    color: white;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding-top: 100px;
    text-align: center;
    background: rgba(0, 0, 0, 0.4);
    z-index: 999;
}
</style>

另一个页面参考:

<template>
    <div class="table-box">
        <table class="my-detail">
            <caption class="big-title">标题</caption>
            <tbody>
                <tr>
                    <td class="de-title">id</td>
                    <td class="de-con">{{ dataItem.id }}</td>
                    <td class="de-title">内容</td>
                    <td class="de-con">{{ dataItem.con }}</td>
                </tr>
                <tr>
                    <td class="de-title">内容</td>
                    <td class="de-con">{{ dataItem.con }}</td>
                    <td class="de-title">内容</td>
                    <td class="de-con">{{ dataItem.con }}</td>
                </tr>
                <tr>
                    <td class="de-title">内容</td>
                    <td colspan="3">{{ dataItem.con }}</td>
                </tr>
                <tr>
                    <td class="de-title">内容</td>
                    <td class="de-con" colspan="3">{{ dataItem.con }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
export default {
    props: {
        dataItem: {}
    }
}
</script>

<style lang="scss" scoped>
.table-box {
    color: #222;
    width: 100%;
    padding: 0 20px;
    padding-bottom: 40px;
    box-sizing: border-box;

    .my-detail {
        width: 100%;
        min-width: 400px;
        max-width: 1200px;
        border-collapse: collapse;

        .big-title {
            line-height: 40px;
            font-size: 20px;
            font-weight: bold;
        }

        td {
            font-size: 14px;
            height: 28px;
            line-height: 28px;
            padding: 4px 6px;
            border: #000000 1px solid;
            border-spacing: 2px;
            border-collapse: collapse;
            &.de-title {
                width: 100px;
                text-align: center;
                font-weight: bold;
            }

            &.de-con {
                white-space: nowrap;
                text-overflow: ellipsis;
            }
        }
    }
}
</style>

写这个功能的时候有一个需求一直不知道怎么解决,就是内容太多的时候会导致打印出来的同一个id的内容分成两个页面。试过把字体调小,但是内容又多了之后也还是会重现这个问题。不知道有没有办法可以固定只用一个页面导出?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值