博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React实现打印功能
阅读量:6503 次
发布时间:2019-06-24

本文共 10727 字,大约阅读时间需要 35 分钟。

一、需求分析:

环境:react,antd,antd-pro

将选中的数据进行打印,可以自定义分页的大小。
由于打印的列等多个因素,导致如果写成组件在使用的时候依旧会改变源码,所以采用了写成页面的方式,

二、实现需求:

1、数据传值

进行传值的时候,刚开始使用的是在通过this.props.location进行传值,但是这样数据被写死了,导致再次进入页面的时候无法更新打印的值。

最后采用了一个全局的model进行实现的传值。

2、表格生成

分为四部分进行生成,分别是标题、表头、表格、表尾。其中表头,表尾因为需求的原因写死。

以下为代码:

createTitle = (title)=>(  

{title}

)createHeader = (headerData)=>{ headerData = [ { orderID:'订单编号', value:'P201901020002', },{ people:'采购人员', value:'xxx', },{ time:'采购时间', value:'2019年01月01日', } ]; return (
订单编号:
采购员: 采购时间:
)}createForm = (printCol,printData)=>(
{ (
{printCol.map(item=>
)}
) } { printData.map(item=> (
{Object.keys(item).map(i =>
)}
) ) }
{item.name}
{item[i]}
)createFooter = (footerData)=>{ return (
供应商(签字)
库管员(签字)
{`第${footerData.current}页`} {`共${footerData.total}页`}
)}createPrintArea = (printCol)=>{ const {printGroupData} = this.state; return ( printGroupData.map((item,index)=>{ if(item.length){ return (
{this.createTitle('xxxxxxx公司xxx单')} {this.createHeader('asd')} {this.createForm(printCol,item)} {this.createFooter({current:index+1,total:printGroupData.length})}
) } }) )}

最主要的是CSS的调整,因为之后的打印需求将所有的CSS内联:

以下为css:

export const styleObj = {  printArea:{    width: '500px',    fontSize: '12px',    align:'center'  },  printInput:{    fontWeight:'bold',    border: 'none',  },  title:{    textAlign: 'center',    fontSize: '15px',    fontWeight: '700',  },  header:{    fontWeight:'bold',    fontSize: '12px',  },  printTable:{    fontSize: '12px',    fontWeight: '700',    color: 'black',    border: '1px black',    borderCollapse: 'collapse',    textAlign: 'center',  },  printTableTh:{    padding: '4px',    border: '1px solid black',    textAlign: 'center',  },  printTableTr:{    textAlign:'center',    padding: '4px',    border: '1px solid black',  },  number:{    width: '60px',  },  goodsName:{    width: '180px',  },  unitName:{    width: '75px',  },  specifications:{    width: '90px',  },  goodsType:{    width: '90px',  },  footer:{    fontSize:'12px',  },  footerSpace:{    width: '20px',    display: 'block',  },  printInputFooter:{    fontWeight:'bold',    border:'none',    width: '85px',  },};

3、实现分页

分页即将数据进行分割,然后每次生成表格的时候将分割后的每个表格数据依次传入表格生成函数,从而生成全部表格。

分页函数:

//传入的数据为:分页的大小,需要分页的数据。page = (pageNumber,printData)=>{  const printDataBack = printData.concat();  const printGroupData = [];  while(printDataBack.length >= pageNumber){    let tempGroup = [];    tempGroup = printDataBack.splice(0,pageNumber);    printGroupData.push(tempGroup);  }  if(printDataBack.length){    printGroupData.push(printDataBack);  }  printGroupData.forEach((item)=>{    item.forEach((i,index)=>{      i.number = index+1;    })  });  return printGroupData;}

注意:解构出来的数据是引用,需要进行备份。

设置一个input框以及一个按钮,input框用于输入分页的数字,再点击按钮以及第一次进入页面的时候进行分页。

4、实现打印

实现方法一(不推荐):
直接在本页面进行刷新

优点:css不用内嵌。

缺点:导致本页面刷新,某些数据丢失。

实现方法:直接获取到需要打印的区域,然后将本页面的innerHTML设置为获取的区域,然后调用系统的print,最后调用reload

代码:

print = () => {    window.document.body.innerHTML = window.document.getElementById('billDetails').innerHTML;      window.print();     window.location.reload();}
实现方法二:
打开一个页面进行打印

优点:打印不在关乎本页面的业务

缺点:CSS需要内联
代码:

handlePrint = () => {  const win = window.open('','printwindow');  win.document.write(window.document.getElementById('printArea').innerHTML);  win.print();  win.close();}

三、完整代码

以下为完整代码:

index.js

