js实现调用浏览器自带打印工单功能

本例子基于vue实现,但逻辑是通用的。
HTML部分 :逻辑使用table,为保证视觉统一,每行分24列,通过colspan合并列
JS部分

<div style="max-height:100%;width:100%;overflow:auto;" :id="printId">
  <table class="font-s10" border="1" cellpadding="0" cellspacing="0">
        <tr class="font-s20 font-b align-center">
          <td colspan="24" class="color-bg_lightyellow color-black">
            项目审批表
          </td>
        </tr>

        <tr>
          <td colspan="1" class="td-t font-s8">序号</td>
          <td colspan="9" class="td-t">流程名称</td>
          <td colspan="2" class="td-t">流程时间</td>
          <td colspan="2" class="td-t">流程金额</td>
          <td colspan="10" class="td-t font-s6">描述</td>
        </tr>
         <tr v-for="(item, idx) in  detail.processArr || []" :key="idx">
          <td colspan="1">{{ idx + 1 }}</td>
          <td colspan="9" class="font-s7">{{ item.xx}}</td>
          <td colspan="2" class="font-s7">{{ (item.xx || "").substr(0, 10) }}</td>
          <td colspan="2" class="color-red font-s8"> {{ item.xx2  }}元</td>
          <td colspan="12" class="color-red font-s8"> {{ item.xx3  }}</td>
        </tr>
        <!--空行-->
         <tr><td colspan="24" class="space0"></td> </tr>
        <tr>
          <td class="td-t mode-rl align-center font-s14" rowspan="3" colspan="2" >
            签批流
          </td>
          <td colspan="4" class="td-t lineheight_18">采购经办负责人</td>
          <td colspan="7"></td>
          <td colspan="4" class="td-t">发起审批时间</td>
          <td colspan="7"></td>
        </tr>
        <tr>
          <td colspan="4" class="td-t lineheight_18">项目负责人</td>
          <td colspan="7"></td>
          <td colspan="4" class="td-t">运营</td>
          <td colspan="7"></td>
        </tr>
        <tr>
          <td colspan="4" class="td-t lineheight_18">事业部负责人</td>
          <td colspan="7"></td>
          <td colspan="4" class="td-t">总经理</td>
          <td colspan="7"></td>
        </tr>
    </table>
</div>

css部分用同一套统一样式,如果是scss,自己在线转一下就得了,这段转的css,在下面js打印中会用到的

.printTable {
  .pre {
    white-space: pre-line;
  }
  .lineheight {
    &_12 {
      height: 12px;
    }
    &_18 {
      height: 18px;
    }
    &_24 {
      height: 24px;
    }
    &_36 {
      height: 36px;
    }
    &_48 {
      height: 48px;
    }
  }
  .font {
    &-s6 {
      font-size: 6px;
      line-height: 8px;
    }
    &-s7 {
      font-size: 7px;
      line-height: 9px;
    }
    &-s8 {
      font-size: 8px;
      line-height: 10px;
    }
    &-s9 {
      font-size: 9px;
      line-height: 12px;
    }
    &-s10 {
      font-size: 10px;
      line-height: 12px;
    }
    &-s14 {
      font-size: 14px;
      line-height: 16px;
    }
    &-s20 {
      font-size: 20px;
      line-height: 28px;
    }
    &-b {
      font-weight: 600;
    }
    &-bb {
      font-weight: 900;
    }
    &-nowrap {
      white-space: nowrap;
    }
  }

  .color {
    &-bg {
      &_yellow {
        background: #ffc000;
      }
      &_lightyellow {
        background: #ffff00;
      }
      &_grey {
        background: #e4e4e4;
      }
      &_pink {
        background: #fce4d6;
      }
      &_green {
        color: #60a265;
      }
      &_black {
        color: #000;
      }
    }
    &-red {
      color: #f00;
    }
    &-grey {
      color: grey;
    }
    &-green {
      color: #60a265;
    }
    &-pink {
      color: #fce4d6;
    }
    &-lightyellow {
      color: #ffff00;
    }
    &-yellow {
      color: #ffc000;
    }
  }

  .align-center {
    text-align: center;
  }

  table {
    table-layout: fixed;
    font-size: 12px;
    line-height: 30px;
    width: 100%;
    border: 0px solid #dddddd;
    border-collapse: collapse;
    color: #444;
  }

  table tr {
    border-bottom: 1px solid #d1d1d1;
  }
  table tr:first-child {
    border-top: 1px solid #d1d1d1;
  }
  table tr > td {
    border-right: 1px solid #d1d1d1;
  }
  table tr > td:first-child {
    border-left: 1px solid #d1d1d1;
  }

  table th,
  table td {
    padding: 0 5px;
    white-space: wrap;
    word-wrap: break-word;
  }

  table .td-t {
    background: #e4e4e4;
    color: #666;
  }

  table .td-c {
    color: #444;
  }

  td.space {
    height: 10px;
    line-height: 10px;
    background: #f5f3f3;
  }

  td.space0 {
    height: 5px;
    line-height: 5px;
    background: #f5f3f3;
  }

  table tr.strip:nth-child(2n + 1) {
    background: #eff6ff;
  }

  table tr.strip:nth-child(2n) {
    background: #ffffff;
  }

  table .mode-rl {
    writing-mode: vertical-rl;
    vertical-align: middle;
    text-align: center;
    letter-spacing: 5px;
  }
}

