当前位置: 首页 > news >正文

react封装一个打印功能

1创建一个utils文件夹 下的打印js文件 printUtils

const JsBarcode = require('jsbarcode'); // 条形码

//创建打印iframe框架
	const createPrintIframe = () => {
	  if (document.getElementById('printIframe')) {
	    document.body.removeChild(document.getElementById('printIframe'));
	  }
	  let iframe = document.createElement('iframe');
	  iframe.id = 'printIframe';
	  iframe.style.width = '100%';
	  iframe.style.height = '100%';
	  iframe.style.display = 'none';
	  return iframe;
	};

//创建table表头
	const createCaption = (title) => {
	  let caption = document.createElement('div');
	  caption.innerText = title;
	  return caption;
	};

//根据倍数拆分数组
	const sliceArry = (num, data) => {
	  let submitData = [];
	  let tempNum = 0;
	  for (let i = 0; i < data.length; i++) {
	    if (i % num == 0 && i != 0) {
	      submitData.push(data.slice(tempNum, i));
	      tempNum = i;
	    }
	    if (i + 1 == data.length) {
	      submitData.push(data.slice(tempNum, i + 1));
	    }
	  }
	  return submitData;
	};

// //创建table基础信息
	// const createThead = (data, columns) => {
	//   let thead = document.createElement('thead');
	//   let tr = document.createElement('tr');
	//   console.log('tempData', data);
	//   let dataLength = data.length;
	//   data.forEach((row, index) => {
	//     let tempTh = document.createElement('th');
	//     tempTh.style.width = row.width + 'px' || '160px';
	//     // tempTh.style.
	//     // style="white-space: nowrap"
	//     tempTh.setAttribute('nowrap', 'nowrap');
	//     tempTh.innerText = row.label;
	//     let tempTd = document.createElement('td');
	//     if (index == dataLength - 1) {
	//       tempTd.setAttribute('colspan', columns.length);
	//     }
	//     tempTd.innerText = row.value;
	//     tr.appendChild(tempTh);
	//     tr.appendChild(tempTd);
	//   });
	//   thead.appendChild(tr);
	//   return thead;
	// };

//创建基础信息
	const createThead = (data, baseInfoDataBox, span) => {
	  //根据传过来的每行展示多少个动态设置每个元素的宽度
	  let tempwidth = Math.round((10 / span) * 10);
	  data.map((row) => {
	    let tempDom = document.createElement('div');
	    tempDom.setAttribute('class', 'printBase_box_content');
	    tempDom.style.width = tempwidth + '%';
	    let labeldom = document.createElement('div');
	    labeldom.setAttribute('class', 'printBase_box_title');
	    labeldom.innerText = row.label + ':';
	    let textdom = document.createElement('div');
	    textdom.setAttribute('class', 'printBase_box_text');
	    textdom.innerText = row.value;
	    tempDom.appendChild(labeldom);
	    tempDom.appendChild(textdom);
	    baseInfoDataBox.appendChild(tempDom);
	  });
	};

//创建表格表头内容
	const createTableThead = (coluns) => {
	  let thead = document.createElement('thead');
	  let tr = document.createElement('tr');
	  coluns.map((row) => {
	    let tempTh = document.createElement('th');
	    tempTh.style.width = row.width + 'px' || '160px';
	    tempTh.innerText = row.title;
	    tr.appendChild(tempTh);
	  });
	  thead.appendChild(tr);
	  return thead;
	};
	
//创建表格里面数据
	const createTableData = (columns, tableData) => {
	  let tbody = document.createElement('tbody');
	  tableData.map((row, index) => {
	    let tr = document.createElement('tr');
	    columns.map((rows) => {
	      let tempTd = document.createElement('td');
	      tempTd.innerText = row[rows.dataIndex];
	      tr.appendChild(tempTd);
	    });
	    // tableData[columns[index].dataIndex]
	    tbody.appendChild(tr);
	  });
	  return tbody;
	};

//创建底部签名
	const createFoot = (footData) => {
	  let tDom = document.createElement('div');
	  tDom.setAttribute('class', 'printFoot');
	  footData.map((row) => {
	    let tDiv = document.createElement('div');
	    tDiv.setAttribute('class', 'printFoot-content');
	    tDiv.style.width = Math.round((10 / footData.length) * 10) + '%';
	    let tSpanTitle = document.createElement('span');
	    tSpanTitle.innerText = row.title;
	    let tSpanValue = document.createElement('span');
	    tSpanValue.innerText = row.value || '';
	    tDiv.appendChild(tSpanTitle);
	    tDiv.appendChild(tSpanValue);
	    tDom.appendChild(tDiv);
	  });
	  return tDom;
	};