import React, { PureComponent } from 'react';import { connect } from 'dva';import {  Row,  Button,  Col,  Card,  Form,  message,  InputNumber,} from 'antd';import PageHeaderWrapper from '@/components/PageHeaderWrapper';import {styleObj} from './style';@Form.create()@connect(({ print }) => ({  print,}))class PrintTable extends PureComponent {  state = {    printData:[],    printCol:[],    pageNumber:10,    printGroupData:[],  }  componentDidMount() {    const printCol = [      {        key:'number',        name:'序号',      },{        key:'goodsName',        name:'商品名称',      },{        key:'goodsType',        name:'商品类型',      },{        key:'unitName',        name:'单位',      },{        key:'specifications',        name:'规格',      }];    const printData = [];    const { pageNumber } = this.state;    const { print:{ payload:{formPrintData} } } = this.props;    formPrintData.forEach((i,index)=>{      const colData = {};      printCol.forEach(j=>{        colData[j.key] = i[j.key];      })      colData.number = index+1;      printData.push(colData);    });    const printGroupData = this.page(pageNumber,printData);    this.setState({      printData,      printCol,      printGroupData,    })  }  componentWillReceiveProps(nextProps){    const printCol = [      {        key:'number',        name:'序号',      },{        key:'goodsName',        name:'商品名称',      },{        key:'goodsType',        name:'商品类型',      },{        key:'unitName',        name:'单位',      },{        key:'specifications',        name:'规格',      }];    const printData = [];    const { pageNumber } = this.state;    const { print:{ payload:{formPrintData} } } = nextProps;    formPrintData.forEach((i,index)=>{      const colData = {};      printCol.forEach(j=>{        colData[j.key] = i[j.key];      })      colData.number = index+1;      printData.push(colData);    });    const printGroupData = this.page(pageNumber,printData);    this.setState({      printData,      printCol,      printGroupData,    })  }  createTitle = (title)=>(    

{title}

) createHeader = (headerData)=>{ headerData = [ { orderID:'订单编号', value:'P201901020002', },{ people:'采购人员', value:'xxx', },{ time:'采购时间', value:'2019年01月01日', } ]; return (
订单编号:
采购员: 采购时间:
) } createForm = (printCol,printData)=>(
{ (
{printCol.map(item=>
)}
) } { printData.map(item=> (
{Object.keys(item).map(i =>
)}
) ) }
{item.name}
{item[i]}
) createFooter = (footerData)=>{ return (
供应商(签字)
库管员(签字)
{`第${footerData.current}页`} {`共${footerData.total}页`}
) } handlePrint = () => { const win = window.open('','printwindow'); win.document.write(window.document.getElementById('printArea').innerHTML); win.print(); win.close(); } createPrintArea = (printCol)=>{ const {printGroupData} = this.state; return ( printGroupData.map((item,index)=>{ if(item.length){ return (
{this.createTitle('xxxxxxx公司xxx单')} {this.createHeader('asd')} {this.createForm(printCol,item)} {this.createFooter({current:index+1,total:printGroupData.length})}
) } }) ) } handlePage = ()=>{ const { pageNumber, printData } = this.state; if(pageNumber <= 0){ message.warning('输出正确的分页'); return; } this.setState({ printGroupData:this.page(pageNumber, printData) }) } page = (pageNumber,printData)=>{ const printDataBack = printData.concat(); const printGroupData = []; while(printDataBack.length >= pageNumber){ let tempGroup = []; tempGroup = printDataBack.splice(0,pageNumber); printGroupData.push(tempGroup); } if(printDataBack.length){ printGroupData.push(printDataBack); } printGroupData.forEach((item)=>{ item.forEach((i,index)=>{ i.number = index+1; }) }); return printGroupData; } onChange = (value)=>{ this.setState({ pageNumber:value, }) } render() { const { printCol, printData } = this.state; return (
{printCol.length&&printData.length? this.createPrintArea(printCol):null}
); }}export default PrintTable;

style.js

export const styleObj = {  printArea:{    width: '500px',    fontSize: '12px',    align:'center'  },  printInput:{    fontWeight:'bold',    border: 'none',  },  title:{    textAlign: 'center',    fontSize: '15px',    fontWeight: '700',  },  header:{    fontWeight:'bold',    fontSize: '12px',  },  printTable:{    fontSize: '12px',    fontWeight: '700',    color: 'black',    border: '1px black',    borderCollapse: 'collapse',    textAlign: 'center',  },  printTableTh:{    padding: '4px',    border: '1px solid black',    textAlign: 'center',  },  printTableTr:{    textAlign:'center',    padding: '4px',    border: '1px solid black',  },  number:{    width: '60px',  },  goodsName:{    width: '180px',  },  unitName:{    width: '75px',  },  specifications:{    width: '90px',  },  goodsType:{    width: '90px',  },  footer:{    fontSize:'12px',  },  footerSpace:{    width: '20px',    display: 'block',  },  printInputFooter:{    fontWeight:'bold',    border:'none',    width: '85px',  },};

转载地址:http://hfqyo.baihongyu.com/

你可能感兴趣的文章
神秘函件引发的4G+与全网通的较量
查看>>
CloudCC:智能CRM究竟能否成为下一个行业风口?
查看>>
高德开放平台推出LBS游戏行业解决方案提供专业地图平台能力支持
查看>>
追求绿色数据中心
查看>>
Web开发初学指南
查看>>
OpenStack Days China:华云数据CTO郑军分享OpenStack创新实践
查看>>
探寻光存储没落的真正原因
查看>>
高通64位ARMv8系列服务器芯片商标命名:Centriq
查看>>
中国人工智能学会通讯——融合经济学原理的个性化推荐 1.1 互联网经济系统的基本问题...
查看>>
盘点大数据商业智能的十大戒律
查看>>
戴尔为保护数据安全 推出新款服务器PowerEdge T30
查看>>
今年以来硅晶圆涨幅约达40%
查看>>
构建智能的新一代网络——专访Mellanox市场部副总裁 Gilad Shainer
查看>>
《数字视频和高清:算法和接口》一导读
查看>>
《中国人工智能学会通讯》——6.6 实体消歧技术研究
查看>>
如何在Windows查看端口占用情况及查杀进程
查看>>
云存储应用Upthere获7700万美元股权债务融资
查看>>
国家互联网应急中心何世平博士主题演讲
查看>>
洗茶,你误会了多少年?
查看>>
移动大数据“后市场”受青睐 亟需数据深度学习人才
查看>>