浏览器打印遇到的一些坑....

做了三四天的浏览器打印....有点想吐血的感觉...不过总体来说还是有点收获的.

先看一下最终一些打印的预览图:

image.png
image.png
image.png

注意点:

背景色打印

.bg {
    -webkit-print-color-adjust: exact; /* 这一行必须要 */
    print-color-adjust: exact;
    background-color: green;
}

@page {
    size: landscape;
}

横竖打印,以及打印边距

portrait为竖着打 landscape为横着打

    Vue.prototype.GlobalPrint = function(title = '打印', printHtml, pageSet = {}) {
        // 打开一个新窗口
        const myWindow = window.open('', title);

        // 获取id为app内的html
        const bodyHtml = printHtml || window.document.getElementById('app').innerHTML;

        // 获取head标签内的html
        let headHtml = document.head.innerHTML;
        const pageStr = `
            <style media="print">
                @page {
                    size: ${pageSet.size || 'landscape'}; // portrait
                    margin: ${pageSet.margin || '18mm 18mm 18mm 18mm'};
                }   
            </style>
        `;
        headHtml += pageStr;
        // 头中的screen换成打印样式print
        headHtml = headHtml.replace('screen', 'screen, print');
        //重新写入文档流
        myWindow.document.write('<html>');
        myWindow.document.write(headHtml);
        myWindow.document.write('<body >');
        myWindow.document.write(bodyHtml);
        myWindow.document.write('<script>setTimeout(function() {window.print(); window.close();}, 50)</');
        myWindow.document.write('script>');
        myWindow.document.write('</body></html>');

        return true;
    }

调用方式

this.GlobalPrint(null, null, {
  size: 'portrait',
  margin: '1cm'
});

分页

  @media print {
    .next-page {
     page-break-before: always;
    }
  }

print.less

.so-list-print {
  position: relative;
  font-size: 12px;
  @media print {
    .next-page {
     page-break-before: always;
    }
  }

  .next-page {
    position: relative;
    .right-top {
      position: absolute;
      right: 0;
      top: 0;
    }
    .right-top-2 {
      position: absolute;
      right: 0;
      top: 12px;
    }
  }

  .header-first {
    display: flex;
    flex-wrap: wrap;
    span {
      width: 50%
    }
    span:nth-child(even) {
      text-align: right;
    }
  }

  .header-second {
    display: flex;
    flex-wrap: wrap;
    span {
      width: 33.33%
    }
    span:nth-child(2) {
      text-align: center;
    }
    span:nth-child(3) {
      text-align: right;
    }
  }

  .print-header {
    text-align: center;
    margin-top: 15px;
    font-weight: bold;
  }

  .top-line {
    height: 10px;
    border: none;
    border-top: 10px groove;
    margin-top: 2px;
    margin-bottom: 2px;
  }

  .bottom-line {
    height: 1px;
    border: none;
    border-top: 3px groove;
    margin-top: 12px;
    margin-bottom: 12px;
  }

  .count {
    text-align: right;
    span {
      width: 10%;
      text-align: center;
      display: inline-block;
    }
  }

  .sign {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
    div {
      text-align: center;
      margin-right: 20px;
      border: 1px solid grey;
      width: 80px;
      height: 70px;
      span {
        font-size: 12px;
        padding: 8px;
        display: block;
        border-bottom: 1px groove;
      }
    }
  }

  @border-color: #e1e1e1;
  .table-container {
    table {
      text-align: center;
      font-size: 12px;
      width: 100%;
      th, td {
        border-bottom: 1px solid @border-color;
        padding: 6px;
      }
    }
  }

  .footer-left {
    position: absolute;
    bottom: -30px;
    left: 0px;
    span {
      font-size: 20px;
      font-weight: bold;
    }
  }

  .footer-center {
    @media print {
      display: none;
    }
    position: fixed;
    bottom: 30px;
    left: 50%;
  }
}

print.vue