//创建打印模版
	const createPrintTem = () => {
	  let iframe = createPrintIframe(); // 上边写的框架
	  document.body.appendChild(iframe);
	  let style = document.createElement('style');
	  style.type = 'text/css';
	  style.innerHTML =
	    '* {padding:0px;margin:0px}' +
	    '@page { size: landscape;margin: 0mm;  }' +
	    'table{border-collapse: collapse;font-size:12px}' +
	    'table tr th { border: 1px solid;padding:8px 8px;}' +
	    'table tr td { border: 1px solid;padding: 8px 8px;}' +
	    ' .print { width: 1100px;display: flex;flex-direction: column;align-items: center;padding:50px}' +
	    ' .printTitle {align-items: center;width: 100%;margin-bottom: 20px;}' +
	    ' .printBase {display: flex;flex-direction: column;align-items: center;width: 100%}' +
	    ' .printBase_box {display: flex;flex-direction: row;width: 100%; line-height:22px;margin-bottom: 10px}' +
	    ' .printBase_box_content {display: flex;flex-direction: row;}' +
	    ' .printBase_box_text {padding-left:5px}' +
	    ' .printFoot {display:flex;flex-direction:row;width:100%;margin-top: 10px;}' +
	    ' .titleContent {text-align: center;}' +
	    ' .barcodeimg {float:right}';	
	  //创建大盒子
	  let box = document.createElement('div');
	  box.setAttribute('class', 'print');
	  //创建标题盒子
	  let titlebox = document.createElement('div');
	  titlebox.setAttribute('class', 'printTitle');
	  //创建标题盒子内容容器
	  let titleContent = document.createElement('div');
	  titleContent.setAttribute('class', 'titleContent');
  	  titlebox.appendChild(titleContent);
	 // 创建基础信息盒子
	  let basebox = document.createElement('div');
	  basebox.setAttribute('class', 'printBase');
	  box.appendChild(titlebox);
	  box.appendChild(basebox);
	  iframe.contentWindow.document.head.appendChild(style);
	  iframe.contentWindow.document.body.appendChild(box);
	  return { iframe, box, titlebox, basebox, titleContent };
	};


//打印完成后触发
	const afterPrint = () => {
	  console.log('afterPrintafterPrintafterPrintafterPrint');
	};

// 打印 重点
	const printFn = (config, baseInfo, columns, tableData, footData) => {
	  let { iframe, box, titlebox, basebox, titleContent } = createPrintTem(); //模板
	  let footdom = createFoot(footData);
	  let tempDiv = document.createElement('div');
	  tempDiv.style.width = '100%';
	  // tempDiv.style.border = '1px solid';
	  iframe.contentWindow.document.body.children[0].appendChild(tempDiv); // 增加table
	  iframe.contentWindow.document.body.children[0].appendChild(footdom); // 增加底部
	  //给table增加标题
	  titleContent.appendChild(createCaption(config.proTitle));
	  titleContent.appendChild(createCaption(config.title));
	  //如果需要条形码
	  if (config.barcode) {
	    let barcodeDiv = document.createElement('div');
	    barcodeDiv.setAttribute('class', 'barcodeimg');
	    let barcode = document.createElement('img');
	    barcode.id = 'barcode';
	    barcodeDiv.appendChild(barcode);
	    titlebox.appendChild(barcodeDiv);
	    console.log('createBarcode', config);
	    JsBarcode(
	      iframe.contentWindow.document.getElementById('barcode'),
	      config.orderNum || '未配置编码',
	      {
	        width: 2,
	        height: 40
	      });
	  }

  //创建打印table
	  let table = document.createElement('table');
	  // 设置属性
	  table.setAttribute('width', '100%');
	  table.setAttribute('cellspacing', '0');
	  table.setAttribute('cellpadding', '0');	
 	 //处理有多少个theard,创建table基础信息
	  let tempData = sliceArry(config.span, baseInfo);
	  console.log('tempData', tempData);
	  tempData.map((row, index) => {
	    let baseInfoDataBox = document.createElement('div');
	    baseInfoDataBox.setAttribute('class', 'printBase_box');
	    createThead(row, baseInfoDataBox, config.span);
	    basebox.appendChild(baseInfoDataBox);
	  });
	  //创建table数据
	  let tableThead = createTableThead(columns);
	  table.appendChild(tableThead);
	  let tableTbody = createTableData(columns, tableData);
	  table.appendChild(tableTbody);
	  tempDiv.appendChild(table);
	  iframe.contentWindow.onafterprint = afterPrint;
	
  //延迟打印 todo
	  setTimeout(() => { 
	    //打印
	    iframe.contentWindow.print();
	  }, 1000);
	};

export { createPrintIframe, createPrintTem, printFn };

2在要打印的文件里引入封装的打印js文件
如下图
在这里插入图片描述

import { printFn } from '@/utils/printUtils';// 引入打印操作