JS部分

/*
* 处理工单审批流的数据
*/
async print(id) {
      this.printId = "flow_" + id;
      this.show = false;
      
      setTimeout(async () => {
        await this.handlePrintPage(this.printId); //这个id最好有意义生成,为防止重复调用获取到非本次数据
      }, 500);
},
 /**
  * @param id 
   * @param isPortrait 是否垂直打印
   * @param isAddSinglePageStyle  是否添加单页始终插入分页符
   * css参数不明白的自己去查去 `page-break-after`
   */
handlePrintPage(id, isPortrait = true, isAddSinglePageStyle = true) {
    // 这段就是上面那个css啦,真的长
    var printStyles = `
    .single{page-break-after:${ isAddSinglePageStyle ? "always" : "auto" };margin-top:0cm;}
    .single .single-content{page-break-after:${ isAddSinglePageStyle ? "always" : "auto"};margin-top:1cm;}
    .pre{white-space:pre-line}
    .lineheight_12{height:12px}
    .lineheight_18{height:18px}
    .lineheight_24{height:24px}
    .lineheight_36{height:36px}
    .lineheight_48{height:48px}
    .font-s6{font-size:6px;line-height:8px}
    .font-s7{font-size:7px;line-height:9px}
    .font-s8{font-size:8px;line-height:10px}
    .font-s9{font-size:9px;line-height:12px}
    .font-s10{font-size:10px;line-height:12px}
    .font-s14{font-size:14px;line-height:16px}
    .font-s20{font-size:20px;line-height:28px}
    .font-b{font-weight:600}
    .font-bb{font-weight:900}
    .font-nowrap{white-space:nowrap}
    .color-bg_yellow{background:#ffc000}
    .color-bg_lightyellow{background:#ffff00}
    .color-bg_grey{background:#e4e4e4}
    .color-bg_green{background:#60A265}
    .color-bg_pink{background:#fce4d6}
    .color-red{color:#f00}
    .color-grey{color:grey}
    .color-pink{color:#fce4d6}
    .color-lightyellow{color:#ffff00}
    .color-yellow{color:#ffc000}
    .color-green{color:#60A265}
    .color-black{color:#000}
    .align-center{text-align:center}
    table{table-layout:fixed;font-size:12px;line-height:30px;width:100%;border:0px solid #d1d1d1;border-collapse:collapse;color:#444}
    table th,table td{padding:0 5px;white-space:wrap;word-wrap:break-word;}
    table tr { border-bottom: 1px solid #d1d1d1;}
    table tr:first-child {border-top: 1px solid #d1d1d1;}
    table tr > td {border-right: 1px solid #d1d1d1;}
    table tr > td:first-child {border-left: 1px solid #d1d1d1;}
    table .td-t{background:#e4e4e4;color:#666}
    table .td-c{color:#444}
    td.space{height:10px;line-height:10px;background:#f5f3f3}
    td.space0{height:5px;line-height:5px;background:#f5f3f3}
    table tr.strip:nth-child(2n+1){background:#eff6ff}
    table tr.strip:nth-child(2n){background:#ffffff}
    table .mode-rl{writing-mode:vertical-rl;vertical-align:middle;text-align:center;letter-spacing:5px}
`;
      // 控制横向打印还是纵向打印(但总是不生效),控制上下左右边距
      var content = `
      <style type="text/css" media="print">
        @page {
          size:${isPortrait ? "portrait" : "landscape"}
           @bottom-center {
            content: "Page " counter(page) " of " counter(pages);
           }
        }
        body{ ${isPortrait ? "margin-left:1cm;" : "margin-top:0cm;"} }
        *{box-sizing:border-box;-webkit-print-color-adjust:exact;print-color-adjust:exact;color-adjust:exact;}
        ${printStyles}
     </style>`;
      content += document.getElementById(id).innerHTML;

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

推荐阅读更多精彩内容