<template>
    <div class="so-list-print">
        <div v-for="(item, index) in printData" :key="index" class="next-page">
            <div v-for="(detail, key) in item.sort" :key="key" :class="key == item.totalPage ? null : 'next-page'">
                <h2 class="print-header">仓库出货单</h2>

                <div class="right-top">
                    <span>第 {{item.header.printCount}} 回打印</span>
                </div>
                <div class="right-top-2">
                    <span class="align-left;">打印时间: {{ item.header.timeCur }}</span>
                </div>

                <div class="header-first">
                    <span>发运单号: {{ item.header.soNo }}</span>
                    <span>发货时间: {{ item.header.sendTime }}</span>
                    <span>仓库编号: {{ item.header.warehouseCode }}</span>
                    <span>客户编号: {{ item.header.customerCode }}</span>
                </div>

                <div class="header-second">
                    <span>仓库名称: {{ item.header.warehouseName }}</span>
                    <span>物流名称: {{ item.header.logistics }}</span>
                    <span>客户名称: {{ item.header.customerName }}</span>
                </div>

                <hr class="top-line" />
                <div class="table-container">
                    <table>
                        <thead>
                        <tr>
                            <th>序号</th>
                            <th>商品编码</th>
                            <th>商品名称</th>
                            <th>分类</th>
                            <th width="10%">计划数量</th>
                            <th width="10%">成交数量</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr v-for="(item2, index) in detail">
                            <td>{{ item2.index }}</td>
                            <td>{{ item2.skuCode }}</td>
                            <td>{{ item2.skuName }}</td>
                            <td>{{ item2.divName}}</td>
                            <td width="10%">{{ item2.planQty }}</td>
                            <td width="10%">{{ item2.shipQty }}</td>
                        </tr>
                        </tbody>
                    </table>
                </div>

                <span class="footer-left">当前第 <span>{{parseInt(key) + 1}}</span> 页, 共 <span>{{ item.totalPage }}</span> 页</span>
            </div>

            <div class="count">
                总计: <span>{{ item.header.totalPlanQty }}</span><span>{{ item.header.totalShipQty }}</span>
            </div>
            <hr class="bottom-line" />

            <div class="sign">
                <div><span>物流</span></div>
                <div><span>驾驶员</span></div>
                <div><span>店铺</span></div>
                <div><span>验收印</span></div>
            </div>
        </div>

        <div class="footer-center">
            <el-button @click="GlobalPrint(null, null, printOptions)" type="primary">打印</el-button>
        </div>
    </div>
</template>

<script>
    import moment from 'moment';
    import {DeliveryFindAll} from './service/service';
    export default {
        data() {
            const url = this.$route.path;
            const soIds = url.substring(url.lastIndexOf('/') + 1, url.length);
            const soIdArr = soIds.split(',');
            return {
                soIds: soIdArr,
                printData: [],
                printOptions: {
                    size: 'portrait',
                    margin: '1cm'
                },
                catData: {
                    pageName: 'so-list-print',
                    msg: 'Failed',
                },
                loading: false,
            }
        },
        mounted() {
            this.init();
        },
        methods: {
            init() {
                const soIds = this.soIds;
                if (soIds.length === 0) {
                    this.$alert('无发运单id,无法打印!', '提示', {confirmButtonText: '确定', type: 'info'});
                    return;
                }

                const catData = {...this.catData, msg: 'DeliveryFindAll'};
                this.loading = true;
                DeliveryFindAll(soIds, catData).then((res = []) => {
                    this.loading = false;

                    res.forEach(item => {
                        item.header.timeCur = moment().format('YYYY-MM-DD HH:mm:ss');
                        item.details.forEach((item2, index) => {
                            item2.index = index + 1;
                        });
                        item.sort = {};
                        const count = parseInt(item.details.length / 25) + 1;
                        for (let i = 0; i < count; i++) {
                            item.sort[i] = item.details.slice(i * 25, (i + 1) * 25);
                        }
                        item.totalPage = count;
                    });


                    this.printData = res;

                    this.$confirm('确认打印', '提示').then(() => {
                        this.GlobalPrint(null, null, this.printOptions);
                    }).catch(() => {})
                }).catch((err) => {
                    this.loading = false;
                    this.printData = [];

                    this.$alert(err.msg || '服务器错误!', '提示', {type: 'error'});
                });
            },
        }
    };
</script>

<style lang="less">
    @import url("../../less/print/so-list-print");
</style>

另外页眉页脚是没法通过浏览器自定义设置的,需要自己写div和样式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • mobileHack 这里收集了许多移动端上遇到的各种坑与相对解决方案 工具类网站 HTML5 与 CSS3 技术...
    Zoemings阅读 6,530评论 0 12
  • 原文链接:https://lon.im/post/css-print.html 简介 本文主要讲解如何使用 CSS...
    龙好阅读 3,263评论 0 11
  • mobileHack 这里收集了许多移动端上遇到的各种坑与相对解决方案 工具类网站 HTML5 与 CSS3 技术...
    安石0阅读 1,888评论 0 5
  • 目前已经做了14次访谈: 压榨式提问——林英帅 压榨式提问——钱成 压榨式提问——张慧群 压榨式提问——程熙 压榨...
    于帅Jacob阅读 325评论 0 0
  • 送元二使安西 王维 渭城朝雨浥轻尘,客舍青青柳色新。 劝君更尽一杯酒,西出阳关无故人。 此诗又名渭城...
    白的白红的红阅读 396评论 0 0