在这里插入图片描述

  //打印 
  print = async ({ selectedRows }) => { // 选中的行
    console.log('dsadsd', selectedRows);
    if (selectedRows[0]?.docType === 'STKO') { // 调整单状态为IA-期初调整 就提示错误
      return ElNotification({
        type: 'error',
        message: '请选择<调整单类型>不为【IA-期初调整】的单据!'
      });
    }
    // 表头
    const config = {
      proTitle: 'OU_中燃宝电器(深圳)公司',
      title: '领料出库单',
      span: 3
    };
    //表格信息
    const columns = [
      { title: '行号', dataIndex: 'lineNo' },
      { title: '商品编码', dataIndex: 'itemCode' },
      { title: '商品名称', dataIndex: 'itemName' },
      { title: '申请数量', dataIndex: 'qty' },
      { title: '出库数量', dataIndex: 'qty' },
      { title: '单位', dataIndex: 'uomName' },
      { title: '备注', dataIndex: 'remark' } ];
      
      // 底部信息
    let tableData = [];
    const footData = [
      { title: '领料人:' },
      { title: '复核人:' },
      { title: '仓管员:' }];
      
    this.setState({
      pageLoading: true
    });
    const res = await service.findOneInvAj(selectedRows[0]?.id); // 请求接口
    this.setState({
      pageLoading: false
    });
    if (res.success) {
      const baseInfo = [
        { label: '调整单', value: res.data.docNo },
        { label: '申请部门', value: '' },
        {
          label: '申请日期',
          value: asserts.isExist(res.data?.applyDate)
            ? dayjs(res.data.applyDate).format('YYYY-MM-DD')
            : ''
        },
        { label: '原因码', value: res.data?.reasonCodeName },
        { label: '仓库', value: res.data?.whName },
        { label: '功能库区', value: res.data?.deter2Name },
        { label: '项目编号', value: '' },
        { label: '项目名称', value: '' },
        { label: '项目类型', value: '' },
        { label: '施工队', value: '' },
        { label: '户外/庭院', value: '' },
        { label: '服务商', value: '' },
        {
          label: '执行时间(交易时间)',
          value: asserts.isExist(res.data?.ioDate)
            ? dayjs(res.data.ioDate).format('YYYY-MM-DD')
            : ''
        },
        { label: '执行货位', value: '' },
        { label: '备注', value: res.data?.remark }
      ];
      
      // 过滤大于等于0的
      tableData = res.data.invAjDVOList?.filter((val) => +val.qty < 0);
      if (!tableData.length) {
        return ElNotification({
          type: 'error',
          message: '请选择<调整单调整数>【小于0】的单据!'
        });
      }
      
      tableData.forEach((row) => {
        row.qty = Math.abs(row.qty);
      });
      
      tableData = res.data.invAjDVOList;
      printFn(config, baseInfo, columns, tableData, footData);
    } else {
      ElNotification({
        type: 'error',
        message: res.message || res.data || '打印失败'
      });
    }
  };

在这里插入图片描述

相关文章:

  • 在linux环境下编译C++ 程序
  • react项目中,在tab列表上展示某个字段以 数组形式 展示
  • Spark Streaming官方文档学习--下
  • Vue 判断两个时间选择框的校验element 。开始时间不能大于结束时间
  • 为什么不能访问django自带的索引页
  • SSIS 数据类型和类型转换
  • Vue,列表展示。多个字段拼接展示
  • Swift开发:NSLayoutConstraint纯代码实现自动布局-初级篇
  • react中的 Modal.confirm
  • 数据挖掘之决策树ID3算法(C#实现)
  • 【一小时入门】webpack 入门指南
  • Vue中 beforeRouteLeave离开路由之前要执行的操作
  • AF3.1.0简单二次封装
  • Vue 项目中 根目录中router路由拦截 beforeEach 常用的写法
  • 不同按钮模板自定义
  • 收藏网友的 源程序下载网
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【面试系列】之二:关于js原型
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Codepen 每日精选(2018-3-25)
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • co模块的前端实现
  • Docker: 容器互访的三种方式
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • JavaScript 奇技淫巧
  • Vue学习第二天
  • Webpack 4x 之路 ( 四 )
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 大数据与云计算学习:数据分析(二)
  • 大整数乘法-表格法
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 异步
  • 06-01 点餐小程序前台界面搭建
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (+4)2.2UML建模图
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (八)Spring源码解析:Spring MVC
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (一)kafka实战——kafka源码编译启动
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转载)从 Java 代码到 Java 堆
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET Core中Emit的使用
  • .NET Core中的去虚
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • @取消转义
  • [2016.7.Test1] T1 三进制异或
  • [20160807][系统设计的三次迭代]
  • [C#]C# OpenVINO部署yolov8图像分类模型
  • [C/C++随笔] char与unsigned char区别